Skip to main content

HashtreeStore

Struct HashtreeStore 

Source
pub struct HashtreeStore { /* private fields */ }

Implementations§

Source§

impl HashtreeStore

Source

pub fn upload_file<P: AsRef<Path>>(&self, file_path: P) -> Result<String>

Upload a file as raw plaintext and return its CID, with auto-pin

Source

pub fn upload_file_no_pin<P: AsRef<Path>>(&self, file_path: P) -> Result<String>

Upload a file without pinning (for blossom uploads that can be evicted)

Source

pub fn upload_file_with_chunk_size<P: AsRef<Path>>( &self, file_path: P, chunk_size: Option<usize>, ) -> Result<String>

Source

pub fn upload_file_with_chunk_size_and_progress<P: AsRef<Path>>( &self, file_path: P, chunk_size: Option<usize>, progress: &AddProgress, ) -> Result<String>

Source

pub fn upload_file_stream<R: Read, F>( &self, reader: R, _file_name: impl Into<String>, callback: F, ) -> Result<String>
where F: FnMut(&str),

Upload a file from a stream with progress callbacks

Source

pub fn upload_dir<P: AsRef<Path>>(&self, dir_path: P) -> Result<String>

Upload a directory and return its root hash (hex) Respects .gitignore and ignores common OS junk files by default.

Source

pub fn upload_dir_with_options<P: AsRef<Path>>( &self, dir_path: P, respect_gitignore: bool, ) -> Result<String>

Upload a directory with options as raw plaintext (no CHK encryption)

Source

pub fn upload_dir_with_options_and_chunk_size<P: AsRef<Path>>( &self, dir_path: P, respect_gitignore: bool, chunk_size: Option<usize>, ) -> Result<String>

Source

pub fn upload_dir_with_options_and_chunk_size_and_progress<P: AsRef<Path>>( &self, dir_path: P, respect_gitignore: bool, chunk_size: Option<usize>, progress: &AddProgress, ) -> Result<String>

Source

pub fn upload_file_encrypted<P: AsRef<Path>>( &self, file_path: P, ) -> Result<String>

Upload a file with CHK encryption, returns CID in format “hash:key”

Source

pub fn upload_file_encrypted_with_chunk_size<P: AsRef<Path>>( &self, file_path: P, chunk_size: Option<usize>, ) -> Result<String>

Source

pub fn upload_file_encrypted_with_chunk_size_and_progress<P: AsRef<Path>>( &self, file_path: P, chunk_size: Option<usize>, progress: &AddProgress, ) -> Result<String>

Source

pub fn upload_dir_encrypted<P: AsRef<Path>>( &self, dir_path: P, ) -> Result<String>

Upload a directory with CHK encryption, returns CID Respects .gitignore and ignores common OS junk files by default.

Source

pub fn upload_dir_encrypted_with_options<P: AsRef<Path>>( &self, dir_path: P, respect_gitignore: bool, ) -> Result<String>

Upload a directory with CHK encryption and options Returns CID as “hash:key” format for encrypted directories

Source

pub fn upload_dir_encrypted_with_options_and_chunk_size<P: AsRef<Path>>( &self, dir_path: P, respect_gitignore: bool, chunk_size: Option<usize>, ) -> Result<String>

Source

pub fn upload_dir_encrypted_with_options_and_chunk_size_and_progress<P: AsRef<Path>>( &self, dir_path: P, respect_gitignore: bool, chunk_size: Option<usize>, progress: &AddProgress, ) -> Result<String>

Source§

impl HashtreeStore

Source

pub fn gc(&self) -> Result<GcStats>

Garbage collect unpinned content

Source

pub fn verify_lmdb_integrity(&self, delete: bool) -> Result<VerifyResult>

Verify LMDB blob integrity - checks that stored data matches its key hash Returns verification statistics and optionally deletes corrupted entries

Source

pub async fn verify_r2_integrity(&self, _delete: bool) -> Result<VerifyResult>

Fallback for non-S3 builds

Source

pub fn compact_lmdb_environments( &self, env_dirs: &[PathBuf], keep_backup: bool, ) -> Result<Vec<CompactResult>>

Source§

impl HashtreeStore

Source

pub fn make_room_for_cached_blob(&self, incoming_bytes: u64) -> Result<u64>

Source

pub fn enforce_cached_blob_budget_after_insert( &self, inserted_bytes: u64, ) -> Result<u64>

Source

