···77 mst::MstNode,
88 walk::{MstError, Output},
99};
1010-use std::collections::BTreeMap;
1110use cid::Cid;
1211use iroh_car::CarReader;
1312use std::convert::Infallible;
···185184 pub async fn load_car<R: AsyncRead + Unpin>(&self, reader: R) -> Result<Driver<R>, DriveError> {
186185 Driver::load_car(reader, self.block_processor, self.mem_limit_mb).await
187186 }
188188-189189- /// Begin processing an atproto MST from a CAR file
190190- pub async fn count_entries<R: AsyncRead + Unpin>(&self, reader: R) -> Result<Option<BTreeMap<usize, usize>>, DriveError> {
191191- Driver::count_entries(reader).await
192192- }
193187}
194188195189impl<R: AsyncRead + Unpin> Driver<R> {
196196- pub async fn count_entries(
197197- reader: R,
198198- ) -> Result<Option<BTreeMap<usize, usize>>, DriveError> {
199199- let mut mem_blocks: HashMap<ObjectLink, _> = HashMap::new();
200200-201201- let mut car = CarReader::new(reader).await?;
202202-203203- let roots = car.header().roots();
204204- assert_eq!(roots.len(), 1);
205205-206206- let root = *roots.first().ok_or(DriveError::MissingRoot)?;
207207- log::debug!("root: {root:?}");
208208-209209- let mut commit = None;
210210-211211-212212- // try to load all the blocks into memory
213213- while let Some((cid, data)) = car.next_block().await? {
214214- // the root commit is a Special Third Kind of block that we need to make
215215- // sure not to optimistically send to the processing function
216216- if cid == root {
217217- let c: Commit = serde_ipld_dagcbor::from_slice(&data)?;
218218- commit = Some(c);
219219- continue;
220220- }
221221- let maybe_processed = MaybeProcessedBlock::maybe(|_| vec![], data);
222222-223223- // stash (maybe processed) blocks in memory as long as we have room
224224- mem_blocks.insert(cid.into(), maybe_processed);
225225- }
226226-227227- let commit = commit.ok_or(DriveError::MissingCommit)?;
228228-229229- // the commit always must point to a Node; empty node => empty MST special case
230230- let root_node: MstNode = match mem_blocks
231231- .get(&commit.data)
232232- .ok_or(DriveError::MissingCommit)?
233233- {
234234- MaybeProcessedBlock::Processed(_) => Err(WalkError::BadCommitFingerprint)?,
235235- MaybeProcessedBlock::Raw(bytes) => serde_ipld_dagcbor::from_slice(bytes)?,
236236- };
237237-238238- if root_node.depth.unwrap_or(0) < 4 {
239239- return Ok(None);
240240- }
241241-242242- let mut walker = Walker::new(root_node);
243243- Ok(Some(walker.count_entries(&mut mem_blocks)?))
244244- }
245190246191 /// Begin processing an atproto MST from a CAR file
247192 ///