Help us shape the future of Go! Take the 2026 Go Developer Survey

kv

package
v0.27.1 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2026 License: BSD-3-Clause Imports: 18 Imported by: 0

Documentation

Overview

Package kv provides a key-value store interface with hierarchical path-based keys. Keys are represented as string slices (e.g., ["user", "profile", "123"]) and encoded internally using a configurable separator (default ':').

Backends implement exact-key records and explicitly addressed collections. Database-wide key enumeration is not part of the store contract.

Index

Constants

View Source
const DefaultSeparator byte = ':'

DefaultSeparator is the default separator byte used to encode key segments.

Variables

View Source
var (
	// ErrNotFound is returned when a key does not exist in the store.
	ErrNotFound = errors.New("kv: not found")
	// ErrInvalidDeadline is returned when an entry deadline is already expired.
	ErrInvalidDeadline = errors.New("kv: invalid deadline")
	// ErrCreateIfAbsentUnsupported is returned when a Store does not implement
	// the optional atomic conditional-create capability.
	ErrCreateIfAbsentUnsupported = errors.New("kv: atomic create-if-absent unsupported")
	// ErrCompareAndMutateUnsupported is returned when a Store does not implement
	// the optional atomic compare-and-mutate capability.
	ErrCompareAndMutateUnsupported = errors.New("kv: atomic compare-and-mutate unsupported")
	// ErrStoreClosed is returned when a Store is used after Close. Using a
	// closed store is a programming error at the call site, so callers should
	// treat it as a shutdown signal and stop, not retry.
	ErrStoreClosed = errors.New("kv: store closed")
)

Sentinel errors.

View Source
var ErrWrongType = errors.New("kv: wrong value type")

ErrWrongType reports an operation on a key holding another data type.

View Source
var OpenBadger = NewBadger

OpenBadger is an alias for NewBadger kept for discoverability. Deprecated: use NewBadger.

Functions

func CompareAndMutate

func CompareAndMutate(
	ctx context.Context,
	store Store,
	guard Key,
	expected []byte,
	entries []Entry,
	keys []Key,
) (matched bool, err error)

CompareAndMutate atomically applies entries and deletes when guard still has the exact expected value. A missing or changed guard returns matched=false without changing any key.

func CreateIfAbsent

func CreateIfAbsent(ctx context.Context, store Store, guard Entry, entries []Entry) (existing []byte, created bool, err error)

CreateIfAbsent atomically stores guard and entries through the Store's optional conditional-create capability. When guard.Key already exists, it returns its stored value and leaves every key unchanged. The boolean reports whether this call created the guard and entries. If entries contains guard.Key, guard wins.

func SharedAtomicStore

func SharedAtomicStore(stores ...Store) (Store, []Key, bool)

SharedAtomicStore resolves stores to their common transaction boundary and returns the prefix of each logical view relative to that boundary.

The boolean is false when a store is nil, when the stores use different transaction boundaries, or when their concrete roots cannot be compared safely. Callers can then reject configurations that cannot provide one atomic BatchMutate across all of the logical views.

func SupportsCompareAndMutate

func SupportsCompareAndMutate(store Store) bool

SupportsCompareAndMutate reports whether store provides the atomic compare-and-mutate capability. Prefixed stores inherit support from their underlying store.

func SupportsCreateIfAbsent

func SupportsCreateIfAbsent(store Store) bool

SupportsCreateIfAbsent reports whether store provides the atomic conditional-create capability. Prefixed stores inherit support from their underlying store.

func SupportsCreateIfAllAbsent

func SupportsCreateIfAllAbsent(store Store) bool

SupportsCreateIfAllAbsent reports whether store can atomically require several uniqueness keys to be absent before creating one record set.

Types

type Badger

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

Badger is a persistent Store backed by BadgerDB.

BadgerDB panics when a call reaches a closed database handle, so the store counts the operations that currently touch db. Close marks the store closed and waits for that count to drain before it releases the handle: an operation that started first always finishes against a live handle. New operations after Close starts report ErrStoreClosed.

func NewBadger

func NewBadger(dir string, opts *Options) (*Badger, error)

NewBadger opens (or creates) a BadgerDB store at dir. Pass nil opts for defaults.

func NewBadgerInMemory

func NewBadgerInMemory(opts *Options) (*Badger, error)

NewBadgerInMemory creates an in-memory BadgerDB store (no disk persistence). Useful for integration tests that need a real Badger instance without temp dirs.

func NewBadgerWithDB added in v0.2.0

