mirror of
https://github.com/facebook/sapling.git
synced 2024-10-08 07:49:11 +03:00
revisionstore: add AncestorIterator class
Summary: This moves the ancestor iteration logic for cases where we iterate one by one. This will be used by the HistoryPack code in upcoming diffs. Reviewed By: quark-zju Differential Revision: D9136978 fbshipit-source-id: e60b0a1e2ee5036938b51bbd910fbaf548d7aa75
This commit is contained in:
parent
550d912ae0
commit
c8d9db34df
@ -9,6 +9,12 @@ use key::Key;
|
||||
#[fail(display = "Ancestor Iterator Error: {:?}", _0)]
|
||||
struct AncestorIteratorError(String);
|
||||
|
||||
pub struct AncestorIterator<T: Fn(&Key, &HashSet<Key>) -> Result<NodeInfo>> {
|
||||
get_more: T,
|
||||
seen: HashSet<Key>,
|
||||
queue: VecDeque<Key>,
|
||||
}
|
||||
|
||||
pub struct BatchedAncestorIterator<T: Fn(&Key, &HashSet<Key>) -> Result<Ancestors>> {
|
||||
get_more: T,
|
||||
seen: HashSet<Key>,
|
||||
@ -16,6 +22,18 @@ pub struct BatchedAncestorIterator<T: Fn(&Key, &HashSet<Key>) -> Result<Ancestor
|
||||
pending_infos: HashMap<Key, NodeInfo>,
|
||||
}
|
||||
|
||||
impl<T: Fn(&Key, &HashSet<Key>) -> Result<NodeInfo>> AncestorIterator<T> {
|
||||
pub fn new(key: &Key, get_more: T) -> Self {
|
||||
let mut iter = AncestorIterator {
|
||||
get_more: get_more,
|
||||
seen: HashSet::new(),
|
||||
queue: VecDeque::new(),
|
||||
};
|
||||
iter.queue.push_back(key.clone());
|
||||
iter
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Fn(&Key, &HashSet<Key>) -> Result<Ancestors>> BatchedAncestorIterator<T> {
|
||||
pub fn new(key: &Key, get_more: T) -> Self {
|
||||
let mut iter = BatchedAncestorIterator {
|
||||
@ -29,6 +47,29 @@ impl<T: Fn(&Key, &HashSet<Key>) -> Result<Ancestors>> BatchedAncestorIterator<T>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Fn(&Key, &HashSet<Key>) -> Result<NodeInfo>> Iterator for AncestorIterator<T> {
|
||||
type Item = Result<(Key, NodeInfo)>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(current) = self.queue.pop_front() {
|
||||
match (self.get_more)(¤t, &self.seen) {
|
||||
Err(e) => Some(Err(e)),
|
||||
Ok(node_info) => {
|
||||
self.seen.insert(current.clone());
|
||||
for parent in node_info.parents.iter() {
|
||||
if !self.seen.contains(parent) {
|
||||
self.queue.push_back(parent.clone());
|
||||
}
|
||||
}
|
||||
Some(Ok((current, node_info.clone())))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Fn(&Key, &HashSet<Key>) -> Result<Ancestors>> Iterator for BatchedAncestorIterator<T> {
|
||||
type Item = Result<(Key, NodeInfo)>;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user