···36363737 let limit_mb = 32;
38383939- let mut driver =
4040- match repo_stream::drive::load_car(reader, |block| S(block.len()), 10 * mb).await? {
4141- repo_stream::drive::Vehicle::Lil(_, _) => panic!("try this on a bigger car"),
4242- repo_stream::drive::Vehicle::Big(big_stuff) => {
4343- let disk_store = repo_stream::disk::SqliteStore::new(tmpfile.clone(), limit_mb);
4444- let (commit, driver) = big_stuff.finish_loading(disk_store).await?;
4545- log::warn!("big: {:?}", commit);
4646- driver
4747- }
4848- };
4949-5050- println!("hello!");
3939+ let driver = match repo_stream::drive::load_car(reader, |block| S(block.len()), 10 * mb).await?
4040+ {
4141+ repo_stream::drive::Vehicle::Lil(_, _) => panic!("try this on a bigger car"),
4242+ repo_stream::drive::Vehicle::Big(big_stuff) => {
4343+ let disk_store = repo_stream::disk::SqliteStore::new(tmpfile.clone(), limit_mb);
4444+ let (commit, driver) = big_stuff.finish_loading(disk_store).await?;
4545+ log::warn!("big: {:?}", commit);
4646+ driver
4747+ }
4848+ };
51495250 let mut n = 0;
5353- loop {
5454- let (d, p) = driver.next_chunk(1024).await?;
5555- driver = d;
5656- let Some(pairs) = p else {
5757- break;
5858- };
5151+ let (mut rx, worker) = driver.rx(512).await?;
5252+5353+ log::debug!("walking...");
5454+ while let Some(pairs) = rx.recv().await {
5955 n += pairs.len();
6060- // log::info!("got {rkey:?}");
6156 }
5757+ log::debug!("done walking! joining...");
5858+5959+ worker.await.unwrap().unwrap();
6060+6161+ log::debug!("joined.");
6262+6263 // log::info!("now is the time to check mem...");
6364 // tokio::time::sleep(std::time::Duration::from_secs(22)).await;
6464- drop(driver);
6565 log::info!("bye! {n}");
66666767 std::fs::remove_file(tmpfile).unwrap(); // need to also remove -shm -wal
+46
src/drive.rs
···330330 Ok((self, Some(out)))
331331 }
332332 }
333333+334334+ pub async fn rx(
335335+ mut self,
336336+ n: usize,
337337+ ) -> Result<
338338+ (
339339+ tokio::sync::mpsc::Receiver<Vec<(String, T)>>,
340340+ tokio::task::JoinHandle<Result<(), DiskDriveError>>,
341341+ ),
342342+ DiskDriveError,
343343+ > {
344344+ let (tx, rx) = tokio::sync::mpsc::channel::<Vec<(String, T)>>(1);
345345+346346+ // sketch: this worker is going to be allowed to execute without a join handle
347347+ // ...should we return the join handle here so the caller at least knows about it?
348348+ // yes probably for error handling?? (orrr put errors in the channel)
349349+ let worker = tokio::task::spawn_blocking(move || {
350350+ let mut reader = self.access.get_reader()?;
351351+352352+ loop {
353353+ let mut out = Vec::with_capacity(n);
354354+355355+ for _ in 0..n {
356356+ // walk as far as we can until we run out of blocks or find a record
357357+ match self.walker.disk_step(&mut reader, self.process)? {
358358+ Step::Missing(cid) => return Err(DiskDriveError::MissingBlock(cid)),
359359+ Step::Finish => break,
360360+ Step::Step { rkey, data } => {
361361+ out.push((rkey, data));
362362+ continue;
363363+ }
364364+ };
365365+ }
366366+367367+ if out.is_empty() {
368368+ break;
369369+ }
370370+ tx.blocking_send(out).unwrap();
371371+ }
372372+373373+ drop(reader); // cannot outlive access
374374+ Ok(())
375375+ }); // await later
376376+377377+ Ok((rx, worker))
378378+ }
333379}
334380335381/// The core driver between the block stream and MST walker