From 5ff3aca3f93781b18042250ab57ae20962443023 Mon Sep 17 00:00:00 2001 From: Chris Dickinson Date: Sun, 1 Dec 2019 16:43:07 -0800 Subject: [PATCH] start stubbing in "pack" command --- src/bin/eos.rs | 5 ++++- src/stores/loose.rs | 54 +++++++++++++++++++++++++++++++++++++++------ src/stores/mod.rs | 4 +++- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/bin/eos.rs b/src/bin/eos.rs index d088f6d..5e819d2 100644 --- a/src/bin/eos.rs +++ b/src/bin/eos.rs @@ -21,6 +21,8 @@ enum Command { }, Get { hashes: Vec + }, + Pack { } } @@ -118,7 +120,8 @@ async fn main () -> anyhow::Result<()> { let loose = LooseStore::::new(destination); match &eos.command { Command::Add { files } => cmd_add(loose, files).await?, - Command::Get { hashes } => cmd_get(loose, hashes).await? + Command::Get { hashes } => cmd_get(loose, hashes).await?, + Command::Pack { } => loose.to_packed_store().await? }; Ok(()) } diff --git a/src/stores/loose.rs b/src/stores/loose.rs index 1461377..206d9f9 100644 --- a/src/stores/loose.rs +++ b/src/stores/loose.rs @@ -14,6 +14,7 @@ use std::io::Write; use flate2::write::{ ZlibEncoder }; use flate2::bufread::{ ZlibDecoder }; use flate2::Compression; +use std::pin::Pin; #[derive(Clone)] pub struct LooseStore { @@ -34,16 +35,52 @@ impl LooseStore { 0 } - pub async fn to_packed_store() -> anyhow::Result<()> { - // enumerate all objects - // fill out objects with recency/sortorderinfo - // sort objects by type, then "sortpath" (basename/dir for blobs, semver order descending for packages) - // walk each object type with a sliding window of comparisons. write deltas if they're >50% compression. - // + // enumerate all objects + // fill out objects with recency/sortorderinfo + // - sort objects by type, then "sortpath" + // - basename/dir for blobs, semver order descending for packages + // - walk each object type with a sliding window of comparisons. + // - write deltas if they're >50% compression. + pub async fn to_packed_store(&self) -> anyhow::Result<()> { + let entries: Vec = std::fs::read_dir(&self.location)? + .filter_map(|xs| { + let dent = xs.ok()?; + let filename = dent.file_name(); + let name = filename.to_string_lossy(); + if name.len() != 2 { + return None + } + name.parse::().ok()?; + Some(dent.path()) + }) + .filter_map(|fullpath| { + Some(std::fs::read_dir(&fullpath).ok()?.filter_map(|xs| { + let dent = xs.ok()?; + let name = dent.file_name(); + Some(format!("{}{}", fullpath.file_name()?.to_string_lossy(), name.to_string_lossy())) + }).collect::>()) + }) + .flatten() + .collect(); + + println!("len={}", entries.len()); Ok(()) } } +#[derive(Clone)] +pub struct LooseObjectStream { + location: PathBuf, + phantom: PhantomData +} + +impl Stream for LooseObjectStream { + type Item = Object>; + fn poll_next(self: Pin<&mut Self>, cx: &mut futures::task::Context) -> futures::task::Poll> { + unimplemented!(); + } +} + #[async_trait] impl WritableStore for LooseStore { async fn add + Send>(&self, object: Object) -> anyhow::Result { @@ -108,6 +145,8 @@ impl WritableStore for LooseStore { #[async_trait] impl ReadableStore for LooseStore { + type ObjectStream = LooseObjectStream; + async fn get + Send>(&self, item: T) -> anyhow::Result>>> { let bytes = item.as_ref(); let bytes_encoded = hex::encode(bytes); @@ -162,7 +201,8 @@ impl ReadableStore for LooseStore { } } - async fn list>>(&self) -> R { + async fn list(&self) -> Self::ObjectStream { + unimplemented!() } diff --git a/src/stores/mod.rs b/src/stores/mod.rs index 92ea0e5..9ff209d 100644 --- a/src/stores/mod.rs +++ b/src/stores/mod.rs @@ -24,7 +24,9 @@ pub trait WritableStore { #[async_trait] pub trait ReadableStore { + type ObjectStream; + async fn get + Send>(&self, item: T) -> anyhow::Result>>>; - async fn list>>(&self) -> R; + async fn list(&self) -> Self::ObjectStream; async fn get_stream<'a, T: AsRef<[u8]> + Send, R: Stream>(&self, item: T) -> Option; }