content

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 27, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package content reconstructs full artifact content from Fossil's delta-chain storage.

Fossil stores blobs either as full content or as deltas against a source blob. Expand walks the delta chain from a given RID back to the root, decompresses each link, and applies deltas in sequence to produce the original content. Cycle detection prevents infinite loops.

Verify expands a blob and compares its hash (SHA1 or SHA3-256) against the stored UUID. IsPhantom checks whether a blob is a placeholder awaiting delivery during sync.

Index

Constants

View Source
const (
	// ClusterThreshold is the minimum number of unclustered, non-phantom blobs
	// before cluster generation triggers.
	ClusterThreshold = 100

	// ClusterMaxSize is the maximum number of M-cards per cluster artifact.
	ClusterMaxSize = 800
)

Variables

This section is empty.

Functions

func AvailableByUUID

func AvailableByUUID(q db.Querier, uuid string) (libfossil.FslID, bool)

AvailableByUUID resolves uuid to its rid and reports whether that artifact's content is available, per IsAvailable.

Use this in place of blob.Exists wherever the resolved rid is about to be passed to Expand: blob.Exists answers true for a phantom, whose content cannot be read.

func DeltaSource

func DeltaSource(q db.Querier, rid libfossil.FslID) (libfossil.FslID, error)

DeltaSource returns the rid that rid is stored as a delta against, or 0 if rid holds full content. Exported so callers outside this package (the clone send path, notably) can tell whether stored content read via blob.Load is a delta payload or full text without duplicating this query.

func Deltify

func Deltify(tx *db.Tx, rid, srcRid libfossil.FslID) (saved int, err error)

Deltify tries to rewrite the artifact rid, currently stored whole, as a delta against srcRid. It returns the number of stored bytes saved; 0 means the policy above declined and rid was left untouched, which is a normal outcome and not an error.

The rewrite changes only how rid is stored, never what it expands to, so callers need not tell anyone the representation changed.

Deltify takes a *db.Tx rather than a db.Querier because rewriting an artifact is two statements -- the blob content and the delta link -- that must land together. A blob holding delta bytes with no delta row expands as though it were full content, which is silent corruption rather than a detectable error. Canonical wraps the same pair in db_begin_transaction / db_end_transaction (content.c:938-941); requiring the transaction in the signature makes that non-negotiable at compile time.

func Expand

func Expand(q db.Querier, rid libfossil.FslID) (result []byte, err error)

func GenerateClusters

func GenerateClusters(q db.Querier) (int, error)

GenerateClusters creates cluster artifacts for unclustered blobs that are not phantoms, shunned, or private. Returns the number of clusters created.

func IsAvailable

func IsAvailable(q db.Querier, rid libfossil.FslID) bool

IsAvailable reports whether the content of rid can actually be read.

This is the availability predicate, distinct from blob.Exists, which answers only whether a row is present. It returns false for a phantom (blob.size < 0), false for an unknown rid, and — transitively — false for a delta whose chain bottoms out in a phantom, even though every blob row in that chain exists. It returns true only when the full chain is grounded in readable full-text content.

Ported from Fossil's content_is_available (src/content.c:163). Callers must never walk the delta table themselves; that logic lives here alone.

func IsPhantom

func IsPhantom(q db.Querier, rid libfossil.FslID) (bool, error)

func IsPrivate

func IsPrivate(q db.Querier, rid int64) bool

IsPrivate returns true if the blob with the given rid is in the private table.

func MakePrivate

func MakePrivate(q db.Querier, rid int64) error

MakePrivate inserts the rid into the private table (no-op if already present).

func MakePublic

func MakePublic(q db.Querier, rid int64) error

MakePublic removes the rid from the private table (no-op if not present).

func Undelta

func Undelta(tx *db.Tx, rid libfossil.FslID) error

Undelta rewrites rid as full content, dropping its delta link. Mirrors content_undelta (src/content.c:745-769), including its update of blob.size, which content_deltify deliberately does not touch.

func Verify

func Verify(q db.Querier, rid libfossil.FslID) error

Verify confirms that rid's stored content hashes to its declared UUID. Expand performs this same check internally on every expansion now, so Verify is a thin, explicitly-named wrapper for callers (repo rebuild, integration tests) that want to state their intent as verification rather than retrieval.

Types

type AvailabilityCache

type AvailabilityCache struct {
	// contains filtered or unexported fields
}

AvailabilityCache memoizes IsAvailable across many calls that share delta chains, for a caller that knows blob content is immutable for the cache's lifetime -- a single crosslink sweep. IsAvailable walks a blob's whole delta chain on every call, and crosslink calls it once per F-card of every check-in, so the same file blobs -- and the same chain suffixes -- are walked again and again; on the Fossil SCM corpus that walk was ~40% of the sweep.

A blob's availability is a property of its chain, and every node above a given node in the same chain shares that node's grounding or phantom, so one walk decides every node it passes through. The cache records that verdict for each rid, and a later walk that reaches an already-decided rid stops there. Total walk work over a sweep is then bounded by the number of distinct blobs, not by the number of F-card references.

Not safe for concurrent use, and valid only while the delta table and blob sizes it walked stay put: create one per sweep, discard it at the end.

func NewAvailabilityCache

func NewAvailabilityCache() *AvailabilityCache

NewAvailabilityCache returns an empty availability cache.

func (*AvailabilityCache) ByUUID

func (a *AvailabilityCache) ByUUID(q db.Querier, uuid string) (libfossil.FslID, bool)

ByUUID resolves uuid to its rid and reports whether that blob's content is available, memoizing the chain walk. Semantics match AvailableByUUID.

type Cache

type Cache struct {
	// contains filtered or unexported fields
}

Cache is a concurrency-safe LRU cache for expanded blob content. It reduces redundant delta-chain walks by caching the fully-expanded result of Expand, keyed by rid.

A nil *Cache is valid and acts as a passthrough to Expand.

func NewCache

func NewCache(maxBytes int64) *Cache

NewCache creates a cache bounded by maxBytes of expanded content.

func (*Cache) Clear

func (c *Cache) Clear()

Clear removes all entries from the cache.

func (*Cache) Expand

func (c *Cache) Expand(q db.Querier, rid libfossil.FslID) ([]byte, error)

Expand returns the expanded content for rid, serving from cache when possible.

On a miss it walks rid's delta chain only as far back as the deepest ancestor the cache already holds, and caches every node it materializes on the way forward. That is what makes a sweep over a whole repository — every blob of a chain expanded once, in some order — cost one delta application per blob rather than one per (blob, chain-depth) pair.

A nil receiver falls through to Expand directly.

func (*Cache) Invalidate

func (c *Cache) Invalidate(rid libfossil.FslID)

Invalidate removes a single rid from the cache.

func (*Cache) Stats

func (c *Cache) Stats() CacheStats

Stats returns a snapshot of cache statistics.

type CacheStats

type CacheStats struct {
	Hits    int64
	Misses  int64
	Size    int64
	MaxSize int64
	Entries int
}

CacheStats reports cache hit/miss statistics and current memory usage.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL