refactor: make PostOrderIterator 'static

kind of forgot the String and Vec<u8> while trying to impl the Iterator
trait to return non-static values.
This commit is contained in:
Joonas Koivunen 2020-08-07 14:54:34 +03:00
parent 41566e4759
commit fdc5f8aa84
3 changed files with 23 additions and 57 deletions
http/src/v0/root_files
unixfs/src/dir/builder

@ -274,10 +274,7 @@ where
yield next; yield next;
} }
let mut full_path = String::new(); let mut iter = tree.build();
let mut block_buffer = Vec::new();
let mut iter = tree.build(&mut full_path, &mut block_buffer);
while let Some(res) = iter.next_borrowed() { while let Some(res) = iter.next_borrowed() {
let TreeNode { path, cid, total_size, block } = res.map_err(AddError::TreeBuilding)?; let TreeNode { path, cid, total_size, block } = res.map_err(AddError::TreeBuilding)?;

@ -179,19 +179,13 @@ impl BufferingTreeBuilder {
/// Returned `PostOrderIterator` will use the given `full_path` and `block_buffer` to store /// Returned `PostOrderIterator` will use the given `full_path` and `block_buffer` to store
/// its data during the walk. `PostOrderIterator` implements `Iterator` while also allowing /// its data during the walk. `PostOrderIterator` implements `Iterator` while also allowing
/// borrowed access via `next_borrowed`. /// borrowed access via `next_borrowed`.
pub fn build<'a>( pub fn build(self) -> PostOrderIterator {
self,
full_path: &'a mut String,
block_buffer: &'a mut Vec<u8>,
) -> PostOrderIterator<'a> {
PostOrderIterator::new( PostOrderIterator::new(
Visited::Descent { Visited::Descent {
node: self.root_builder, node: self.root_builder,
name: None, name: None,
depth: 0, depth: 0,
}, },
full_path,
block_buffer,
self.opts, self.opts,
) )
} }
@ -223,11 +217,8 @@ mod tests {
.put_file("a/b/c/d/e/i.txt", five_block_foobar, 221) .put_file("a/b/c/d/e/i.txt", five_block_foobar, 221)
.unwrap(); .unwrap();
let mut full_path = String::new(); let actual = builder
let mut buffer = Vec::new(); .build()
let iter = builder.build(&mut full_path, &mut buffer);
let actual = iter
.map(|res| res.map(|n| (n.path, n.cid, n.block))) .map(|res| res.map(|n| (n.path, n.cid, n.block)))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
.unwrap(); .unwrap();
@ -255,11 +246,8 @@ mod tests {
let mut builder = BufferingTreeBuilder::default(); let mut builder = BufferingTreeBuilder::default();
builder.put_file("", some_cid(0), 1).unwrap(); builder.put_file("", some_cid(0), 1).unwrap();
let mut full_path = String::new(); let actual = builder
let mut buffer = Vec::new(); .build()
let iter = builder.build(&mut full_path, &mut buffer);
let actual = iter
.map(|res| res.map(|OwnedTreeNode { path, .. }| path)) .map(|res| res.map(|OwnedTreeNode { path, .. }| path))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
.unwrap(); .unwrap();
@ -298,11 +286,8 @@ mod tests {
.unwrap(); .unwrap();
builder.put_file("b", five_block_foobar, 221).unwrap(); builder.put_file("b", five_block_foobar, 221).unwrap();
let mut full_path = String::new(); let actual = builder
let mut buffer = Vec::new(); .build()
let iter = builder.build(&mut full_path, &mut buffer);
let actual = iter
.map(|res| res.map(|OwnedTreeNode { path, cid, .. }| (path, cid.to_string()))) .map(|res| res.map(|OwnedTreeNode { path, cid, .. }| (path, cid.to_string())))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
.unwrap(); .unwrap();
@ -327,11 +312,8 @@ mod tests {
let mut builder = BufferingTreeBuilder::new(opts); let mut builder = BufferingTreeBuilder::new(opts);
builder.put_file("a", five_block_foobar, 221).unwrap(); builder.put_file("a", five_block_foobar, 221).unwrap();
let mut full_path = String::new(); let actual = builder
let mut buffer = Vec::new(); .build()
let iter = builder.build(&mut full_path, &mut buffer);
let actual = iter
.map(|res| res.map(|OwnedTreeNode { path, cid, .. }| (path, cid.to_string()))) .map(|res| res.map(|OwnedTreeNode { path, cid, .. }| (path, cid.to_string())))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
.unwrap(); .unwrap();
@ -378,11 +360,8 @@ mod tests {
builder.put_file("a/b/c/d/e.txt", some_cid(1), 1).unwrap(); builder.put_file("a/b/c/d/e.txt", some_cid(1), 1).unwrap();
builder.put_file("a/b/c/d/f.txt", some_cid(2), 1).unwrap(); builder.put_file("a/b/c/d/f.txt", some_cid(2), 1).unwrap();
let mut full_path = String::new(); let actual = builder
let mut buffer = Vec::new(); .build()
let iter = builder.build(&mut full_path, &mut buffer);
let actual = iter
.map(|res| res.map(|OwnedTreeNode { path, .. }| path)) .map(|res| res.map(|OwnedTreeNode { path, .. }| path))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
.unwrap(); .unwrap();
@ -414,11 +393,8 @@ mod tests {
let mut builder = BufferingTreeBuilder::default(); let mut builder = BufferingTreeBuilder::default();
builder.put_file("a/b", target, 12).unwrap(); builder.put_file("a/b", target, 12).unwrap();
let mut full_path = String::new(); let actual = builder
let mut buffer = Vec::new(); .build()
let iter = builder.build(&mut full_path, &mut buffer);
let actual = iter
.map(|res| res.map(|n| (n.path, n.cid, n.block))) .map(|res| res.map(|n| (n.path, n.cid, n.block)))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
.unwrap(); .unwrap();

@ -6,10 +6,10 @@ use std::collections::{BTreeMap, HashMap};
/// ///
/// Implements the Iterator interface for owned values and the borrowed version, `next_borrowed`. /// Implements the Iterator interface for owned values and the borrowed version, `next_borrowed`.
/// The tree is fully constructed once this has been exhausted. /// The tree is fully constructed once this has been exhausted.
pub struct PostOrderIterator<'a> { pub struct PostOrderIterator {
full_path: &'a mut String, full_path: String,
old_depth: usize, old_depth: usize,
block_buffer: &'a mut Vec<u8>, block_buffer: Vec<u8>,
// our stack of pending work // our stack of pending work
pending: Vec<Visited>, pending: Vec<Visited>,
// "communication channel" from nested entries back to their parents // "communication channel" from nested entries back to their parents
@ -21,19 +21,12 @@ pub struct PostOrderIterator<'a> {
opts: TreeOptions, opts: TreeOptions,
} }
impl<'a> PostOrderIterator<'a> { impl PostOrderIterator {
pub(super) fn new( pub(super) fn new(root: Visited, opts: TreeOptions) -> Self {
root: Visited,
full_path: &'a mut String,
block_buffer: &'a mut Vec<u8>,
opts: TreeOptions,
) -> Self {
full_path.clear();
PostOrderIterator { PostOrderIterator {
full_path, full_path: Default::default(),
old_depth: 0, old_depth: 0,
block_buffer, block_buffer: Default::default(),
pending: vec![root], pending: vec![root],
persisted_cids: Default::default(), persisted_cids: Default::default(),
reused_children: Vec::new(), reused_children: Vec::new(),
@ -233,7 +226,7 @@ impl<'a> PostOrderIterator<'a> {
Visited::Post { name, depth, .. } => (name.as_deref(), *depth), Visited::Post { name, depth, .. } => (name.as_deref(), *depth),
}; };
update_full_path((self.full_path, &mut self.old_depth), name, depth); update_full_path((&mut self.full_path, &mut self.old_depth), name, depth);
match visited { match visited {
Visited::Descent { node, name, depth } => { Visited::Descent { node, name, depth } => {
@ -339,7 +332,7 @@ impl<'a> PostOrderIterator<'a> {
} }
} }
impl<'a> Iterator for PostOrderIterator<'a> { impl Iterator for PostOrderIterator {
type Item = Result<OwnedTreeNode, TreeConstructionFailed>; type Item = Result<OwnedTreeNode, TreeConstructionFailed>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {