Skip to content

Commit

Permalink
Add export APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
DrChat committed Feb 16, 2025
1 parent f0f2ec0 commit 9e2aa3b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
29 changes: 29 additions & 0 deletions atrium-repo/src/mst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,35 @@ impl<S: AsyncBlockStoreRead> Tree<S> {
algos::compute_depth(&mut self.storage, node.unwrap_or(self.root)).await
}

/// Returns a stream of all CIDs in the tree or referenced by the tree.
pub fn export(&mut self) -> impl Stream<Item = Result<Cid, Error>> + '_ {
// Start from the root of the tree.
let mut stack = vec![Located::InSubtree(self.root)];

try_stream! {
while let Some(e) = stack.pop() {
match e {
Located::InSubtree(cid) => {
let node = Node::read_from(&mut self.storage, cid).await?;
yield cid;

for entry in node.entries.iter().rev() {
match entry {
NodeEntry::Tree(entry) => {
stack.push(Located::InSubtree(*entry));
}
NodeEntry::Leaf(entry) => {
stack.push(Located::Entry(entry.value));
}
}
}
}
Located::Entry(value) => yield value,
}
}
}
}

/// Returns a stream of all entries in this tree, in lexicographic order.
///
/// This function will _not_ work with a partial MST, such as one received from
Expand Down
21 changes: 21 additions & 0 deletions atrium-repo/src/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,27 @@ impl<R: AsyncBlockStoreRead> Repository<R> {
}
}

/// Export a list of all CIDs in the repository.
pub async fn export(&mut self) -> Result<impl Iterator<Item = Cid>, Error> {
let mut mst = mst::Tree::open(&mut self.db, self.latest_commit.data);

let mut r = vec![self.root];
r.extend(mst.export().try_collect::<Vec<_>>().await?);
Ok(r.into_iter())
}

/// Export all CIDs in the repository into a blockstore.
pub async fn export_into(&mut self, mut bs: impl AsyncBlockStoreWrite) -> Result<(), Error> {
let cids = self.export().await?.collect::<HashSet<_>>();

for cid in cids {
bs.write_block(cid.codec(), SHA2_256, self.db.read_block(cid).await?.as_slice())
.await?;
}

Ok(())
}

/// Extract the CIDs associated with a particular record.
///
/// If the record does not exist in this repository, the CIDs returned will point to the
Expand Down

0 comments on commit 9e2aa3b

Please sign in to comment.