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

cache

package
v2.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2026 License: MIT Imports: 22 Imported by: 0

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

View Source
const (
	TTLNoKey    = -2 // key does not exist
	TTLNoExpire = -1 // key exists without a timeout
)

TTL states returned alongside a zero duration.

Variables

View Source
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.

View Source
var (
	ErrZAddIncrPair = errors.New("ERR INCR option supports a single increment-element pair")
	ErrScoreNaN     = errors.New("ERR resulting score is not a number (NaN)")
)

Functions

func UnixNano

func UnixNano(t time.Time) int64

UnixNano is t.UnixNano without overflow for dates past 2262.

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 New

func New(opts Options) *BoltCache

New creates a cache and starts its background expiry loop. Call Close to stop it.

func (*BoltCache) Atomic

func (c *BoltCache) Atomic(keys []string, all bool, fn func(tx *Tx) error) (err error)

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

func (c *BoltCache) DeleteExpired() int

DeleteExpired removes all expired keys and returns how many were removed.

func (*BoltCache) KeyVersion

func (c *BoltCache) KeyVersion(key string) uint64

KeyVersion returns a counter that changes whenever key (or another key in the same shard) is modified. Used to implement WATCH.

func (*BoltCache) Len

func (c *BoltCache) Len() int64

Len returns the number of keys (including expired keys not yet reclaimed).

func (*BoltCache) Load

func (c *BoltCache) Load(r io.Reader) (int, error)

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) LoadFile

func (c *BoltCache) LoadFile(path string) (int, error)

LoadFile loads a snapshot file. A missing file is not an error.

func (*BoltCache) OOM

func (c *BoltCache) OOM() bool

OOM reports whether writes that grow memory must be refused: the noeviction policy is active and a limit is exceeded.

func (*BoltCache) Options

func (c *BoltCache) Options() Options

Options returns the effective options.

func (*BoltCache) SaveFile

func (c *BoltCache) SaveFile(path string, compress bool) (int, error)

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) ShardOf added in v2.1.0

func (c *BoltCache) ShardOf(key string) int

ShardOf returns the index of the shard holding key; keys with the same index share a lock.

func (*BoltCache) Snapshot

func (c *BoltCache) Snapshot(w io.Writer) (int, error)

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) Stats

func (c *BoltCache) Stats() Stats

Stats returns current counters.

func (*BoltCache) UsedMemory

func (c *BoltCache) UsedMemory() int64

UsedMemory returns the approximate number of bytes held by the keyspace.

func (*BoltCache) Writes

func (c *BoltCache) Writes() uint64

Writes returns a counter incremented on every mutation. Persistence uses it to skip snapshots when nothing changed.

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 Kind

type Kind uint8

Kind is the type of value stored at a key.

const (
	KindNone Kind = iota
	KindString
	KindList
	KindSet
	KindHash
	KindZSet
)

func (Kind) String

func (k Kind) String() string

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.

func (*Persister) LastSave

func (p *Persister) LastSave() time.Time

LastSave returns the time of the last successful save (zero if none).

func (*Persister) Load

func (p *Persister) Load() (int, error)

Load restores the snapshot file into the cache.

func (*Persister) Save

func (p *Persister) Save(force bool) (bool, error)

Save writes a snapshot. Unless force is set it is skipped when nothing changed since the previous save. It reports whether a file was written.

func (*Persister) Start

func (p *Persister) Start()

Start begins saving every Interval.

func (*Persister) Stop

func (p *Persister) Stop() error

Stop ends the periodic loop and writes a final snapshot.

type Policy

type Policy string

Policy selects which keys are evicted when a limit is exceeded.

const (
	PolicyLRU        Policy = "lru"        // least recently used
	PolicyLFU        Policy = "lfu"        // least frequently used
	PolicyRandom     Policy = "random"     // any key
	PolicyTTL        Policy = "ttl"        // nearest expiration first, then LRU
	PolicyNoEviction Policy = "noeviction" // reject writes with an OOM error
)

func ParsePolicy

func ParsePolicy(s string) (Policy, error)

ParsePolicy validates an eviction policy name.

