Skip to main content

HashTree

Struct HashTree 

Source
pub struct HashTree<S: Store> { /* private fields */ }
Expand description

HashTree - unified create, read, and edit merkle tree operations

Implementations§

Source§

impl<S: Store> HashTree<S>

Source

pub fn new(config: HashTreeConfig<S>) -> Self

Source

pub fn is_encrypted(&self) -> bool

Check if encryption is enabled

Source

pub async fn put(&self, data: &[u8]) -> Result<(Cid, u64), HashTreeError>

Store content, returns (Cid, size) where Cid is hash + optional key Encrypts by default when encryption feature is enabled

Source

pub async fn get(&self, cid: &Cid) -> Result<Option<Vec<u8>>, HashTreeError>

Get content by Cid (handles decryption automatically)

Source

pub async fn put_stream<R: AsyncRead + Unpin>( &self, reader: R, ) -> Result<(Cid, u64), HashTreeError>

Store content from an async reader (streaming put)

Reads data in chunks and builds a merkle tree incrementally. Useful for large files or streaming data sources. Returns (Cid, size) where Cid is hash + optional key

Source

pub fn get_stream( &self, cid: &Cid, ) -> Pin<Box<dyn Stream<Item = Result<Vec<u8>, HashTreeError>> + Send + '_>>

Read content as a stream of chunks by Cid (handles decryption automatically)

Returns an async stream that yields chunks as they are read. Useful for large files or when you want to process data incrementally.

Source

pub async fn put_blob(&self, data: &[u8]) -> Result<Hash, HashTreeError>

Store a blob directly (small data, no encryption) Returns the content hash

Source

pub async fn put_file(&self, data: &[u8]) -> Result<(Cid, u64), HashTreeError>

Store a file, chunking if necessary Returns (Cid, size) where Cid is hash + optional key

Source

pub async fn put_directory( &self, entries: Vec<DirEntry>, ) -> Result<Cid, HashTreeError>

Build a directory from entries Returns Cid with key if encrypted

For large directories, the messagepack-encoded TreeNode is stored via put() which automatically chunks the data. The reader uses read_file() to reassemble.

Source

pub async fn put_tree_node( &self, links: Vec<Link>, ) -> Result<Hash, HashTreeError>

Create a tree node with custom links

Source

pub async fn get_blob( &self, hash: &Hash, ) -> Result<Option<Vec<u8>>, HashTreeError>

Get raw data by hash

Source

pub async fn get_tree_node( &self, hash: &Hash, ) -> Result<Option<TreeNode>, HashTreeError>

Get and decode a tree node (unencrypted)

Source

pub async fn get_node( &self, cid: &Cid, ) -> Result<Option<TreeNode>, HashTreeError>

Get and decode a tree node using Cid (with decryption if key present)

Source

pub async fn get_directory_node( &self, cid: &Cid, ) -> Result<Option<TreeNode>, HashTreeError>

Get directory node, handling chunked directory data Use this when you know the target is a directory (from parent link_type)

Source

pub async fn is_tree(&self, hash: &Hash) -> Result<bool, HashTreeError>

Check if hash points to a tree node (no decryption)

Source

pub async fn is_dir(&self, cid: &Cid) -> Result<bool, HashTreeError>

Check if Cid points to a directory (with decryption)

Source

pub async fn is_directory(&self, hash: &Hash) -> Result<bool, HashTreeError>

Check if hash points to a directory (tree with named links, no decryption)

Source

pub async fn read_file( &self, hash: &Hash, ) -> Result<Option<Vec<u8>>, HashTreeError>

Read a complete file (reassemble chunks if needed)

Source

pub async fn read_file_range( &self, hash: &Hash, start: u64, end: Option<u64>, ) -> Result<Option<Vec<u8>>, HashTreeError>

Read a byte range from a file (fetches only necessary chunks)

  • start: Starting byte offset (inclusive)
  • end: Ending byte offset (exclusive), or None to read to end

This is more efficient than read_file() for partial reads of large files.

Source

pub async fn read_file_range_cid( &self, cid: &Cid, start: u64, end: Option<u64>, ) -> Result<Option<Vec<u8>>, HashTreeError>

