Documentation
¶
Overview ¶
Package cache implements BoltCache's in-memory keyspace: typed values (strings, lists, sets, hashes), expiration, memory/key limits with eviction, multi-key atomic transactions and snapshot persistence.
Concurrency model: the keyspace is split into shards, each guarded by its own RWMutex. Every operation on a key runs entirely under that key's shard lock, so single-key commands are atomic. Multi-key atomicity (MULTI/EXEC and Lua scripts) is provided by Atomic, which locks all involved shards in a fixed order before running.
Index ¶
- Constants
- Variables
- func UnixNano(t time.Time) int64
- type BoltCache
- func (c *BoltCache) Atomic(keys []string, all bool, fn func(tx *Tx) error) (err error)
- func (c *BoltCache) Close()
- func (c *BoltCache) DeleteExpired() int
- func (c *BoltCache) KeyVersion(key string) uint64
- func (c *BoltCache) Len() int64
- func (c *BoltCache) Load(r io.Reader) (int, error)
- func (c *BoltCache) LoadFile(path string) (int, error)
- func (c *BoltCache) OOM() bool
- func (c *BoltCache) Options() Options
- func (c *BoltCache) SaveFile(path string, compress bool) (int, error)
- func (c *BoltCache) Snapshot(w io.Writer) (int, error)
- func (c *BoltCache) Stats() Stats
- func (c *BoltCache) UsedMemory() int64
- func (c *BoltCache) Writes() uint64
- type ExpireCond
- type Kind
- type Options
- type PersistOptions
- type Persister
- type Policy
- type SetOptions
- type SetResult
- type Stats
- type Tx
- func (t *Tx) Append(key, val string) (int, error)
- func (t *Tx) DBSize() (int64, error)
- func (t *Tx) Del(keys ...string) (int, error)
- func (t *Tx) Delete(key string) (bool, error)
- func (t *Tx) Exists(keys ...string) (int, error)
- func (t *Tx) Expire(key string, d time.Duration, cond ExpireCond) (bool, error)
- func (t *Tx) ExpireAt(key string, at time.Time, cond ExpireCond) (bool, error)
- func (t *Tx) ExpireTime(key string) (at time.Time, state int, err error)
- func (t *Tx) FlushAll() error
- func (t *Tx) Get(key string) (string, bool, error)
- func (t *Tx) GetDel(key string) (string, bool, error)
- func (t *Tx) GetEx(key string, exp int64, persist bool) (string, bool, error)
- func (t *Tx) GetRange(key string, start, end int) (string, error)
- func (t *Tx) HDel(key string, fields ...string) (int, error)
- func (t *Tx) HExists(key, field string) (bool, error)
- func (t *Tx) HGet(key, field string) (string, bool, error)
- func (t *Tx) HGetAll(key string) ([]string, error)
- func (t *Tx) HIncrBy(key, field string, delta int64) (int64, error)
- func (t *Tx) HIncrByFloat(key, field string, delta float64) (float64, error)
- func (t *Tx) HKeys(key string) ([]string, error)
- func (t *Tx) HLen(key string) (int, error)
- func (t *Tx) HMGet(key string, fields ...string) ([]string, []bool, error)
- func (t *Tx) HSet(key string, pairs ...string) (int, error)
- func (t *Tx) HSetNX(key, field, val string) (bool, error)
- func (t *Tx) HStrLen(key, field string) (int, error)
- func (t *Tx) HVals(key string) ([]string, error)
- func (t *Tx) InAtomic() bool
- func (t *Tx) IncrBy(key string, delta int64) (int64, error)
- func (t *Tx) IncrByFloat(key string, delta float64) (float64, error)
- func (t *Tx) Keys(pattern string) ([]string, error)
- func (t *Tx) LIndex(key string, index int) (string, bool, error)
- func (t *Tx) LLen(key string) (int, error)
- func (t *Tx) LPop(key string, count int) ([]string, error)
- func (t *Tx) LPush(key string, vals ...string) (int, error)
- func (t *Tx) LPushX(key string, vals ...string) (int, error)
- func (t *Tx) LRange(key string, start, stop int) ([]string, error)
- func (t *Tx) LRem(key string, count int, val string) (int, error)
- func (t *Tx) LSet(key string, index int, val string) error
- func (t *Tx) LTrim(key string, start, stop int) error
- func (t *Tx) MGet(keys ...string) ([]string, []bool, error)
- func (t *Tx) MemoryUsage(key string) (int64, error)
- func (t *Tx) Persist(key string) (bool, error)
- func (t *Tx) RPop(key string, count int) ([]string, error)
- func (t *Tx) RPush(key string, vals ...string) (int, error)
- func (t *Tx) RPushX(key string, vals ...string) (int, error)
- func (t *Tx) RandomKey() (string, bool, error)
- func (t *Tx) Rename(src, dst string, nx bool) (bool, error)
- func (t *Tx) SAdd(key string, members ...string) (int, error)
- func (t *Tx) SCard(key string) (int, error)
- func (t *Tx) SDiff(keys ...string) ([]string, error)
- func (t *Tx) SInter(keys ...string) ([]string, error)
- func (t *Tx) SIsMember(key, member string) (bool, error)
- func (t *Tx) SMIsMember(key string, members ...string) ([]bool, error)
- func (t *Tx) SMembers(key string) ([]string, error)
- func (t *Tx) SPop(key string, count int) ([]string, error)
- func (t *Tx) SRem(key string, members ...string) (int, error)
- func (t *Tx) SUnion(keys ...string) ([]string, error)
- func (t *Tx) Scan(cursor uint64, pattern string, count int, kind Kind) (next uint64, keys []string, err error)
- func (t *Tx) Set(key, val string, ttl time.Duration) error
- func (t *Tx) SetWithOptions(key, val string, opts SetOptions, wantOld bool) (SetResult, error)
- func (t *Tx) StrLen(key string) (int, error)
- func (t *Tx) TTL(key string) (d time.Duration, state int, err error)
- func (t *Tx) Type(key string) (Kind, error)
Constants ¶
const ( TTLNoKey = -2 // key does not exist TTLNoExpire = -1 // key exists without a timeout )
TTL states returned alongside a zero duration.
Variables ¶
var ( ErrWrongType = errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") ErrNotInteger = errors.New("ERR value is not an integer or out of range") ErrNotFloat = errors.New("ERR value is not a valid float") ErrOverflow = errors.New("ERR increment or decrement would overflow") ErrNoSuchKey = errors.New("ERR no such key") ErrIndexRange = errors.New("ERR index out of range") ErrOOM = errors.New("OOM command not allowed when used memory > 'maxmemory'") ErrUndeclaredKey = errors.New("ERR script tried accessing a key that was not declared in KEYS") ErrNotInAtomicCtx = errors.New("ERR this command is not allowed inside scripts") )
Errors returned by cache operations. Their text follows Redis conventions so they can be sent to RESP clients verbatim.
Functions ¶
Types ¶
type BoltCache ¶
type BoltCache struct {
*Tx
// contains filtered or unexported fields
}
BoltCache is the keyspace. Its data methods (Get, Set, LPush, ...) are promoted from an embedded non-transactional Tx.
func (*BoltCache) Atomic ¶
Atomic runs fn with exclusive access to the shards owning keys (or to every shard when all is true). Operations on other keys inside fn fail with ErrUndeclaredKey. Shards are locked in ascending order, so concurrent Atomic calls cannot deadlock.
func (*BoltCache) Close ¶
func (c *BoltCache) Close()
Close stops background goroutines. The data remains readable.
func (*BoltCache) DeleteExpired ¶
DeleteExpired removes all expired keys and returns how many were removed.
func (*BoltCache) KeyVersion ¶
KeyVersion returns a counter that changes whenever key (or another key in the same shard) is modified. Used to implement WATCH.
func (*BoltCache) Load ¶
Load reads a snapshot (version 2 or legacy, gzipped or not) from r and merges it into the cache. It returns the number of keys loaded.
func (*BoltCache) OOM ¶
OOM reports whether writes that grow memory must be refused: the noeviction policy is active and a limit is exceeded.
func (*BoltCache) SaveFile ¶
SaveFile atomically writes a snapshot to path: data goes to a temporary file in the same directory which is fsynced and renamed over path, so a crash never leaves a truncated snapshot behind.
func (*BoltCache) Snapshot ¶
Snapshot writes every live key to w in snapshot format. Each shard is copied under its read lock and encoded afterwards, so writers are blocked only briefly.
func (*BoltCache) UsedMemory ¶
UsedMemory returns the approximate number of bytes held by the keyspace.
type ExpireCond ¶
type ExpireCond uint8
ExpireCond restricts when an expiration is applied (EXPIRE NX|XX|GT|LT).
const ( ExpireAlways ExpireCond = iota ExpireNX // only if the key has no expiry ExpireXX // only if the key has an expiry ExpireGT // only if the new expiry is greater ExpireLT // only if the new expiry is less )
type Options ¶
type Options struct {
// MaxKeys limits the number of keys; 0 means unlimited.
MaxKeys int64
// MaxMemory limits the approximate memory used by keys and values, in
// bytes; 0 means unlimited.
MaxMemory int64
// EvictionThreshold is the fraction (0,1] of MaxMemory at which eviction
// starts. Defaults to 1.
EvictionThreshold float64
// EvictionPolicy decides what happens when a limit is exceeded.
EvictionPolicy Policy
// CleanupInterval is how often expired keys are actively reclaimed.
// Expired keys are never returned regardless. 0 disables the loop.
CleanupInterval time.Duration
}
Options configures a cache.
type PersistOptions ¶
type PersistOptions struct {
File string
Interval time.Duration
Compress bool
// BackupCount is how many previous snapshots to keep next to File
// (File.backup.<timestamp>). 0 disables backups.
BackupCount int
// CleanupWhenExceeds delays pruning until more than this many backups
// exist, batching deletions. Values <= BackupCount prune on every save.
CleanupWhenExceeds int
// Logf receives informational messages; may be nil.
Logf func(format string, args ...any)
}
PersistOptions configures periodic snapshots.
type Persister ¶
type Persister struct {
// contains filtered or unexported fields
}
Persister periodically writes snapshots of a cache to disk.
func NewPersister ¶
func NewPersister(c *BoltCache, opts PersistOptions) *Persister
NewPersister creates a persister; call Start to begin periodic saves.
type Policy ¶
type Policy string
Policy selects which keys are evicted when a limit is exceeded.
func ParsePolicy ¶
ParsePolicy validates an eviction policy name.
type SetOptions ¶
type SetOptions struct {
TTL time.Duration // relative expiration; 0 = none
ExpireAt time.Time // absolute expiration; takes precedence over TTL
KeepTTL bool // retain the existing expiration
NX bool // only set if the key does not exist
XX bool // only set if the key exists
}
SetOptions mirrors the options of the Redis SET command.
type SetResult ¶
type SetResult struct {
Written bool // false when NX/XX prevented the write
Old string // previous string value
HadOld bool // a previous string value existed
}
SetResult reports the outcome of SetWithOptions.
type Stats ¶
type Stats struct {
Keys int64
KeysWithTTL int64
UsedMemory int64
Hits uint64
Misses uint64
Expired uint64
Evicted uint64
Writes uint64
}
Stats is a point-in-time view of cache counters.
type Tx ¶
type Tx struct {
// contains filtered or unexported fields
}
Tx is a handle for running operations. The cache's own embedded Tx locks shards per operation; a Tx passed to an Atomic callback already holds the locks for its declared keys.
func (*Tx) Exists ¶
Exists returns how many of keys exist (duplicates are counted twice, like Redis).
func (*Tx) ExpireAt ¶
ExpireAt sets key's absolute expiration time. A time in the past deletes the key. It reports whether the timeout was set.
func (*Tx) ExpireTime ¶
ExpireTime returns key's absolute expiration (zero time when none) with the same state convention as TTL.
func (*Tx) GetEx ¶
GetEx returns the string at key and optionally changes its expiration: exp > 0 sets an absolute unix-nano expiry, persist removes it.
func (*Tx) GetRange ¶
GetRange returns the substring of the string at key between start and end (inclusive, negative offsets count from the end).
func (*Tx) HIncrByFloat ¶
HIncrByFloat adds delta to the float in field.
func (*Tx) HSet ¶
HSet sets field/value pairs (pairs must have even length) and returns how many fields were newly created.
func (*Tx) IncrBy ¶
IncrBy adds delta to the integer stored at key (0 when absent) and returns the new value. The key's TTL is preserved.
func (*Tx) IncrByFloat ¶
IncrByFloat adds delta to the float stored at key.
func (*Tx) LPush ¶
LPush prepends values (each one becoming the new head, like Redis) and returns the list length.
func (*Tx) LRange ¶
LRange returns elements between start and stop (inclusive, negative indexes count from the tail).
func (*Tx) LRem ¶
LRem removes occurrences of val: count > 0 from head, count < 0 from tail, 0 all of them. Returns the number removed.
func (*Tx) MemoryUsage ¶
MemoryUsage returns the approximate bytes used by key (0 when absent).
func (*Tx) Rename ¶
Rename moves the value at src to dst, overwriting dst. With nx it fails (returning false) when dst exists. Both keys must be accessible in the current context; outside Atomic the two shards are locked in order so the move is atomic.
func (*Tx) SMIsMember ¶
SMIsMember reports membership for each member.
func (*Tx) Scan ¶
func (t *Tx) Scan(cursor uint64, pattern string, count int, kind Kind) (next uint64, keys []string, err error)
Scan iterates the keyspace incrementally. The cursor is a shard index: a full iteration (starting and ending at cursor 0) returns every key that existed for the whole iteration at least once, matching SCAN's guarantee. kind filters by type when not KindNone.
func (*Tx) Set ¶
Set stores a string value, replacing any existing value and type. A ttl of 0 means no expiration.
func (*Tx) SetWithOptions ¶
SetWithOptions implements SET with NX/XX/KEEPTTL/EX/PX. When wantOld is true the previous value is returned (SET ... GET), which fails with ErrWrongType if the old value isn't a string.