Iterator over missing nodes for a set of search roots

This commit is contained in:
Jeremy Wall 2022-09-05 12:02:54 -04:00
parent fdf79c26b1
commit b12c92c9d4
2 changed files with 70 additions and 5 deletions

53
src/dag/iter.rs Normal file
View File

@ -0,0 +1,53 @@
// Copyright 2022 Jeremy Wall (Jeremy@marzhilsltudios.com)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::collections::BTreeSet;
use super::Merkle;
use crate::hash::HashWriter;
use crate::node::Node;
use crate::store::{Result, Store};
pub struct Gap<'dag, S, HW>
where
S: Store<HW>,
HW: HashWriter,
{
dag: &'dag Merkle<S, HW>,
search_nodes: BTreeSet<Vec<u8>>,
}
impl<'dag, S, HW> Gap<'dag, S, HW>
where
S: Store<HW>,
HW: HashWriter,
{
pub fn new(dag: &'dag Merkle<S, HW>, search_nodes: BTreeSet<Vec<u8>>) -> Self {
Self { dag, search_nodes }
}
pub fn next(&mut self) -> Result<Option<Vec<Node<HW>>>> {
let nodes = self
.dag
.find_next_non_descendant_nodes(&self.search_nodes)?;
self.search_nodes = BTreeSet::new();
for id in nodes.iter().map(|n| n.id().to_vec()) {
self.search_nodes.insert(id);
}
if nodes.len() > 0 {
Ok(Some(nodes))
} else {
Ok(None)
}
}
}

View File

@ -21,6 +21,9 @@ use crate::{
store::{Result, Store, StoreError},
};
mod iter;
pub use iter::*;
/// Node comparison values. In a given Merkle DAG a Node can come `After`, `Before`, be `Equivalent`, or `Uncomparable`.
/// If the two nodes have the same id they are eqivalent. If two nodes are not part of the same sub graph within the DAG
/// then they are Uncomparable. If one node is an ancestor of another DAG then that node comes before the other. If the
@ -152,26 +155,35 @@ where
})
}
pub fn gap_fill_iter<'dag, 'iter>(
&'dag self,
search_nodes: BTreeSet<Vec<u8>>,
) -> Gap<'iter, S, HW>
where
'dag: 'iter,
{
Gap::new(self, search_nodes)
}
/// Find the immediate next non descendant nodes in this graph for the given `search_nodes`.
pub fn find_next_non_descendant_nodes(
&self,
search_nodes: &BTreeSet<Vec<u8>>,
) -> Result<Vec<Node<HW>>> {
let mut stack: Vec<Vec<u8>> = dbg!(self.roots.iter().cloned().collect());
dbg!(search_nodes);
let mut stack: Vec<Vec<u8>> = self.roots.iter().cloned().collect();
let mut ids = BTreeSet::new();
while !stack.is_empty() {
let node_id = dbg!(stack.pop().unwrap());
let node_id = stack.pop().unwrap();
let node = self.get_node_by_id(node_id.as_slice())?.unwrap();
let deps = node.dependency_ids();
if dbg!(deps.len()) == 0 {
if deps.len() == 0 {
// This is a leaf node which means it's the beginning of a sub graph
// the search_nodes_are not part of.
ids.insert(node.id().to_owned());
}
for dep in deps {
// We found one of the search roots.
if dbg!(search_nodes.contains(dep.as_slice())) {
if search_nodes.contains(dep.as_slice()) {
// This means that the previous node is a parent of the search_roots.
ids.insert(node.id().to_owned());
continue;