pub fn make_room_for_durable_blob(&self, incoming_bytes: u64) -> Result<u64>

Source

pub fn enforce_durable_blob_budget_after_insert( &self, inserted_bytes: u64, ) -> Result<u64>

Source

pub fn relieve_cached_blob_write_pressure( &self, incoming_bytes: u64, ) -> Result<u64>

Source

pub fn pin(&self, hash: &[u8; 32]) -> Result<()>

Pin a hash (prevent garbage collection)

Source

pub fn unpin(&self, hash: &[u8; 32]) -> Result<()>

Unpin a hash (allow garbage collection)

Source

pub fn is_pinned(&self, hash: &[u8; 32]) -> Result<bool>

Check if hash is pinned

Source

pub fn list_pins_raw(&self) -> Result<Vec<[u8; 32]>>

List all pinned hashes (raw bytes)

Source

pub fn list_pins_with_names(&self) -> Result<Vec<PinnedItem>>

List all pinned hashes with names

Source

pub fn owned_blob_stats(&self) -> Result<Vec<OwnedBlobStats>>

Source

pub fn tree_index_limits(&self) -> TreeIndexLimits

Bounds complete-DAG indexing by both the configured storage budget and an absolute traversal-node ceiling. A zero storage budget means the raw store is unbounded, but authenticated requests still retain a hard cap.

Source

pub fn pin_and_index_tree( &self, root: &Cid, owner: &str, name: Option<&str>, priority: u8, limits: TreeIndexLimits, ) -> Result<PinTreeResult, PinTreeError>

Validate every referenced blob, then index all descendants and pin the root in one LMDB transaction. No pin or index metadata is written if traversal, decryption, decoding, or resource validation fails.

Source

pub fn index_tree( &self, root_hash: &Hash, owner: &str, name: Option<&str>, priority: u8, ref_key: Option<&str>, ) -> Result<()>

Index a tree after sync - tracks all blobs in the tree for eviction

If ref_key is provided (e.g. “npub…/name”), it will replace any existing tree with that ref, allowing old versions to be evicted.

Source

pub fn unindex_tree(&self, root_hash: &Hash) -> Result<u64>

Unindex a tree - removes blob-tree mappings and deletes orphaned blobs Returns the number of bytes freed

Source

pub fn get_tree_meta(&self, root_hash: &Hash) -> Result<Option<TreeMeta>>

Get tree metadata

Source

pub fn get_tree_ref(&self, key: &str) -> Result<Option<Hash>>

Source

pub fn list_indexed_trees(&self) -> Result<Vec<(Hash, TreeMeta)>>

List all indexed trees

Source

pub fn tracked_size(&self) -> Result<u64>

Get total tracked storage size (sum of all tree_meta.total_size)

Source

pub fn evict_if_needed(&self) -> Result<u64>

Run eviction if storage is over quota Returns bytes freed

Eviction order:

  1. Orphaned blobs (not in any indexed tree and not pinned)
  2. Trees by priority (lowest first) and access age (least recent first)
Source

pub fn max_size_bytes(&self) -> u64

Get the maximum storage size in bytes

Source

pub fn storage_by_priority(&self) -> Result<StorageByPriority>

Get storage usage by priority tier

Source

pub fn get_storage_stats(&self) -> Result<StorageStats>

Get storage statistics

Source§

impl HashtreeStore

Source

pub fn new<P: AsRef<Path>>(path: P) -> Result<Self>

Create a new store with the configured local storage limit.

Source

pub fn new_with_backend<P: AsRef<Path>>( path: P, backend: StorageBackend, max_size_bytes: u64, ) -> Result<Self>

Create a new store with an explicit local backend and size limit.

Source

pub fn with_s3<P: AsRef<Path>>( path: P, s3_config: Option<&S3Config>, ) -> Result<Self>

Create a new store with optional S3 backend and the configured local storage limit.

Source

pub fn with_options<P: AsRef<Path>>( path: P, s3_config: Option<&S3Config>, max_size_bytes: u64, ) -> Result<Self>

Create a new store with optional S3 backend and custom size limit.

The raw local blob backend remains unbounded. HashtreeStore enforces max_size_bytes at the tree-management layer so eviction can honor pins, orphan handling, and local-only eviction when S3 is used as archive.

Source

pub fn with_options_and_backend<P: AsRef<Path>>( path: P, s3_config: Option<&S3Config>, max_size_bytes: u64, evict_orphans: bool, backend: &StorageBackend, ) -> Result<Self>

