store

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package store is cloudrig's metadata layer: a versioned compare-and-swap key/value map. Payload bytes never pass through it, only blob hashes.

Index

Constants

View Source
const FlushInterval = time.Second

FlushInterval is how long a write waits before the snapshot is rewritten.

Writes are debounced rather than flushed each time: a burst of a thousand objects should cost one rewrite, not a thousand.

Variables

View Source
var (
	// ErrNotFound is returned by Get and Delete for an absent key.
	ErrNotFound = errors.New("store: key not found")

	// ErrVersionMismatch means a compare-and-swap lost. GCS preconditions are
	// built on it, so it must be reported, never retried away.
	ErrVersionMismatch = errors.New("store: version mismatch")

	// ErrInvalidPageToken is returned by List for a token it did not issue.
	ErrInvalidPageToken = errors.New("store: invalid page token")
)

Sentinel errors. Callers map these onto status codes; the store has no HTTP.

Functions

func PageToken

func PageToken(key string) string

PageToken builds a token that resumes a List after key. Callers that stop part-way through a page need to name where they stopped, and the token format belongs to the store rather than to them.

Types

type Entry

type Entry struct {
	Key     string `json:"key"`
	Val     []byte `json:"val"`
	Version uint64 `json:"version"`
}

Entry is one key's stored state, for a snapshot. Version travels with it: restoring without it would reset every compare-and-swap baseline, so a precondition that held before a restart would fail after one.

type KV

type KV struct {
	Key     string
	Val     []byte
	Version uint64
}

KV is one entry. List returns keys with values because GCS delimiter rollup synthesizes prefixes[] from key structure.

type Memory

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

Memory is an in-process Store. Every mutation holds the write lock across both the compare and the swap, which is what makes the CAS atomic.

func NewMemory

func NewMemory() *Memory

NewMemory returns an empty in-memory Store.

func (*Memory) Delete

func (s *Memory) Delete(ctx context.Context, key string, ifVersion uint64) error

func (*Memory) Get

func (s *Memory) Get(ctx context.Context, key string) ([]byte, uint64, error)

func (*Memory) List

func (s *Memory) List(ctx context.Context, prefix string, limit int, pageToken string) ([]KV, string, error)

func (*Memory) Put

func (s *Memory) Put(ctx context.Context, key string, val []byte, ifVersion uint64) (uint64, error)

func (*Memory) Reset

func (s *Memory) Reset(ctx context.Context, keyPrefix string) error

func (*Memory) Restore

func (s *Memory) Restore(entries []Entry)

Restore replaces the contents with entries.

func (*Memory) Snapshot

func (s *Memory) Snapshot() []Entry

Snapshot returns every entry, in key order.

type Persistent

type Persistent struct {
	*Memory
	// contains filtered or unexported fields
}

Persistent is a Memory that survives a restart.

Reads and writes stay in memory — durability here is a convenience for a developer restarting a daemon, not a database — and the whole map is snapshotted to one file, written to a temp path and renamed so a crash mid-write leaves the previous snapshot intact.

func OpenPersistent

func OpenPersistent(path string, clk clock.Clock) (*Persistent, error)

OpenPersistent loads a snapshot from path, or starts empty if there is none.

func (*Persistent) Close

func (p *Persistent) Close() error

Close cancels any pending flush and writes a final snapshot.

func (*Persistent) Delete

func (p *Persistent) Delete(ctx context.Context, key string, ifVersion uint64) error

func (*Persistent) Flush

func (p *Persistent) Flush() error

Flush writes the snapshot now.

func (*Persistent) Put

func (p *Persistent) Put(ctx context.Context, key string, val []byte, ifVersion uint64) (uint64, error)

func (*Persistent) Reset

func (p *Persistent) Reset(ctx context.Context, keyPrefix string) error

type Store

type Store interface {
	// Get returns the value and its current version, or ErrNotFound.
	Get(ctx context.Context, key string) (val []byte, version uint64, err error)

	// Put writes val and returns the new version. ifVersion of 0 requires the
	// key be absent; anything else requires it be the current version.
	// There is no unconditional Put: the compare and swap must be one step.
	Put(ctx context.Context, key string, val []byte, ifVersion uint64) (uint64, error)

	// Delete removes a key. ifVersion of 0 deletes unconditionally; anything
	// else requires it be the current version. An absent key is ErrNotFound.
	Delete(ctx context.Context, key string, ifVersion uint64) error

	// List returns entries under prefix in key order, starting after pageToken.
	// limit is a scan budget, not a page size: delimiter rollup may consume far
	// more entries than it emits, so API pagination is built above this.
	List(ctx context.Context, prefix string, limit int, pageToken string) ([]KV, string, error)

	// Reset removes every key under keyPrefix; an empty prefix removes all.
	Reset(ctx context.Context, keyPrefix string) error
}

Store is a versioned key/value map with compare-and-swap writes. Versions start at 1, leaving 0 free to mean something else in the preconditions.

Directories

Path Synopsis
Package blob stores object payloads as content-addressed files.
Package blob stores object payloads as content-addressed files.

Jump to

Keyboard shortcuts

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