Enforce ordering for bundles with duplicate chunks (closes #13)

This commit is contained in:
Dennis Schwerdel 2017-04-16 21:06:59 +02:00
parent e0f4f30933
commit ca7153117b
4 changed files with 17 additions and 11 deletions

View File

@ -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 {

View File

@ -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)
}
}
}

View File

@ -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(())
}

View File

@ -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