Source

pub fn with_embedded_options<P: AsRef<Path>>( path: P, s3_config: Option<&S3Config>, max_size_bytes: u64, ) -> Result<Self>

Create a store for an embedded, single-process hashtree host.

The macOS app sandbox denies LMDB’s default System V semaphore locks. The embedded host owns this data directory in one process, so it uses external process isolation plus LMDB NO_LOCK for metadata and the filesystem blob backend to avoid opening a second LMDB environment.

Source

pub fn base_path(&self) -> &Path

Source

pub fn router(&self) -> &StorageRouter

Get the storage router

Source

pub fn store_arc(&self) -> Arc<StorageRouter>

Get the storage router as Arc (for use with HashTree which needs Arc) All writes through this go to both LMDB and S3

Source

pub fn force_sync(&self) -> Result<()>

Source

pub fn record_blob_accesses<I>(&self, hashes: I)
where I: IntoIterator<Item = Hash>,

Source

pub fn blob_last_accessed_at(&self, hash: &Hash) -> Result<Option<u64>>

Source

pub fn blob_last_accessed_many( &self, hashes: &[Hash], ) -> Result<Vec<(Hash, u64)>>

Source

pub fn get_tree_node(&self, hash: &[u8; 32]) -> Result<Option<TreeNode>>

Get tree node by hash (raw bytes)

Source

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

Store a raw blob, returns SHA256 hash as hex.

Source

pub fn put_owned_blob_with_inserted( &self, data: &[u8], pubkey: &[u8; 32], ) -> Result<(String, bool)>

Store an owned Blossom blob under the configured durable storage limit.

Source

pub fn put_owned_blob(&self, data: &[u8], pubkey: &[u8; 32]) -> Result<String>

Source

pub fn put_owned_blobs_report( &self, items: &[(Hash, Vec<u8>)], pubkey: &[u8; 32], ) -> Result<PutManyReport>

Store multiple owned Blossom blobs, batching raw blob and owner-index writes.

Source

pub fn put_owned_blobs( &self, items: &[(Hash, Vec<u8>)], pubkey: &[u8; 32], ) -> Result<usize>

Store multiple owned Blossom blobs, returning only the number of new blobs.

Source

pub fn put_cached_blob_with_inserted( &self, data: &[u8], ) -> Result<(String, bool)>

Store an opportunistically cached blob.

Unlike durable put_blob writes, this path may evict disposable orphaned blobs to make room under storage pressure. It intentionally avoids touching indexed trees, social-graph roots, explicit pins, and owned Blossom blobs.

Source

pub fn put_cached_blob(&self, data: &[u8]) -> Result<String>

Source

pub fn put_cached_blobs_report( &self, items: &[(Hash, Vec<u8>)], ) -> Result<PutManyReport>

Store multiple opportunistically cached blobs in one raw storage batch.

Source

pub fn put_cached_blobs(&self, items: &[(Hash, Vec<u8>)]) -> Result<usize>

Store multiple opportunistically cached blobs, returning only the number of new blobs.

Source

pub fn get_blob(&self, hash: &[u8; 32]) -> Result<Option<Vec<u8>>>

Get a raw blob by SHA256 hash (raw bytes).

Source

pub fn get_blob_range( &self, hash: &[u8; 32], start: u64, end_inclusive: u64, ) -> Result<Option<Vec<u8>>>

Source

pub fn blob_size(&self, hash: &[u8; 32]) -> Result<Option<u64>>

Source

pub fn blob_exists(&self, hash: &[u8; 32]) -> Result<bool>

Check if a blob exists by SHA256 hash (raw bytes).

Source

pub fn set_blob_owner(&self, sha256: &[u8; 32], pubkey: &[u8; 32]) -> Result<()>

Add an owner (pubkey) to a blob for Blossom protocol Multiple users can own the same blob - it’s only deleted when all owners remove it

Source

pub fn is_blob_owner( &self, sha256: &[u8; 32], pubkey: &[u8; 32], ) -> Result<bool>

Check if a pubkey owns a blob

Source

pub fn get_blob_owners(&self, sha256: &[u8; 32]) -> Result<Vec<[u8; 32]>>

Get all owners (pubkeys) of a blob via prefix scan (returns raw bytes)

Source

pub fn blob_has_owners(&self, sha256: &[u8; 32]) -> Result<bool>

Check if blob has any owners

Source

pub fn get_blob_owner(&self, sha256: &[u8; 32]) -> Result<Option<[u8; 32]>>

