pub struct FsStore { /* private fields */ }Expand description
Filesystem-based storage for Heddle objects.
Layout:
.heddle/
objects/
blobs/
ab/
cdef1234...
trees/
ab/
cdef1234...
states/
<change_id>.state
actions/
<action_id>.action
packs/
<hash>.pack
<hash>.idxImplementations§
Source§impl FsStore
impl FsStore
Sourcepub fn new(root: impl AsRef<Path>) -> Self
pub fn new(root: impl AsRef<Path>) -> Self
Create a new filesystem store rooted at the given path.
The path should be the .heddle directory.
Sourcepub fn with_compression(
root: impl AsRef<Path>,
compression: CompressionConfig,
) -> Self
pub fn with_compression( root: impl AsRef<Path>, compression: CompressionConfig, ) -> Self
Create a new filesystem store with custom compression settings.
Sourcepub fn compression(&self) -> CompressionConfig
pub fn compression(&self) -> CompressionConfig
Get the compression configuration.
Sourcepub fn set_compression(&mut self, compression: CompressionConfig)
pub fn set_compression(&mut self, compression: CompressionConfig)
Set the compression configuration.
pub fn loose_object_write_mode(&self) -> LooseObjectWriteMode
pub fn set_loose_object_write_mode(&mut self, mode: LooseObjectWriteMode)
Sourcepub fn reload_packs(&self) -> Result<()>
pub fn reload_packs(&self) -> Result<()>
Reload pack files from disk.
Sourcepub fn pack_manager(&self) -> &RwLock<PackManager>
pub fn pack_manager(&self) -> &RwLock<PackManager>
Get the pack manager for pack operations.
pub fn clear_recent_object_caches(&self)
pub fn pack_ids(&self) -> Result<Vec<PackObjectId>>
Trait Implementations§
Source§impl ObjectStore for FsStore
impl ObjectStore for FsStore
Source§fn loose_blob_path(&self, hash: &ContentHash) -> Option<PathBuf>
fn loose_blob_path(&self, hash: &ContentHash) -> Option<PathBuf>
Loose blob path safe for hardlink/clonefile materialization.
Returns Some(path) only when the loose file exists and is
stored uncompressed — then the on-disk bytes are byte-identical
to the blob’s content, so a hard link materializes the worktree
file without an extra copy. Compressed blobs and pack-only blobs
fall through to None and the caller writes decompressed bytes
the slow way.
Source§fn promote_to_loose_uncompressed(&self, hash: &ContentHash) -> Result<bool>
fn promote_to_loose_uncompressed(&self, hash: &ContentHash) -> Result<bool>
Promote a blob to its uncompressed-loose canonical path so
loose_blob_path returns Some(path) and hardlink-first
materialization fires.
Three cases:
- Already loose+uncompressed: peek the header, no-op.
- Loose but compressed: read+decompress, atomically rewrite the canonical path with raw bytes.
- Pack-only: read out of the pack via
get_blob, atomically write to the canonical loose path. Pack copy is left in place — the next prune cycle will discard the loose mirror and a future materialize will re-promote.
fn get_blob(&self, hash: &ContentHash) -> Result<Option<Blob>>
fn put_blob(&self, blob: &Blob) -> Result<ContentHash>
fn put_blob_with_hash( &self, blob: &Blob, hash: ContentHash, ) -> Result<ContentHash>
fn put_blob_bytes_with_hash( &self, data: &[u8], hash: ContentHash, ) -> Result<ContentHash>
fn has_blob(&self, hash: &ContentHash) -> Result<bool>
Source§fn blob_size(&self, hash: &ContentHash) -> Result<Option<u64>>
fn blob_size(&self, hash: &ContentHash) -> Result<Option<u64>>
hash, or Ok(None) when the blob is not in the store. Read morefn get_tree(&self, hash: &ContentHash) -> Result<Option<Tree>>
fn put_tree(&self, tree: &Tree) -> Result<ContentHash>
fn put_tree_serialized( &self, data: &[u8], hash: ContentHash, ) -> Result<ContentHash>
fn has_tree(&self, hash: &ContentHash) -> Result<bool>
fn get_state(&self, id: &ChangeId) -> Result<Option<State>>
fn put_state(&self, state: &State) -> Result<()>
fn put_state_serialized(&self, data: &[u8], id: ChangeId) -> Result<()>
fn has_state(&self, id: &ChangeId) -> Result<bool>
fn list_states(&self) -> Result<Vec<ChangeId>>
fn get_action(&self, id: &ActionId) -> Result<Option<Action>>
fn put_action(&self, action: &mut Action) -> Result<ActionId>
fn list_actions(&self) -> Result<Vec<ActionId>>
fn list_blobs(&self) -> Result<Vec<ContentHash>>
fn list_trees(&self) -> Result<Vec<ContentHash>>
fn pack_objects(&self, aggressive: bool) -> Result<(u64, u64)>
fn get_pack_object( &self, id: &PackObjectId, ) -> Result<Option<(ObjectType, Vec<u8>)>>
fn install_pack( &self, pack_data: &[u8], index_data: &[u8], ) -> Result<Vec<PackObjectId>>
Source§fn put_blobs_packed(&self, blobs: Vec<(ContentHash, Vec<u8>)>) -> Result<()>
fn put_blobs_packed(&self, blobs: Vec<(ContentHash, Vec<u8>)>) -> Result<()>
FsStore) override this to install one
packfile + index — two fsyncs total instead of N. Used by the
snapshot hot path so writing 1000 small files takes ~one fsync,
not 1000. Read moreSource§fn install_pack_streaming(
&self,
pack_path: &Path,
index_path: &Path,
) -> Result<()>
fn install_pack_streaming( &self, pack_path: &Path, index_path: &Path, ) -> Result<()>
StreamingPackBuilder). The default
impl reads both files fully and delegates to install_pack,
so any backend that doesn’t override this still works (at the
cost of giving back the bounded-memory promise). Real fs-
backed stores override this to rename(2) both files into the
pack directory without ever loading them. Read more