func NewBadgerWithDB(db *badger.DB, opts *Options) (*Badger, error)

NewBadgerWithDB creates a Store that borrows an already-open Badger DB. Closing the returned Store does not close db.

func NewBadgerWithOptions

func NewBadgerWithOptions(dbOpts badger.Options, opts *Options) (*Badger, error)

NewBadgerWithOptions opens a BadgerDB store with custom badger.Options. This is useful for advanced tuning (e.g. in-memory mode, compression settings).

func (*Badger) AddMembers added in v0.16.0

func (b *Badger) AddMembers(ctx context.Context, key Key, members ...string) error

AddMembers adds members idempotently to one collection.

func (*Badger) ApplyMutation added in v0.16.0

func (b *Badger) ApplyMutation(ctx context.Context, mutation Mutation) (bool, error)

ApplyMutation updates record and collection keys in one optimistic transaction.

func (*Badger) BatchDelete

func (b *Badger) BatchDelete(ctx context.Context, keys []Key) error

func (*Badger) BatchMutate

func (b *Badger) BatchMutate(ctx context.Context, entries []Entry, keys []Key) error

func (*Badger) BatchSet

func (b *Badger) BatchSet(ctx context.Context, entries []Entry) error

func (*Badger) Close

func (b *Badger) Close() error

Close marks the store closed and closes the underlying database when the store owns it. It waits for in-flight operations, is idempotent, and reports the underlying close error only on the first call. Every later use of the store answers ErrStoreClosed instead of reaching the closed handle.

func (*Badger) CompareAndMutate

func (b *Badger) CompareAndMutate(
	ctx context.Context,
	guard Key,
	expected []byte,
	entries []Entry,
	keys []Key,
) (bool, error)

func (*Badger) CreateIfAbsent

func (b *Badger) CreateIfAbsent(ctx context.Context, guard Entry, entries []Entry) ([]byte, bool, error)

func (*Badger) CreateIfAllAbsent

func (b *Badger) CreateIfAllAbsent(ctx context.Context, guards []Entry, entries []Entry) (Key, []byte, bool, error)

func (*Badger) Delete

func (b *Badger) Delete(ctx context.Context, key Key) error

func (*Badger) Get

func (b *Badger) Get(ctx context.Context, key Key) ([]byte, error)

func (*Badger) HasMember added in v0.16.0

func (b *Badger) HasMember(ctx context.Context, key Key, member string) (bool, error)

HasMember performs an exact member-key lookup.

func (*Badger) ListMembers added in v0.16.0

func (b *Badger) ListMembers(ctx context.Context, key Key) ([]string, error)

ListMembers enumerates only the member-key range of one exact collection.

func (*Badger) RangeOrderedMembers added in v0.16.0

func (b *Badger) RangeOrderedMembers(ctx context.Context, key Key, query OrderedRange) ([]string, error)

RangeOrderedMembers seeks directly into the exact collection's member keys.

func (*Badger) RemoveMembers added in v0.16.0

func (b *Badger) RemoveMembers(ctx context.Context, key Key, members ...string) error

RemoveMembers removes members idempotently from one collection.

func (*Badger) RunGC

func (b *Badger) RunGC(discardRatio float64) error

RunGC triggers BadgerDB's value log garbage collection. discardRatio is the minimum fraction of entries that must be discarded for a rewrite to happen (typically 0.5). Returns nil if GC ran, badger.ErrNoRewrite if nothing to collect, and ErrStoreClosed once the store is closed.

func (*Badger) Set

func (b *Badger) Set(ctx context.Context, key Key, value []byte) error

func (*Badger) Size

func (b *Badger) Size() (lsm, vlog int64, err error)

Size returns the on-disk size in bytes as reported by BadgerDB. It reports ErrStoreClosed once the store is closed, with both sizes zero.

type Condition added in v0.16.0

type Condition struct {
	Key      Key
	Expected []byte
}

Condition compares a record before applying a mutation. A nil Expected requires absence; a non-nil Expected requires an exact byte match.

type Entry

type Entry struct {
	Key   Key
	Value []byte
	// Deadline sets an absolute expiration time for writes. A zero Deadline means the entry does not expire.
	Deadline time.Time
}

Entry is a key-value pair used by batch and conditional writes.

type Key

type Key []string

Key is a hierarchical path represented as a slice of string segments. For example, Key{"user", "g", "e", "Alice"} encodes to "user:g:e:Alice" using the default separator ':'.

Segments must not contain the configured separator character.

func CreateIfAllAbsent

