···7373 bytes.starts_with(&NODE_FINGERPRINT)
7474 // && bytes.get(3).map(|b| b & 0xF0 == 0x80).unwrap_or(false)
7575 }
7676-}
77767878-impl Node {
7977 /// Check if a node has any entries
8078 ///
8179 /// An empty repository with no records is represented as a single MST node
+46-68
src/walk.rs
···3535 Step { rkey: String, data: T },
3636}
37373838-/// a transformed mst::Node which we can mutate and track progress on
3939-///
4040-/// contains an optional left subtree, whose contents are all to the left of
4141-/// every entry in the entries array.
4242-#[derive(Debug, PartialEq)]
4343-struct ActionNode {
4444- entries: Vec<Need>,
4545-}
4646-4747-impl ActionNode {
4848- fn from_root(tree_root_cid: Cid) -> Self {
4949- ActionNode {
5050- entries: vec![Need::Node(tree_root_cid)],
5151- }
5252- }
5353- fn next(&self) -> Option<Need> {
5454- self.entries.last().cloned()
5555- }
5656- fn found(&mut self) {
5757- self.entries.pop();
5858- }
5959-}
6060-6138#[derive(Debug, Clone, PartialEq)]
6239enum Need {
6340 Node(Cid),
6441 Record { rkey: String, cid: Cid },
6542}
66436767-impl TryFrom<&Node> for ActionNode {
6868- type Error = ActionNodeError;
4444+fn push_from_node(stack: &mut Vec<Need>, node: &Node) -> Result<(), ActionNodeError> {
4545+ let mut entries = Vec::with_capacity(node.entries.len());
69467070- fn try_from(node: &Node) -> Result<Self, Self::Error> {
7171- let mut entries = vec![];
7272-7373- if let Some(tree) = node.left {
7474- entries.push(Need::Node(tree));
7575- }
7676-7777- let mut prefix = vec![];
7878- for entry in &node.entries {
7979- let mut rkey = vec![];
8080- let pre_checked = prefix
8181- .get(..entry.prefix_len)
8282- .ok_or(ActionNodeError::EntryPrefixOutOfbounds)?;
8383- rkey.extend_from_slice(pre_checked);
8484- rkey.extend_from_slice(&entry.keysuffix);
8585- prefix = rkey.clone();
4747+ let mut prefix = vec![];
4848+ for entry in &node.entries {
4949+ let mut rkey = vec![];
5050+ let pre_checked = prefix
5151+ .get(..entry.prefix_len)
5252+ .ok_or(ActionNodeError::EntryPrefixOutOfbounds)?;
5353+ rkey.extend_from_slice(pre_checked);
5454+ rkey.extend_from_slice(&entry.keysuffix);
5555+ prefix = rkey.clone();
86568787- entries.push(Need::Record {
8888- rkey: String::from_utf8(rkey)?,
8989- cid: entry.value,
9090- });
9191- if let Some(ref tree) = entry.tree {
9292- entries.push(Need::Node(*tree));
9393- }
5757+ entries.push(Need::Record {
5858+ rkey: String::from_utf8(rkey)?,
5959+ cid: entry.value,
6060+ });
6161+ if let Some(ref tree) = entry.tree {
6262+ entries.push(Need::Node(*tree));
9463 }
6464+ }
95659696- entries.reverse();
6666+ entries.reverse();
6767+ stack.append(&mut entries);
97689898- Ok(ActionNode { entries })
6969+ if let Some(tree) = node.left {
7070+ stack.push(Need::Node(tree));
9971 }
7272+ Ok(())
10073}
1017410275#[derive(Debug)]
10376pub struct Walker {
104104- stack: Vec<ActionNode>,
7777+ stack: Vec<Need>,
10578}
1067910780impl Walker {
10881 pub fn new(tree_root_cid: Cid) -> Self {
10982 Self {
110110- stack: vec![ActionNode::from_root(tree_root_cid)],
8383+ stack: vec![Need::Node(tree_root_cid)],
11184 }
11285 }
11386···11790 process: impl Fn(&[u8]) -> ProcRes<T, E>,
11891 ) -> Result<Step<T>, Trip<E>> {
11992 loop {
120120- let Some(current_node) = self.stack.last_mut() else {
9393+ let Some(mut need) = self.stack.last() else {
12194 log::trace!("tried to walk but we're actually done.");
12295 return Ok(Step::Finish);
12396 };
124124- let Some(mut need) = current_node.next() else {
125125- self.stack.pop();
126126- continue;
127127- };
1289712998 match &mut need {
13099 Need::Node(cid) => {
···141110 .map_err(|e| Trip::BadCommit(e.into()))?;
142111143112 // found node, make sure we remember
144144- current_node.found();
113113+ self.stack.pop();
145114146115 // queue up work on the found node next
147147- self.stack.push((&node).try_into()?);
116116+ push_from_node(&mut self.stack, &node)?;
148117 }
149118 Need::Record { rkey, cid } => {
150119 log::trace!("need record {cid:?}");
151151- let Some(data) = blocks.get(cid) else {
120120+ let Some(data) = blocks.get_mut(cid) else {
152121 log::trace!("record block not found, resting");
153122 return Ok(Step::Rest(*cid));
154123 };
···156125 let data = match data {
157126 MaybeProcessedBlock::Raw(data) => process(data),
158127 MaybeProcessedBlock::Processed(Ok(t)) => Ok(t.clone()),
159159- MaybeProcessedBlock::Processed(_e) => {
160160- return Err(Trip::RecordFailedProcessing("booo".into()));
161161- } // TODO
128128+ bad => {
129129+ // big hack to pull the error out -- this corrupts
130130+ // a block, so we should not continue trying to work
131131+ let mut steal = MaybeProcessedBlock::Raw(vec![]);
132132+ std::mem::swap(&mut steal, bad);
133133+ let MaybeProcessedBlock::Processed(Err(e)) = steal else {
134134+ unreachable!();
135135+ };
136136+ return Err(Trip::ProcessFailed(e));
137137+ }
162138 };
163139164140 // found node, make sure we remember
165165- current_node.found();
141141+ self.stack.pop();
166142167143 log::trace!("emitting a block as a step. depth={}", self.stack.len());
168144 let data = data.map_err(Trip::ProcessFailed)?;
···230206 left: None,
231207 entries: vec![],
232208 };
233233- let action_node: ActionNode = (&node).try_into().unwrap();
234234- assert_eq!(action_node.next(), None);
209209+ let mut stack = vec![];
210210+ push_from_node(&mut stack, &node).unwrap();
211211+ assert_eq!(stack.last(), None);
235212 }
236213237214 #[test]
···240217 left: Some(cid1()),
241218 entries: vec![],
242219 };
243243- let action_node: ActionNode = (&node).try_into().unwrap();
244244- assert_eq!(action_node.next(), Some(Need::Node(cid1())));
220220+ let mut stack = vec![];
221221+ push_from_node(&mut stack, &node).unwrap();
222222+ assert_eq!(stack.last(), Some(Need::Node(cid1())).as_ref());
245223 }
246224247225 // #[test]