Documentation
¶
Index ¶
- Constants
- Variables
- func ApplySummaryPagination(summaries []*core.SnapshotSummary, opts *ListOptions) []*core.SnapshotSummary
- func CloneChunk(c *core.Chunk) *core.Chunk
- func CloneFileEntry(f core.FileEntry) core.FileEntry
- func CloneSnapshot(s *core.Snapshot) *core.Snapshot
- func HashPath(hexHash string) string
- func NormalizeConfig(cfg *core.Config)
- type ChunkCompactor
- type ChunkStorer
- type CompactReport
- type ConfigStorer
- type IndexStorer
- type ListOptions
- type PreviewStorer
- type ReferenceStorer
- type SnapshotStorer
- type Storer
Constants ¶
const ( ChunkHeaderSize = 1 ChunkFlagCompressed byte = 0x01 // ChunkFlagEncrypted is reserved for future end-to-end encryption of // remote-synced chunks. Not yet implemented. ChunkFlagEncrypted byte = 0x02 )
Chunk wire format constants shared between filesystem backend and remote sync. The on-disk chunk file and the remote chunk object use the same format: a 1-byte header followed by (optionally compressed) chunk data. Bit 0 of the header indicates zstd compression.
Keeping these constants in the storage interface package (rather than duplicated in filesystem and remote) eliminates the dedup violation and ensures both sides agree on the wire format.
const ( DriftDir = ".drift" ChunksDir = "chunks" SnapshotsDir = "snapshots" ManifestsDir = "manifests" RefsDir = "refs" PreviewsDir = "previews" HeadsDir = "heads" TagsDir = "tags" LogsDir = "logs" HeadFile = "HEAD" IndexFile = "index" ConfigFile = "config" PacksDir = "packs" )
Layout constants shared between filesystem backend and remote sync.
Both the on-disk .drift/ layout and the remote wire layout use these directory names. Keeping them in the storage interface package (rather than in backends/filesystem) lets the remote package depend on storage only, without reaching into a concrete backend. See AGENTS.md "Package boundaries".
const MaxSymRefDepth = 8
Variables ¶
var ( // ErrNotFound is returned when a requested object does not exist. ErrNotFound = errors.New("drift: not found") // ErrAlreadyExists is returned when creating an object that already exists. ErrAlreadyExists = errors.New("drift: already exists") // ErrPermission is returned when an operation is denied by permissions. ErrPermission = errors.New("drift: permission denied") // ErrInvalidRef is returned when a reference name or value is malformed. ErrInvalidRef = errors.New("drift: invalid reference") // ErrCorrupted is returned when on-disk data fails an integrity check. ErrCorrupted = errors.New("drift: data corrupted") // ErrUnsupported is returned when a backend does not implement an operation. ErrUnsupported = errors.New("drift: unsupported operation") )
Sentinel errors for the storage layer. Callers use errors.Is to test for specific failure modes; lower layers wrap these with fmt.Errorf("%w", ...) to attach context while preserving the sentinel identity.
These mirror the error hierarchy described in architecture.md §6.5.
Functions ¶
func ApplySummaryPagination ¶
func ApplySummaryPagination(summaries []*core.SnapshotSummary, opts *ListOptions) []*core.SnapshotSummary
ApplySummaryPagination applies ListOptions offset/limit pagination to a slice of snapshot summaries that has already been sorted by the caller. It is shared by the filesystem and memory backends so the pagination semantics (opts==nil → no pagination; Offset beyond len → nil; Limit truncation) stay identical across backends.
func HashPath ¶
HashPath returns the two-level content-addressed path for a hex hash: the first 2 characters as the parent directory, the rest as the filename. This layout is shared by chunks, snapshots, and manifests both on disk and on the remote. Returns the input unchanged if shorter than 2 chars.
func NormalizeConfig ¶
NormalizeConfig applies shared invariants to a loaded config so both backends observe identical field semantics. It runs three phases:
- ApplyEnvOverrides — DRIFT_* environment variables replace the file values (runtime overrides for CI/containers).
- Normalize — empty/zero/out-of-range fields are clamped to defaults, including any values supplied via env overrides in the previous step.
- Validate — semantic sanity check; on failure a warning is logged (slog.Warn) and the clamped value is kept. Failing the whole operation for a suspicious-but-clamped value would be more disruptive than the misconfiguration itself.
Both the filesystem and memory backends call this from GetConfig so the logic lives in one place rather than being duplicated per backend.
Types ¶
type ChunkCompactor ¶
type ChunkCompactor interface {
CompactChunks(ctx context.Context, reachable map[core.Hash]bool, dryRun bool) (CompactReport, error)
}
ChunkCompactor is an optional interface implemented by storage backends that support compacting loose chunks into packed storage. GC calls it after the reachability pass to pack loose chunks and rewrite packs with high dead-block ratios. Backends that do not support packing (e.g. in-memory storage) simply do not implement this interface; GC falls back to per-chunk DeleteChunk in that case.
type ChunkStorer ¶
type ChunkStorer interface {
HasChunk(ctx context.Context, hash core.Hash) (bool, error)
GetChunk(ctx context.Context, hash core.Hash) (*core.Chunk, error)
PutChunk(ctx context.Context, chunk *core.Chunk) error
DeleteChunk(ctx context.Context, hash core.Hash) error
ListChunks(ctx context.Context) ([]core.Hash, error)
}
ChunkStorer provides access to chunk storage.
type CompactReport ¶
type CompactReport struct {
LooseDeleted int
LoosePacked int
PackDeadRemoved int
PacksRewritten int
PacksCreated int
FreedBytes int64
}
CompactReport describes the outcome of a chunk compaction pass.
type ConfigStorer ¶
type ConfigStorer interface {
GetConfig(ctx context.Context) (*core.Config, error)
SetConfig(ctx context.Context, config *core.Config) error
// SetCompressionConfig applies the compression settings to the backend.
// enabled toggles zstd compression of chunk payloads; level is the zstd
// encoder level (1-19, clamped by the implementation). Backends that do
// not compress (e.g. the in-memory test backend) implement this as a
// no-op so porcelain can apply config uniformly across backends without
// type-asserting to a concrete implementation.
SetCompressionConfig(enabled bool, level int) error
}
ConfigStorer provides access to configuration storage.
type IndexStorer ¶
type IndexStorer interface {
GetIndex(ctx context.Context) (*core.Index, error)
SetIndex(ctx context.Context, index *core.Index) error
}
IndexStorer provides access to the staging index.
type ListOptions ¶
ListOptions controls snapshot listing pagination.
type PreviewStorer ¶
type PreviewStorer interface {
GetPreview(ctx context.Context, hash core.Hash, size int) ([]byte, error)
PutPreview(ctx context.Context, hash core.Hash, size int, data []byte) error
}
PreviewStorer provides access to preview (thumbnail) data.
type ReferenceStorer ¶
type ReferenceStorer interface {
GetRef(ctx context.Context, name string) (*core.Reference, error)
SetRef(ctx context.Context, name string, ref *core.Reference) error
ListRefs(ctx context.Context, prefix string) ([]*core.Reference, error)
DeleteRef(ctx context.Context, name string) error
}
ReferenceStorer provides access to reference storage.
type SnapshotStorer ¶
type SnapshotStorer interface {
GetSnapshot(ctx context.Context, id core.SnapshotID) (*core.Snapshot, error)
PutSnapshot(ctx context.Context, snapshot *core.Snapshot) error
DeleteSnapshot(ctx context.Context, id core.SnapshotID) error
ListSnapshots(ctx context.Context, opts *ListOptions) ([]*core.SnapshotSummary, error)
}
SnapshotStorer provides access to snapshot storage.
type Storer ¶
type Storer interface {
ChunkStorer
SnapshotStorer
ReferenceStorer
IndexStorer
PreviewStorer
ConfigStorer
io.Closer
}
Storer is the composite interface for all storage backends.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
backends
|
|
|
Package refname validates reference names (branch, tag, HEAD) for both storage backends.
|
Package refname validates reference names (branch, tag, HEAD) for both storage backends. |