func CreateIfAllAbsent(ctx context.Context, store Store, guards []Entry, entries []Entry) (conflict Key, existing []byte, created bool, err error)

CreateIfAllAbsent atomically checks every guard key and stores all guards and entries only when none of the guards exists. On conflict it returns the first existing guard key and value in input order without changing any key. At least one guard is required; guards win when an entry repeats a guard key.

func (Key) String

func (k Key) String() string

String returns the key as a human-readable string using ':' as separator. This is for display/debug only; use Options.encode for storage encoding.

type Memory

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

Memory is an in-memory Store implementation backed by a sorted map. It is safe for concurrent use and intended primarily for testing.

func NewMemory

func NewMemory(opts *Options) *Memory

NewMemory creates a new in-memory Store. Pass nil for default options.

func (*Memory) AddMembers added in v0.16.0

func (m *Memory) AddMembers(ctx context.Context, key Key, members ...string) error

AddMembers adds members idempotently to one collection.

func (*Memory) ApplyMutation added in v0.16.0

func (m *Memory) ApplyMutation(ctx context.Context, mutation Mutation) (bool, error)

ApplyMutation atomically updates records and collection indexes after all conditions, deadlines and collection types have been checked.

func (*Memory) BatchDelete

func (m *Memory) BatchDelete(ctx context.Context, keys []Key) error

func (*Memory) BatchMutate

func (m *Memory) BatchMutate(ctx context.Context, entries []Entry, keys []Key) error

func (*Memory) BatchSet

func (m *Memory) BatchSet(ctx context.Context, entries []Entry) error

func (*Memory) Close

func (m *Memory) Close() error

func (*Memory) CompareAndMutate

func (m *Memory) CompareAndMutate(
	ctx context.Context,
	guard Key,
	expected []byte,
	entries []Entry,
	keys []Key,
) (bool, error)

func (*Memory) CreateIfAbsent

func (m *Memory) CreateIfAbsent(ctx context.Context, guard Entry, entries []Entry) ([]byte, bool, error)

func (*Memory) CreateIfAllAbsent

func (m *Memory) CreateIfAllAbsent(ctx context.Context, guards []Entry, entries []Entry) (Key, []byte, bool, error)

func (*Memory) Delete

func (m *Memory) Delete(ctx context.Context, key Key) error

func (*Memory) Get

func (m *Memory) Get(ctx context.Context, key Key) ([]byte, error)

func (*Memory) HasMember added in v0.16.0

func (m *Memory) HasMember(ctx context.Context, key Key, member string) (bool, error)

HasMember tests membership without enumerating the collection.

func (*Memory) ListMembers added in v0.16.0

func (m *Memory) ListMembers(ctx context.Context, key Key) ([]string, error)

ListMembers reads one exact collection. Missing collections return no members.

func (*Memory) RangeOrderedMembers added in v0.16.0

func (m *Memory) RangeOrderedMembers(ctx context.Context, key Key, query OrderedRange) ([]string, error)

RangeOrderedMembers selects a bounded range from one exact ordered collection.

func (*Memory) RemoveMembers added in v0.16.0

func (m *Memory) RemoveMembers(ctx context.Context, key Key, members ...string) error

RemoveMembers removes members idempotently from one collection.

func (*Memory) Set

func (m *Memory) Set(ctx context.Context, key Key, value []byte) error

type Mutation added in v0.16.0

type Mutation struct {
	Conditions           []Condition
	Entries              []Entry
	DeleteKeys           []Key
	AddMembers           []SetMembers
	RemoveMembers        []SetMembers
	AddOrderedMembers    []SetMembers
	RemoveOrderedMembers []SetMembers
}

Mutation atomically updates records and collection indexes. Conditions are checked against the initial state. Records are written, keys deleted, members added, then members removed. Record and collection keys must be distinct. Collections do not expire; removing their last member removes the key.

type Options

type Options struct {
	// Separator is the byte used to join key segments when encoding to storage.
	// Default is ':' if zero.
	Separator byte
}

Options configures store behavior.

type OrderedRange added in v0.16.0

type OrderedRange struct {
	After  *string
	Before *string
	Limit  int
}

OrderedRange selects members strictly after After and strictly before Before, in bytewise ascending order. Nil bounds are unbounded. Limit must be positive. Ordered collections are distinct from ordinary Set and value keys, never expire, and are mutated through AddOrderedMembers and RemoveOrderedMembers.

type Redis added in v0.8.3

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

Redis is a Store backed by a single Redis server. The physical storage registry owns the client; Close therefore does not close it.