Get the first owner (pubkey) of a blob (for backwards compatibility)

Source

pub fn delete_blossom_blob( &self, sha256: &[u8; 32], pubkey: &[u8; 32], ) -> Result<bool>

Remove a user’s ownership of a blossom blob Only deletes the actual blob when no owners remain Returns true if the blob was actually deleted (no owners left)

Source

pub fn list_blobs_by_pubkey( &self, pubkey: &[u8; 32], ) -> Result<Vec<BlobDescriptor>>

List all blobs owned by a pubkey (for Blossom /list endpoint)

Source

pub fn get_chunk(&self, hash: &[u8; 32]) -> Result<Option<Vec<u8>>>

Get a single chunk/blob by hash (raw bytes)

Source

pub fn get_file(&self, hash: &[u8; 32]) -> Result<Option<Vec<u8>>>

Get file content by hash (raw bytes) Returns raw bytes (caller handles decryption if needed)

Source

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

Get file content by Cid (hash + optional decryption key as raw bytes) Handles decryption automatically if key is present

Source

pub fn write_file_by_cid_to_writer<W: Write>( &self, cid: &Cid, writer: &mut W, ) -> Result<u64>

Stream file content identified by Cid into a writer without buffering full file in memory.

Source

pub fn write_file_by_cid<P: AsRef<Path>>( &self, cid: &Cid, output_path: P, ) -> Result<u64>

Stream file content identified by Cid directly into a destination path.

Source

pub fn write_file<P: AsRef<Path>>( &self, hash: &[u8; 32], output_path: P, ) -> Result<u64>

Stream a public (unencrypted) file by hash directly into a destination path.

Source

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

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

Source

pub fn get_file_chunk_metadata( &self, hash: &[u8; 32], ) -> Result<Option<Arc<FileChunkMetadata>>>

Get chunk metadata for a file (chunk list, sizes, total size)

Source

pub fn get_file_range( &self, hash: &[u8; 32], start: u64, end: Option<u64>, ) -> Result<Option<(Vec<u8>, u64)>>

Get byte range from file

Source

pub fn stream_file_range_chunks_owned( self: Arc<Self>, hash: &[u8; 32], start: u64, end: u64, ) -> Result<Option<FileRangeChunksOwned>>

Stream file range as chunks using Arc for async/Send contexts

Source

pub fn get_directory_listing( &self, hash: &[u8; 32], ) -> Result<Option<DirectoryListing>>

Get directory structure by hash (raw bytes)

Source

pub fn get_directory_listing_by_cid( &self, cid: &Cid, ) -> Result<Option<DirectoryListing>>

Get directory structure by CID, supporting encrypted directories.

Source

pub fn add_pinned_ref(&self, key: &str) -> Result<()>

Persist a mutable published ref that should stay subscribed.

Source

pub fn remove_pinned_ref(&self, key: &str) -> Result<bool>

Remove a mutable published ref from the live pinned set.

Source

pub fn list_pinned_refs(&self) -> Result<Vec<String>>

List mutable published refs that should stay subscribed.

Source

pub fn add_tracked_author(&self, npub: &str) -> Result<bool>

Persist an author whose published trees should stay mirrored.

Source

pub fn remove_tracked_author(&self, npub: &str) -> Result<bool>

Remove an author from the continuous mirror set.

Source

pub fn list_tracked_authors(&self) -> Result<Vec<String>>

List authors whose published trees should stay mirrored.

Source

pub fn get_cached_root( &self, pubkey_hex: &str, tree_name: &str, ) -> Result<Option<CachedRoot>>

Get cached root for a pubkey/tree_name pair

Source

pub fn set_cached_root( &self, pubkey_hex: &str, tree_name: &str, hash: &str, key: Option<&str>, visibility: &str, updated_at: u64, ) -> Result<()>

Set cached root for a pubkey/tree_name pair

Source

pub fn list_cached_roots( &self, pubkey_hex: &str, ) -> Result<Vec<(String, CachedRoot)>>

List all cached roots for a pubkey

Source

pub fn delete_cached_root( &self, pubkey_hex: &str, tree_name: &str, ) -> Result<bool>

Delete a cached root

Trait Implementations§

Source§

impl ContentStore for HashtreeStore

Source§

fn get(&self, hash_hex: &str) -> Result<Option<Vec<u8>>>

Get content by hex hash

Auto Trait Implementations§

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

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

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more