Documentation
¶
Overview ¶
Package refstore persists reference records in a SQLite database: name bytes → CBOR record bytes, stored verbatim. It is a dumb KV layer; record validation belongs to the daemon and the reference package.
The database is <dir>/refs.sqlite in WAL mode, so any number of processes may hold a store open at once: readers work from a snapshot and never block, and writers — in this process or another — queue behind one another (SQLite runs one write transaction at a time; a second writer waits up to busyTimeout). The file format is shared with other implementations; see architecture/references.md. Queries are generated by sqlc from queries.sql, and the schema is built by the numbered files in migrations/.
Index ¶
- Variables
- type Publication
- type Record
- type Store
- func (s *Store) All() ([]Record, error)
- func (s *Store) Close() error
- func (s *Store) CompareAndDelete(name string, old key.Key) error
- func (s *Store) CompareAndSwap(name string, old key.Key, record []byte) error
- func (s *Store) Create(name string, record []byte) error
- func (s *Store) Delete(name string) error
- func (s *Store) DeleteVolatile(name string) error
- func (s *Store) Get(name string) ([]byte, error)
- func (s *Store) Put(name string, record []byte) error
- func (s *Store) PutBatch(records []Record) (err error)
- func (s *Store) PutVolatile(name string, record []byte) error
- func (s *Store) UpdateBatch(records []Publication, names []Withdrawal) (removed int, err error)
- func (s *Store) Wipe() error
- type Withdrawal
Constants ¶
This section is empty.
Variables ¶
var ErrConflict = errors.New("refstore: reference is not at the expected key")
ErrConflict is returned by the optimistic writes when the reference is not in the state the caller expected: for Create it exists, for the compare forms it points at another key, for UpdateBatch some name is not where the caller saw it. Nothing was changed; the caller re-reads and decides.
var ErrNotFound = errors.New("refstore: reference not found")
ErrNotFound is returned by Get, Delete and the compare forms for an absent name.
Functions ¶
This section is empty.
Types ¶
type Publication ¶ added in v0.0.12
Publication is one record an UpdateBatch stores, with the key the caller saw its name at: Old is the key the record replaces, or nil if there must be no such reference.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a SQLite-backed name→record map. It is safe for concurrent use, by goroutines and by processes. Readers (Get, All) never block; writes are serialized in-process by writeMu, so they queue on the mutex rather than polling SQLite's file lock, and across processes by SQLite itself.
func Open ¶
Open opens (creating if missing) the refs database in dir. sync selects the write durability, matching the daemon's --sync flag. A Pebble store left in dir by an earlier release is imported first; see migrate.go.
func (*Store) CompareAndDelete ¶ added in v0.0.10
CompareAndDelete removes name only if it currently points at old, with CompareAndSwap's errors.
func (*Store) CompareAndSwap ¶ added in v0.0.10
CompareAndSwap stores record under name only if the reference currently points at old — the move from one key to the next that must not overwrite somebody else's move. It returns ErrNotFound if the reference does not exist and ErrConflict if it points elsewhere. The expectation is the key, not the record bytes: a rewrite that kept the key does not invalidate it. record is stored verbatim, as by Put.
func (*Store) Create ¶ added in v0.0.10
Create stores record under name only if no such reference exists, and returns ErrConflict if one does.
func (*Store) Delete ¶
Delete removes name, or returns ErrNotFound if absent. The check is the statement's own row count, so concurrent Deletes of the same name — from any process — report ErrNotFound to all but one caller.
func (*Store) DeleteVolatile ¶ added in v0.0.12
DeleteVolatile is Delete without the commit fsync, for a record written by PutVolatile, and on the same terms: a delete that is lost with the machine brings the record back, for its owner to discard. Like Delete it returns ErrNotFound if name is absent.
func (*Store) PutBatch ¶ added in v0.0.5
PutBatch publishes records atomically, using the configured write durability. When names repeat, the last record wins. An empty batch changes nothing.
func (*Store) PutVolatile ¶ added in v0.0.12
PutVolatile is Put without the commit fsync, for a record that need not survive a power loss because its owner discards it when it starts, such as a session's pin; with sync on, Put pays one fsync for each.
The caller gives up durability and nothing else. The record is visible at once and survives a crash of the process, but a power loss or a crash of the operating system can take the most recent volatile writes with it. The database stays consistent either way, and no durable write is affected. On a store opened without sync no commit is fsynced, and PutVolatile is Put.
func (*Store) UpdateBatch ¶ added in v0.0.12
func (s *Store) UpdateBatch(records []Publication, names []Withdrawal) (removed int, err error)
UpdateBatch withdraws names and publishes records in one commit, each only if its reference is where the caller saw it, so a caller replacing one set of references with another is never seen half way and never undoes another process's move. A record's expectation is the key it replaces, or nil for no reference; a withdrawn name may also be gone already, as the caller asked for that state. Every expectation is checked before anything changes, and if one fails nothing does and the result is ErrConflict — never ErrNotFound, even for a record whose name should exist and does not. Withdrawals run first, so a name in both ends up published. It returns how many rows the withdrawals removed. An empty batch changes nothing.
type Withdrawal ¶ added in v0.0.12
Withdrawal is one name an UpdateBatch removes, with the key the caller saw it at.