type ScoreBound added in v2.1.0

type ScoreBound struct {
	Value     float64
	Exclusive bool
}

ScoreBound is one end of a score range: a value that is inclusive unless Exclusive is set ("(1.5" in Redis syntax).

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) Append

func (t *Tx) Append(key, val string) (int, error)

Append appends val to the string at key and returns the new length.

func (*Tx) DBSize

func (t *Tx) DBSize() (int64, error)

DBSize returns the number of live keys.

func (*Tx) Del

func (t *Tx) Del(keys ...string) (int, error)

Del removes keys and returns how many existed.

func (*Tx) Delete

func (t *Tx) Delete(key string) (bool, error)

Delete removes key and reports whether it existed.

func (*Tx) Exists

func (t *Tx) Exists(keys ...string) (int, error)

Exists returns how many of keys exist (duplicates are counted twice, like Redis).

func (*Tx) Expire

func (t *Tx) Expire(key string, d time.Duration, cond ExpireCond) (bool, error)

Expire sets a relative timeout on key.

func (*Tx) ExpireAt

func (t *Tx) ExpireAt(key string, at time.Time, cond ExpireCond) (bool, error)

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

func (t *Tx) ExpireTime(key string) (at time.Time, state int, err error)

ExpireTime returns key's absolute expiration (zero time when none) with the same state convention as TTL.

func (*Tx) FlushAll

func (t *Tx) FlushAll() error

FlushAll removes every key.

func (*Tx) Get

func (t *Tx) Get(key string) (string, bool, error)

Get returns the string value at key.

func (*Tx) GetDel

func (t *Tx) GetDel(key string) (string, bool, error)

GetDel returns the string at key and deletes it.

func (*Tx) GetEx

func (t *Tx) GetEx(key string, exp int64, persist bool) (string, bool, error)

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

func (t *Tx) GetRange(key string, start, end int) (string, error)

GetRange returns the substring of the string at key between start and end (inclusive, negative offsets count from the end).

func (*Tx) HDel

func (t *Tx) HDel(key string, fields ...string) (int, error)

HDel removes fields and returns how many existed.

func (*Tx) HExists

func (t *Tx) HExists(key, field string) (bool, error)

HExists reports whether field exists.

func (*Tx) HGet

func (t *Tx) HGet(key, field string) (string, bool, error)

HGet returns the value of field.

func (*Tx) HGetAll

func (t *Tx) HGetAll(key string) ([]string, error)

HGetAll returns field/value pairs sorted by field.

func (*Tx) HIncrBy

func (t *Tx) HIncrBy(key, field string, delta int64) (int64, error)

HIncrBy adds delta to the integer in field.

func (*Tx) HIncrByFloat

func (t *Tx) HIncrByFloat(key, field string, delta float64) (float64, error)

HIncrByFloat adds delta to the float in field.

func (*Tx) HKeys

func (t *Tx) HKeys(key string) ([]string, error)

HKeys returns the hash's fields, sorted.

func (*Tx) HLen

func (t *Tx) HLen(key string) (int, error)

HLen returns the number of fields.

func (*Tx) HMGet

func (t *Tx) HMGet(key string, fields ...string) ([]string, []bool, error)

HMGet returns values for fields.

func (*Tx) HSet

func (t *Tx) HSet(key string, pairs ...string) (int, error)

HSet sets field/value pairs (pairs must have even length) and returns how many fields were newly created.

func (*Tx) HSetNX

func (t *Tx) HSetNX(key, field, val string) (bool, error)

HSetNX sets field only if it does not exist.

func (*Tx) HStrLen

func (t *Tx) HStrLen(key, field string) (int, error)

HStrLen returns the length of a field's value.

func (*Tx) HVals

func (t *Tx) HVals(key string) ([]string, error)

HVals returns the hash's values ordered by field.

func (*Tx) InAtomic

func (t *Tx) InAtomic() bool

InAtomic reports whether t is the handle of an Atomic callback.

func (*Tx) IncrBy

func (t *Tx) IncrBy(key string, delta int64) (int64, error)

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

