mirror of https://github.com/dswd/zvault
Enforce ordering for bundles with duplicate chunks (closes #13)
This commit is contained in:
parent
e0f4f30933
commit
ca7153117b
|
@ -21,7 +21,7 @@ pub static HEADER_STRING: [u8; 7] = *b"zvault\x01";
|
||||||
pub static HEADER_VERSION: u8 = 1;
|
pub static HEADER_VERSION: u8 = 1;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Hash, PartialEq, Eq, Clone, Default)]
|
#[derive(Hash, PartialEq, Eq, Clone, Default, Ord, PartialOrd)]
|
||||||
pub struct BundleId(pub Hash);
|
pub struct BundleId(pub Hash);
|
||||||
|
|
||||||
impl Serialize for BundleId {
|
impl Serialize for BundleId {
|
||||||
|
|
14
src/index.rs
14
src/index.rs
|
@ -341,13 +341,13 @@ impl Index {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds the key, data pair into the table.
|
/// Adds the key, data pair into the table.
|
||||||
/// If the key existed in the table before, it is overwritten and false is returned.
|
/// If the key existed the old data is returned.
|
||||||
/// Otherwise it will be added to the table and true is returned.
|
pub fn set(&mut self, key: &Hash, data: &Location) -> Result<Option<Location>, IndexError> {
|
||||||
pub fn set(&mut self, key: &Hash, data: &Location) -> Result<bool, IndexError> {
|
|
||||||
match self.locate(key) {
|
match self.locate(key) {
|
||||||
LocateResult::Found(pos) => {
|
LocateResult::Found(pos) => {
|
||||||
self.data[pos].data = *data;
|
let mut old = *data;
|
||||||
Ok(false)
|
mem::swap(&mut old, &mut self.data[pos].data);
|
||||||
|
Ok(Some(old))
|
||||||
},
|
},
|
||||||
LocateResult::Hole(pos) => {
|
LocateResult::Hole(pos) => {
|
||||||
{
|
{
|
||||||
|
@ -356,7 +356,7 @@ impl Index {
|
||||||
entry.data = *data;
|
entry.data = *data;
|
||||||
}
|
}
|
||||||
try!(self.increase_count());
|
try!(self.increase_count());
|
||||||
Ok(true)
|
Ok(None)
|
||||||
},
|
},
|
||||||
LocateResult::Steal(pos) => {
|
LocateResult::Steal(pos) => {
|
||||||
let mut stolen_key;
|
let mut stolen_key;
|
||||||
|
@ -382,7 +382,7 @@ impl Index {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try!(self.increase_count());
|
try!(self.increase_count());
|
||||||
Ok(true)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,7 +268,7 @@ impl Repository {
|
||||||
BundleMode::Meta => self.next_meta_bundle
|
BundleMode::Meta => self.next_meta_bundle
|
||||||
};
|
};
|
||||||
let chunks = try!(self.bundles.get_chunk_list(&bundle.id));
|
let chunks = try!(self.bundles.get_chunk_list(&bundle.id));
|
||||||
self.bundle_map.set(bundle_id, bundle.id);
|
self.bundle_map.set(bundle_id, bundle.id.clone());
|
||||||
if self.next_meta_bundle == bundle_id {
|
if self.next_meta_bundle == bundle_id {
|
||||||
self.next_meta_bundle = self.next_free_bundle_id()
|
self.next_meta_bundle = self.next_free_bundle_id()
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,13 @@ impl Repository {
|
||||||
self.next_data_bundle = self.next_free_bundle_id()
|
self.next_data_bundle = self.next_free_bundle_id()
|
||||||
}
|
}
|
||||||
for (i, (hash, _len)) in chunks.into_inner().into_iter().enumerate() {
|
for (i, (hash, _len)) in chunks.into_inner().into_iter().enumerate() {
|
||||||
try!(self.index.set(&hash, &Location{bundle: bundle_id as u32, chunk: i as u32}));
|
if let Some(old) = try!(self.index.set(&hash, &Location{bundle: bundle_id as u32, chunk: i as u32})) {
|
||||||
|
// Duplicate chunk, forced ordering: higher bundle id wins
|
||||||
|
let old_bundle_id = try!(self.get_bundle_id(old.bundle));
|
||||||
|
if old_bundle_id > bundle.id {
|
||||||
|
try!(self.index.set(&hash, &old));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use std::io::{self, Read, Write};
|
||||||
|
|
||||||
|
|
||||||
#[repr(packed)]
|
#[repr(packed)]
|
||||||
#[derive(Clone, Copy, PartialEq, Hash, Eq, Default)]
|
#[derive(Clone, Copy, PartialEq, Hash, Eq, Default, Ord, PartialOrd)]
|
||||||
pub struct Hash {
|
pub struct Hash {
|
||||||
pub high: u64,
|
pub high: u64,
|
||||||
pub low: u64
|
pub low: u64
|
||||||
|
|
Loading…
Reference in New Issue