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;
|
||||
|
||||
|
||||
#[derive(Hash, PartialEq, Eq, Clone, Default)]
|
||||
#[derive(Hash, PartialEq, Eq, Clone, Default, Ord, PartialOrd)]
|
||||
pub struct BundleId(pub Hash);
|
||||
|
||||
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.
|
||||
/// If the key existed in the table before, it is overwritten and false is returned.
|
||||
/// Otherwise it will be added to the table and true is returned.
|
||||
pub fn set(&mut self, key: &Hash, data: &Location) -> Result<bool, IndexError> {
|
||||
/// If the key existed the old data is returned.
|
||||
pub fn set(&mut self, key: &Hash, data: &Location) -> Result<Option<Location>, IndexError> {
|
||||
match self.locate(key) {
|
||||
LocateResult::Found(pos) => {
|
||||
self.data[pos].data = *data;
|
||||
Ok(false)
|
||||
let mut old = *data;
|
||||
mem::swap(&mut old, &mut self.data[pos].data);
|
||||
Ok(Some(old))
|
||||
},
|
||||
LocateResult::Hole(pos) => {
|
||||
{
|
||||
|
@ -356,7 +356,7 @@ impl Index {
|
|||
entry.data = *data;
|
||||
}
|
||||
try!(self.increase_count());
|
||||
Ok(true)
|
||||
Ok(None)
|
||||
},
|
||||
LocateResult::Steal(pos) => {
|
||||
let mut stolen_key;
|
||||
|
@ -382,7 +382,7 @@ impl Index {
|
|||
}
|
||||
}
|
||||
try!(self.increase_count());
|
||||
Ok(true)
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -268,7 +268,7 @@ impl Repository {
|
|||
BundleMode::Meta => self.next_meta_bundle
|
||||
};
|
||||
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 {
|
||||
self.next_meta_bundle = self.next_free_bundle_id()
|
||||
}
|
||||
|
@ -276,7 +276,13 @@ impl Repository {
|
|||
self.next_data_bundle = self.next_free_bundle_id()
|
||||
}
|
||||
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(())
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use std::io::{self, Read, Write};
|
|||
|
||||
|
||||
#[repr(packed)]
|
||||
#[derive(Clone, Copy, PartialEq, Hash, Eq, Default)]
|
||||
#[derive(Clone, Copy, PartialEq, Hash, Eq, Default, Ord, PartialOrd)]
|
||||
pub struct Hash {
|
||||
pub high: u64,
|
||||
pub low: u64
|
||||
|
|
Loading…
Reference in New Issue