···11//! Consume a CAR from an AsyncRead, producing an ordered stream of records
2233+use crate::Bytes;
34use crate::HashMap;
45use crate::disk::{DiskError, DiskStore};
56use crate::mst::Node;
66-use bytes::Bytes;
77use cid::Cid;
88use iroh_car::CarReader;
99use std::convert::Infallible;
···2121 BadBlock(#[from] serde_ipld_dagcbor::DecodeError<Infallible>),
2222 #[error("The Commit block reference by the root was not found")]
2323 MissingCommit,
2424- #[error("The MST block {0} could not be found")]
2525- MissingBlock(Cid),
2624 #[error("Failed to walk the mst tree: {0}")]
2725 WalkError(#[from] WalkError),
2826 #[error("CAR file had no roots")]
···8078 }
8179 pub(crate) fn into_bytes(self) -> Bytes {
8280 match self {
8383- MaybeProcessedBlock::Raw(b) => {
8484- let mut owned = b.try_into_mut().unwrap();
8585- owned.extend_from_slice(&[0x00]);
8686- owned.into()
8181+ MaybeProcessedBlock::Raw(mut b) => {
8282+ b.push(0x00);
8383+ b
8784 }
8888- MaybeProcessedBlock::Processed(b) => {
8989- let mut owned = b.try_into_mut().unwrap();
9090- owned.extend_from_slice(&[0x01]);
9191- owned.into()
8585+ MaybeProcessedBlock::Processed(mut b) => {
8686+ b.push(0x01);
8787+ b
9288 }
9389 }
9490 }
9591 pub(crate) fn from_bytes(mut b: Bytes) -> Self {
9692 // TODO: make sure bytes is not empty, that it's explicitly 0 or 1, etc
9797- let suffix = b.split_off(b.len() - 1);
9898- if *suffix == [0x00] {
9393+ let suffix = b.pop().unwrap();
9494+ if suffix == 0x00 {
9995 MaybeProcessedBlock::Raw(b)
10096 } else {
10197 MaybeProcessedBlock::Processed(b)
···292288 for _ in 0..n {
293289 // walk as far as we can until we run out of blocks or find a record
294290 match self.walker.step(&mut self.blocks, self.process)? {
295295- Step::Missing(cid) => return Err(DriveError::MissingBlock(cid)),
296291 Step::Finish => break,
297292 Step::Found { rkey, data } => {
298293 out.push((rkey, data));
···465460 }
466461 };
467462 match step {
468468- Step::Missing(cid) => {
469469- return (state, Err(DriveError::MissingBlock(cid)));
470470- }
471463 Step::Finish => break,
472464 Step::Found { rkey, data } => out.push((rkey, data)),
473465 };
···508500 };
509501510502 match step {
511511- Step::Missing(cid) => {
512512- return tx.blocking_send(Err(DriveError::MissingBlock(cid)));
513513- }
514503 Step::Finish => return Ok(()),
515504 Step::Found { rkey, data } => {
516505 out.push((rkey, data));
+3
src/lib.rs
···9191pub use drive::{DriveError, Driver, DriverBuilder, NeedDisk, noop};
9292pub use mst::Commit;
93939494+// pub use bytes::Bytes;
9595+pub type Bytes = Vec<u8>;
9696+9497pub(crate) use hashbrown::HashMap;
+11-14
src/walk.rs
···11//! Depth-first MST traversal
2233+use crate::Bytes;
34use crate::HashMap;
45use crate::disk::DiskStore;
56use crate::drive::MaybeProcessedBlock;
67use crate::mst::Node;
77-use bytes::Bytes;
88use cid::Cid;
99use sha2::{Digest, Sha256};
1010use std::convert::Infallible;
···2020 MstError(#[from] MstError),
2121 #[error("storage error: {0}")]
2222 StorageError(#[from] fjall::Error),
2323+ #[error("block not found: {0}")]
2424+ MissingBlock(Cid),
2325}
24262527/// Errors from invalid Rkeys
···4446/// Walker outputs
4547#[derive(Debug)]
4648pub enum Step {
4747- /// We needed this CID but it's not in the block store
4848- Missing(Cid),
4949 /// Reached the end of the MST! yay!
5050 Finish,
5151 /// A record was found!
···189189 &mut Need::Node { depth, cid } => {
190190 log::trace!("need node {cid:?}");
191191 let Some(block) = blocks.remove(&cid) else {
192192- log::trace!("node not found, resting");
193193- return Ok(Step::Missing(cid));
192192+ return Err(WalkError::MissingBlock(cid));
194193 };
195194196195 let MaybeProcessedBlock::Raw(data) = block else {
···209208 log::trace!("need record {cid:?}");
210209 // note that we cannot *remove* a record block, sadly, since
211210 // there can be multiple rkeys pointing to the same cid.
212212- let Some(data) = blocks.get_mut(cid) else {
213213- return Ok(Step::Missing(*cid));
211211+ let Some(data) = blocks.get(cid) else {
212212+ return Err(WalkError::MissingBlock(*cid));
214213 };
215214 let rkey = rkey.clone();
216215 let data = match data {
···251250 let cid_bytes = cid.to_bytes();
252251 log::trace!("need node {cid:?}");
253252 let Some(block_slice) = reader.get(&cid_bytes)? else {
254254- log::trace!("node not found, resting");
255255- return Ok(Step::Missing(cid));
253253+ return Err(WalkError::MissingBlock(cid));
256254 };
257255258258- let block = MaybeProcessedBlock::from_bytes(block_slice.into()); // TODO shouldn't fjalls slice already be bytes
256256+ let block = MaybeProcessedBlock::from_bytes(block_slice.to_vec());
259257260258 let MaybeProcessedBlock::Raw(data) = block else {
261259 return Err(WalkError::BadCommitFingerprint);
···273271 log::trace!("need record {cid:?}");
274272 let cid_bytes = cid.to_bytes();
275273 let Some(data_slice) = reader.get(&cid_bytes)? else {
276276- log::trace!("record block not found, resting");
277277- return Ok(Step::Missing(*cid));
274274+ return Err(WalkError::MissingBlock(*cid));
278275 };
279279- let data = MaybeProcessedBlock::from_bytes(data_slice.into());
276276+ let data = MaybeProcessedBlock::from_bytes(data_slice.to_vec());
280277 let rkey = rkey.clone();
281278 let data = match data {
282279 MaybeProcessedBlock::Raw(data) => process(data),
283283- MaybeProcessedBlock::Processed(t) => t.clone(),
280280+ MaybeProcessedBlock::Processed(t) => t,
284281 };
285282286283 // found node, make sure we remember