Read a byte range from a file using a Cid (handles decryption if key present)

Source

pub fn read_file_stream( &self, hash: Hash, ) -> Pin<Box<dyn Stream<Item = Result<Vec<u8>, HashTreeError>> + Send + '_>>

Read a file as stream of chunks Returns an async stream that yields chunks as they are read

Source

pub async fn read_file_chunks( &self, hash: &Hash, ) -> Result<Vec<Vec<u8>>, HashTreeError>

Read file chunks as Vec (non-streaming version)

Source

pub async fn list(&self, cid: &Cid) -> Result<Vec<TreeEntry>, HashTreeError>

List directory entries (Cid-based, supports encrypted directories)

Source

pub async fn list_directory( &self, cid: &Cid, ) -> Result<Vec<TreeEntry>, HashTreeError>

List directory entries using Cid (with decryption if key present) Handles both regular and chunked directory data

Source

pub async fn resolve( &self, cid: &Cid, path: &str, ) -> Result<Option<Cid>, HashTreeError>

Resolve a path within a tree (returns Cid with key if encrypted)

Source

pub async fn resolve_path( &self, cid: &Cid, path: &str, ) -> Result<Option<Cid>, HashTreeError>

Resolve a path within a tree using Cid (with decryption if key present)

Source

pub async fn get_size(&self, hash: &Hash) -> Result<u64, HashTreeError>

Get total size of a tree

Source

pub async fn get_size_cid(&self, cid: &Cid) -> Result<u64, HashTreeError>

Get total size using a Cid (handles decryption if key present)

Source

pub async fn walk( &self, cid: &Cid, path: &str, ) -> Result<Vec<WalkEntry>, HashTreeError>

Walk entire tree depth-first (returns Vec)

Source

pub async fn walk_parallel( &self, cid: &Cid, path: &str, concurrency: usize, ) -> Result<Vec<WalkEntry>, HashTreeError>

Walk entire tree with parallel fetching Uses a work-stealing approach: always keeps concurrency requests in flight

Source

pub async fn walk_parallel_with_progress( &self, cid: &Cid, path: &str, concurrency: usize, progress: Option<&AtomicUsize>, ) -> Result<Vec<WalkEntry>, HashTreeError>

Walk entire tree with parallel fetching and optional progress counter The counter is incremented for each node fetched (not just entries found)

OPTIMIZATION: Blobs are NOT fetched - their metadata (hash, size, link_type) comes from the parent node’s link, so we just add them directly to entries. This avoids downloading file contents during tree traversal.

Source

pub fn walk_stream( &self, cid: Cid, initial_path: String, ) -> Pin<Box<dyn Stream<Item = Result<WalkEntry, HashTreeError>> + Send + '_>>

Walk tree as stream

Source

pub async fn set_entry( &self, root: &Cid, path: &[&str], name: &str, entry_cid: &Cid, size: u64, link_type: LinkType, ) -> Result<Cid, HashTreeError>

Add or update an entry in a directory Returns new root Cid (immutable operation)

Source

pub async fn remove_entry( &self, root: &Cid, path: &[&str], name: &str, ) -> Result<Cid, HashTreeError>

Remove an entry from a directory Returns new root Cid

Source

pub async fn rename_entry( &self, root: &Cid, path: &[&str], old_name: &str, new_name: &str, ) -> Result<Cid, HashTreeError>

Rename an entry in a directory Returns new root Cid

Source

pub async fn move_entry( &self, root: &Cid, source_path: &[&str], name: &str, target_path: &[&str], ) -> Result<Cid, HashTreeError>

Move an entry to a different directory Returns new root Cid

Source

pub fn get_store(&self) -> Arc<S>

Get the underlying store

Source

pub fn chunk_size(&self) -> usize

Get chunk size configuration

Get max links configuration

Auto Trait Implementations§

§

impl<S> Freeze for HashTree<S>

§

impl<S> RefUnwindSafe for HashTree<S>
where S: RefUnwindSafe,

§

impl<S> Send for HashTree<S>

§

impl<S> Sync for HashTree<S>

§

impl<S> Unpin for HashTree<S>

§

impl<S> UnwindSafe for HashTree<S>
where S: RefUnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V