func NewRedisWithClient added in v0.8.3

func NewRedisWithClient(client *redis.Client, opts *Options) (*Redis, error)

NewRedisWithClient creates a Store that borrows an already-open Redis client. Pass nil opts for the default key separator.

func (*Redis) AddMembers added in v0.16.0

func (r *Redis) AddMembers(ctx context.Context, key Key, members ...string) error

AddMembers adds members idempotently to one collection.

func (*Redis) ApplyMutation added in v0.16.0

func (r *Redis) ApplyMutation(ctx context.Context, mutation Mutation) (bool, error)

ApplyMutation updates records and their collection indexes in one Redis script. False means a condition failed and no key was changed.

func (*Redis) BatchDelete added in v0.8.3

func (r *Redis) BatchDelete(ctx context.Context, keys []Key) error

func (*Redis) BatchMutate added in v0.8.3

func (r *Redis) BatchMutate(ctx context.Context, entries []Entry, keys []Key) error

func (*Redis) BatchSet added in v0.8.3

func (r *Redis) BatchSet(ctx context.Context, entries []Entry) error

func (*Redis) Close added in v0.8.3

func (r *Redis) Close() error

func (*Redis) CompareAndMutate added in v0.8.3

func (r *Redis) CompareAndMutate(
	ctx context.Context,
	guard Key,
	expected []byte,
	entries []Entry,
	keys []Key,
) (bool, error)

func (*Redis) CreateIfAbsent added in v0.8.3

func (r *Redis) CreateIfAbsent(ctx context.Context, guard Entry, entries []Entry) ([]byte, bool, error)

func (*Redis) CreateIfAllAbsent added in v0.8.3

func (r *Redis) CreateIfAllAbsent(ctx context.Context, guards []Entry, entries []Entry) (Key, []byte, bool, error)

func (*Redis) Delete added in v0.8.3

func (r *Redis) Delete(ctx context.Context, key Key) error

func (*Redis) Get added in v0.8.3

func (r *Redis) Get(ctx context.Context, key Key) ([]byte, error)

func (*Redis) HasMember added in v0.16.0

func (r *Redis) HasMember(ctx context.Context, key Key, member string) (bool, error)

HasMember tests membership without enumerating the collection.

func (*Redis) ListMembers added in v0.16.0

func (r *Redis) ListMembers(ctx context.Context, key Key) ([]string, error)

ListMembers reads one exact collection. Missing collections return no members.

func (*Redis) RangeOrderedMembers added in v0.16.0

func (r *Redis) RangeOrderedMembers(ctx context.Context, key Key, query OrderedRange) ([]string, error)

RangeOrderedMembers uses Redis's lexicographic Sorted Set index. All members have score zero; range bounds and the limit are evaluated by Redis.

func (*Redis) RemoveMembers added in v0.16.0

func (r *Redis) RemoveMembers(ctx context.Context, key Key, members ...string) error

RemoveMembers removes members idempotently from one collection.

func (*Redis) Set added in v0.8.3

func (r *Redis) Set(ctx context.Context, key Key, value []byte) error

type SQL added in v0.2.0

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

SQL implements one prefix-scoped Store over a SQLite or PostgreSQL table. The connection pool is borrowed and remains owned by the caller.

func NewSQLWithDB added in v0.2.0

func NewSQLWithDB(db *sqlx.DB, prefix string, options *Options) (*SQL, error)

NewSQLWithDB builds a prefix-scoped Store over a borrowed SQL pool. Prefix is used as the quoted backend table name and is not added to encoded keys.

func (*SQL) AddMembers added in v0.16.0

func (s *SQL) AddMembers(ctx context.Context, key Key, members ...string) error

AddMembers adds members idempotently to one collection.

func (*SQL) ApplyMutation added in v0.16.0

func (s *SQL) ApplyMutation(ctx context.Context, mutation Mutation) (applied bool, err error)

ApplyMutation locks the affected keys and atomically updates records and collection/member rows. Conditions are checked before any mutation is applied.

func (*SQL) BatchDelete added in v0.2.0

func (store *SQL) BatchDelete(ctx context.Context, keys []Key) error

BatchDelete atomically removes all keys.

func (*SQL) BatchMutate added in v0.2.0

func (store *SQL) BatchMutate(ctx context.Context, entries []Entry, keys []Key) error

BatchMutate applies sets followed by deletes in one transaction.

func (*SQL) BatchSet added in v0.2.0

func (store *SQL) BatchSet(ctx context.Context, entries []Entry) error