func (t *Tx) IncrByFloat(key string, delta float64) (float64, error)

IncrByFloat adds delta to the float stored at key.

func (*Tx) Keys

func (t *Tx) Keys(pattern string) ([]string, error)

Keys returns all live keys matching pattern, sorted.

func (*Tx) LIndex

func (t *Tx) LIndex(key string, index int) (string, bool, error)

LIndex returns the element at index.

func (*Tx) LLen

func (t *Tx) LLen(key string) (int, error)

LLen returns the length of the list at key.

func (*Tx) LPop

func (t *Tx) LPop(key string, count int) ([]string, error)

LPop removes and returns up to count elements from the head.

func (*Tx) LPush

func (t *Tx) LPush(key string, vals ...string) (int, error)

LPush prepends values (each one becoming the new head, like Redis) and returns the list length.

func (*Tx) LPushX

func (t *Tx) LPushX(key string, vals ...string) (int, error)

LPushX is LPush that only acts on an existing list.

func (*Tx) LRange

func (t *Tx) LRange(key string, start, stop int) ([]string, error)

LRange returns elements between start and stop (inclusive, negative indexes count from the tail).

func (*Tx) LRem

func (t *Tx) LRem(key string, count int, val string) (int, error)

LRem removes occurrences of val: count > 0 from head, count < 0 from tail, 0 all of them. Returns the number removed.

func (*Tx) LSet

func (t *Tx) LSet(key string, index int, val string) error

LSet replaces the element at index.

func (*Tx) LTrim

func (t *Tx) LTrim(key string, start, stop int) error

LTrim keeps only elements between start and stop.

func (*Tx) MGet

func (t *Tx) MGet(keys ...string) ([]string, []bool, error)

MGet returns the values for keys; missing or non-string keys yield ok=false.

func (*Tx) MemoryUsage

func (t *Tx) MemoryUsage(key string) (int64, error)

MemoryUsage returns the approximate bytes used by key (0 when absent).

func (*Tx) Persist

func (t *Tx) Persist(key string) (bool, error)

Persist removes key's timeout and reports whether one was removed.

func (*Tx) RPop

func (t *Tx) RPop(key string, count int) ([]string, error)

RPop removes and returns up to count elements from the tail.

func (*Tx) RPush

func (t *Tx) RPush(key string, vals ...string) (int, error)

RPush appends values and returns the list length.

func (*Tx) RPushX

func (t *Tx) RPushX(key string, vals ...string) (int, error)

RPushX is RPush that only acts on an existing list.

func (*Tx) RandomKey

func (t *Tx) RandomKey() (string, bool, error)

RandomKey returns a random live key, or "" and false when empty.

func (*Tx) Rename

func (t *Tx) Rename(src, dst string, nx bool) (bool, error)

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) SAdd

func (t *Tx) SAdd(key string, members ...string) (int, error)

SAdd adds members and returns how many were newly added.

func (*Tx) SCard

func (t *Tx) SCard(key string) (int, error)

SCard returns the set cardinality.

func (*Tx) SDiff

func (t *Tx) SDiff(keys ...string) ([]string, error)

SDiff returns members of the first set not present in the others, sorted.

func (*Tx) SInter

func (t *Tx) SInter(keys ...string) ([]string, error)

SInter returns the intersection of the given sets, sorted.

func (*Tx) SIsMember

func (t *Tx) SIsMember(key, member string) (bool, error)

SIsMember reports whether member is in the set.

func (*Tx) SMIsMember

func (t *Tx) SMIsMember(key string, members ...string) ([]bool, error)

SMIsMember reports membership for each member.

func (*Tx) SMembers

func (t *Tx) SMembers(key string) ([]string, error)

SMembers returns all members, sorted for deterministic output.

func (*Tx) SPop

func (t *Tx) SPop(key string, count int) ([]string, error)

SPop removes and returns up to count random members.

func (*Tx) SRem

func (t *Tx) SRem(key string, members ...string) (int, error)

SRem removes members and returns how many were removed.

func (*Tx) SUnion

func (t *Tx) SUnion(keys ...string) ([]string, error)

