mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 09:17:30 +03:00
revisionstore: implement iter for DataStore trait
Summary: We need the ability to iterate over a datastore so we can implement repack and cleanup. In a later diff we'll use this trait to implement repack functionality in a way that it can apply to any store that implements IterableStore. Reviewed By: quark-zju Differential Revision: D8885094 fbshipit-source-id: 0a2b1ab8cf524392d890302c33e386f1cd218d24
This commit is contained in:
parent
8f3b150224
commit
c18a1d04f1
@ -87,6 +87,7 @@ use datastore::{DataStore, Delta, Metadata};
|
||||
use error::Result;
|
||||
use key::Key;
|
||||
use node::Node;
|
||||
use repack::IterableStore;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[fail(display = "Datapack Error: {:?}", _0)]
|
||||
@ -357,6 +358,44 @@ impl DataStore for DataPack {
|
||||
}
|
||||
}
|
||||
|
||||
impl IterableStore for DataPack {
|
||||
fn iter<'a>(&'a self) -> Box<Iterator<Item = Result<Key>> + 'a> {
|
||||
Box::new(DataPackIterator::new(self))
|
||||
}
|
||||
}
|
||||
|
||||
struct DataPackIterator<'a> {
|
||||
pack: &'a DataPack,
|
||||
offset: u64,
|
||||
}
|
||||
|
||||
impl<'a> DataPackIterator<'a> {
|
||||
pub fn new(pack: &'a DataPack) -> Self {
|
||||
DataPackIterator {
|
||||
pack: pack,
|
||||
offset: 1, // Start after the header byte
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for DataPackIterator<'a> {
|
||||
type Item = Result<Key>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.offset as usize >= self.pack.len() {
|
||||
return None;
|
||||
}
|
||||
let entry = self.pack.read_entry(self.offset);
|
||||
Some(match entry {
|
||||
Ok(ref e) => {
|
||||
self.offset = e.next_offset;
|
||||
Ok(Key::new(e.filename.to_vec().into_boxed_slice(), e.node))
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -562,4 +601,64 @@ mod tests {
|
||||
assert_eq!(&chains[i], &chain);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iter() {
|
||||
let mut rng = ChaChaRng::from_seed([0u8; 32]);
|
||||
let tempdir = TempDir::new().unwrap();
|
||||
|
||||
let revisions = vec![
|
||||
(
|
||||
Delta {
|
||||
data: Rc::new([1, 2, 3, 4]),
|
||||
base: Some(Key::new(Box::new([0]), Node::random(&mut rng))),
|
||||
key: Key::new(Box::new([0]), Node::random(&mut rng)),
|
||||
},
|
||||
None,
|
||||
),
|
||||
(
|
||||
Delta {
|
||||
data: Rc::new([1, 2, 3, 4]),
|
||||
base: Some(Key::new(Box::new([0]), Node::random(&mut rng))),
|
||||
key: Key::new(Box::new([0]), Node::random(&mut rng)),
|
||||
},
|
||||
None,
|
||||
),
|
||||
];
|
||||
|
||||
let pack = make_pack(&tempdir, &revisions);
|
||||
assert_eq!(
|
||||
pack.iter().collect::<Result<Vec<Key>>>().unwrap(),
|
||||
revisions
|
||||
.iter()
|
||||
.map(|d| d.0.key.clone())
|
||||
.collect::<Vec<Key>>()
|
||||
);
|
||||
}
|
||||
|
||||
quickcheck! {
|
||||
fn test_iter_quickcheck(keys: Vec<(Vec<u8>, Key)>) -> bool {
|
||||
let tempdir = TempDir::new().unwrap();
|
||||
|
||||
let mut revisions: Vec<(Delta, Option<Metadata>)> = vec![];
|
||||
for (data, key) in keys {
|
||||
revisions.push((
|
||||
Delta {
|
||||
data: Rc::from(data.clone()),
|
||||
base: None,
|
||||
key: key.clone(),
|
||||
},
|
||||
None,
|
||||
));
|
||||
}
|
||||
|
||||
let pack = make_pack(&tempdir, &revisions);
|
||||
let same = pack.iter().collect::<Result<Vec<Key>>>().unwrap()
|
||||
== revisions
|
||||
.iter()
|
||||
.map(|d| d.0.key.clone())
|
||||
.collect::<Vec<Key>>();
|
||||
same
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,5 +28,6 @@ pub mod key;
|
||||
pub mod loosefile;
|
||||
pub mod mutabledatapack;
|
||||
pub mod node;
|
||||
pub mod repack;
|
||||
pub mod uniondatastore;
|
||||
pub mod unionhistorystore;
|
||||
|
6
lib/revisionstore/src/repack.rs
Normal file
6
lib/revisionstore/src/repack.rs
Normal file
@ -0,0 +1,6 @@
|
||||
use error::Result;
|
||||
use key::Key;
|
||||
|
||||
pub trait IterableStore {
|
||||
fn iter<'a>(&'a self) -> Box<Iterator<Item = Result<Key>> + 'a>;
|
||||
}
|
Loading…
Reference in New Issue
Block a user