BatchSet atomically stores all entries.

func (*SQL) Close added in v0.2.0

func (store *SQL) Close() error

Close marks the logical adapter closed without closing its pool.

func (*SQL) CompareAndMutate added in v0.2.0

func (store *SQL) CompareAndMutate(ctx context.Context, guard Key, expected []byte, entries []Entry, keys []Key) (bool, error)

CompareAndMutate applies mutations only when the guard value matches.

func (*SQL) CreateIfAbsent added in v0.2.0

func (store *SQL) CreateIfAbsent(ctx context.Context, guard Entry, entries []Entry) ([]byte, bool, error)

CreateIfAbsent conditionally creates one guard and related entries.

func (*SQL) CreateIfAllAbsent added in v0.2.0

func (store *SQL) CreateIfAllAbsent(ctx context.Context, guards []Entry, entries []Entry) (Key, []byte, bool, error)

CreateIfAllAbsent atomically claims every guard in input order.

func (*SQL) Delete added in v0.2.0

func (store *SQL) Delete(ctx context.Context, key Key) error

Delete removes a key when present.

func (*SQL) Get added in v0.2.0

func (store *SQL) Get(ctx context.Context, key Key) ([]byte, error)

Get returns a cloned value and treats expired rows as absent.

func (*SQL) HasMember added in v0.16.0

func (s *SQL) HasMember(ctx context.Context, key Key, member string) (found bool, err error)

HasMember queries the collection/member composite primary key.

func (*SQL) ListMembers added in v0.16.0

func (s *SQL) ListMembers(ctx context.Context, key Key) (members []string, err error)

ListMembers returns members for an exact collection key using its index.

func (*SQL) RangeOrderedMembers added in v0.16.0

func (s *SQL) RangeOrderedMembers(ctx context.Context, key Key, query OrderedRange) (members []string, err error)

RangeOrderedMembers pushes range predicates and LIMIT into the member index.

func (*SQL) RemoveMembers added in v0.16.0

func (s *SQL) RemoveMembers(ctx context.Context, key Key, members ...string) error

RemoveMembers removes members idempotently from one collection.

func (*SQL) Set added in v0.2.0

func (store *SQL) Set(ctx context.Context, key Key, value []byte) error

Set stores a non-expiring value.

type SetMembers added in v0.16.0

type SetMembers struct {
	Key     Key
	Members []string
}

SetMembers addresses members of one exact collection. Members are opaque strings, not hierarchical keys. Collection enumeration has no ordering guarantee.

type Store

type Store interface {
	// Collection methods address one exact key. Members are opaque strings;
	// ListMembers has no ordering guarantee and returns empty for missing keys.
	AddMembers(ctx context.Context, key Key, members ...string) error
	RemoveMembers(ctx context.Context, key Key, members ...string) error
	HasMember(ctx context.Context, key Key, member string) (bool, error)
	ListMembers(ctx context.Context, key Key) ([]string, error)

	// RangeOrderedMembers reads a bounded, lexicographically ordered range from
	// one exact ordered collection. It never enumerates database keys.
	RangeOrderedMembers(ctx context.Context, key Key, query OrderedRange) ([]string, error)

	// ApplyMutation atomically updates records and collection indexes. False
	// means a condition failed and no writes were committed.
	ApplyMutation(ctx context.Context, mutation Mutation) (bool, error)

	// Get retrieves the value for a key. Returns ErrNotFound if not present.
	Get(ctx context.Context, key Key) ([]byte, error)

	// Set stores a key-value pair. Overwrites any existing value.
	Set(ctx context.Context, key Key, value []byte) error

	// Delete removes a key. No error if the key does not exist.
	Delete(ctx context.Context, key Key) error

	// BatchSet atomically stores multiple key-value pairs.
	BatchSet(ctx context.Context, entries []Entry) error

	// BatchDelete atomically removes multiple keys.
	BatchDelete(ctx context.Context, keys []Key) error

	// BatchMutate atomically stores entries and removes keys in one transaction.
	// If a key appears in both collections, the delete is applied last.
	BatchMutate(ctx context.Context, entries []Entry, keys []Key) error

	// Close releases any resources held by the store.
	Close() error
}

Store is the interface for a key-value store with path-based keys.

func Prefixed

func Prefixed(base Store, prefix Key) Store

Prefixed returns a Store view that scopes all keys under prefix.

The returned store does not own the underlying store. Close is intentionally a no-op so multiple prefixed views can share the same base store lifecycle.

Jump to

Keyboard shortcuts

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