SUnion returns the union of the given sets, sorted.

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

func (t *Tx) Set(key, val string, ttl time.Duration) error

Set stores a string value, replacing any existing value and type. A ttl of 0 means no expiration.

func (*Tx) SetWithOptions

func (t *Tx) SetWithOptions(key, val string, opts SetOptions, wantOld bool) (SetResult, error)

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.

func (*Tx) StrLen

func (t *Tx) StrLen(key string) (int, error)

StrLen returns the length of the string at key.

func (*Tx) TTL

func (t *Tx) TTL(key string) (d time.Duration, state int, err error)

TTL returns the remaining time to live of key. When the key is missing or has no timeout, the duration is 0 and state is TTLNoKey/TTLNoExpire; otherwise state is 0.

func (*Tx) Type

func (t *Tx) Type(key string) (Kind, error)

Type returns the kind of value at key (KindNone when absent).

func (*Tx) ZAdd added in v2.1.0

func (t *Tx) ZAdd(key string, opts ZAddOptions, members []ZMember) (ZAddResult, error)

ZAdd adds or updates members.

func (*Tx) ZCard added in v2.1.0

func (t *Tx) ZCard(key string) (int, error)

ZCard returns the number of members.

func (*Tx) ZCount added in v2.1.0

func (t *Tx) ZCount(key string, min, max ScoreBound) (int, error)

ZCount returns the number of members with a score in [min, max].

func (*Tx) ZMScore added in v2.1.0

func (t *Tx) ZMScore(key string, members ...string) ([]float64, []bool, error)

ZMScore returns the scores of several members.

func (*Tx) ZMembers added in v2.1.0

func (t *Tx) ZMembers(key string) ([]ZMember, error)

ZMembers returns every member in order (used by ZSCAN and snapshots).

func (*Tx) ZPop added in v2.1.0

func (t *Tx) ZPop(key string, count int, max bool) ([]ZMember, error)

ZPop removes and returns up to count members with the lowest (or highest when max) scores.

func (*Tx) ZRangeByRank added in v2.1.0

func (t *Tx) ZRangeByRank(key string, start, stop int, rev bool) ([]ZMember, error)

ZRangeByRank returns members by rank.

func (*Tx) ZRangeByScore added in v2.1.0

func (t *Tx) ZRangeByScore(key string, min, max ScoreBound, rev bool, offset, count int) ([]ZMember, error)

ZRangeByScore returns members by score.

func (*Tx) ZRank added in v2.1.0

func (t *Tx) ZRank(key, member string, rev bool) (rank int, score float64, ok bool, err error)

ZRank returns a member's 0-based rank (from the highest score when rev).

func (*Tx) ZRem added in v2.1.0

func (t *Tx) ZRem(key string, members ...string) (int, error)

ZRem removes members and returns how many existed.

func (*Tx) ZRemRangeByRank added in v2.1.0

func (t *Tx) ZRemRangeByRank(key string, start, stop int) (int, error)

ZRemRangeByRank removes members between ranks start and stop.

func (*Tx) ZRemRangeByScore added in v2.1.0

func (t *Tx) ZRemRangeByScore(key string, min, max ScoreBound) (int, error)

ZRemRangeByScore removes members with a score in [min, max].

func (*Tx) ZScore added in v2.1.0

func (t *Tx) ZScore(key, member string) (float64, bool, error)

ZScore returns a member's score.

type ZAddOptions added in v2.1.0

type ZAddOptions struct {
	NX, XX, GT, LT bool
	Incr           bool
}

ZAddOptions mirrors ZADD's flags.

type ZAddResult added in v2.1.0

type ZAddResult struct {
	Added   int     // new members
	Changed int     // new or updated members (ZADD ... CH)
	Score   float64 // resulting score with Incr
	Applied bool    // with Incr: false when NX/XX/GT/LT prevented the update
}

ZAddResult reports what ZAdd did.

type ZMember added in v2.1.0

type ZMember struct {
	Member string
	Score  float64
}

ZMember is a sorted set element.

Jump to

Keyboard shortcuts

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