From f2739300d623159cb5ff438a7d4c0aee5264653d Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Mon, 22 Aug 2022 08:08:14 +0200 Subject: [PATCH] backup: Speed up searching for parent node --- src/archiver/parent.rs | 49 +++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/archiver/parent.rs b/src/archiver/parent.rs index 371df8b..098428d 100644 --- a/src/archiver/parent.rs +++ b/src/archiver/parent.rs @@ -1,3 +1,5 @@ +use std::cmp::Ordering; + use anyhow::Result; use crate::blob::{Node, Tree}; @@ -7,6 +9,7 @@ use crate::index::IndexedBackend; pub struct Parent { tree: Option, be: BE, + node_idx: usize, } pub enum ParentResult { @@ -26,27 +29,42 @@ impl Parent { Self { tree, be: be.clone(), + node_idx: 0, } } - pub fn p_node(&self, node: &Node) -> Option<&Node> { + pub fn p_node(&mut self, node: &Node) -> Option<&Node> { match &self.tree { None => None, - Some(tree) => tree - .nodes() - .iter() - .find(|p_node| p_node.name() == node.name()), + Some(tree) => { + let name = node.name(); + let p_nodes = tree.nodes(); + loop { + match p_nodes.get(self.node_idx) { + None => break None, + Some(p_node) => match p_node.name().cmp(&name) { + Ordering::Less => self.node_idx += 1, + Ordering::Equal => { + break Some(p_node); + } + Ordering::Greater => { + break None; + } + }, + } + } + } } } - pub fn is_parent(&self, node: &Node) -> ParentResult<&Node> { + pub fn is_parent(&mut self, node: &Node) -> ParentResult<&Node> { match self.p_node(node) { None => ParentResult::NotFound, Some(p_node) => { - if p_node.node_type() == node.node_type() - && p_node.meta().size() == node.meta().size() - && p_node.meta().ctime() == node.meta().ctime() - && (node.meta().inode() == &0 || p_node.meta().inode() == node.meta().inode()) + if p_node.node_type == node.node_type + && p_node.meta.size == node.meta.size + && p_node.meta().ctime == node.meta.ctime + && (node.meta.inode == 0 || p_node.meta.inode == node.meta.inode) { ParentResult::Matched(p_node) } else { @@ -56,18 +74,14 @@ impl Parent { } } - pub async fn sub_parent(&self, node: &Node) -> Result { + pub async fn sub_parent(&mut self, node: &Node) -> Result { let tree = match self.p_node(node) { None => None, Some(p_node) => { if p_node.node_type() == node.node_type() { // TODO: print warning when loading failed - Some( - Tree::from_backend(&self.be, p_node.subtree().unwrap()) - .await - .ok(), - ) - .flatten() + let tree = p_node.subtree.unwrap(); + Some(Tree::from_backend(&self.be, tree).await.ok()).flatten() } else { None } @@ -76,6 +90,7 @@ impl Parent { Ok(Self { tree, be: self.be.clone(), + node_idx: 0, }) } }