Documentation
¶
Overview ¶
Package slabbis implements an in-process cache with an optional RESP-compatible server layer.
Design:
Values are stored in a slabber Arena, giving fixed-slot memory management with a lock-free read path. Variable-length values are accommodated via Arena size classes; values larger than the largest class are stored directly on the heap (escape hatch, not the common path).
Keys are managed in a sharded hash map — one shard per logical CPU — to distribute mutex contention. Each shard maps string keys to Entry values holding the slabber ArenaRef, the stored length, and the expiry.
TTL eviction runs in a background goroutine per shard, scanning for expired entries on a configurable interval.
The Cache interface is the public contract. The concrete *cache type satisfies it. A Server wraps a Cache and speaks RESP over a net.Listener.
Concurrency properties:
- Get: one shard RLock + one slabber Slot() call (lock-free after shard)
- Set: one shard Lock + one Arena Alloc + possible Arena Free of old value
- Del: one shard Lock + one Arena Free
- The slabber read path (Slot) holds no lock.
Index ¶
Constants ¶
const Version = "0.1.2"
Version is the current slabbis release.
Variables ¶
var DefaultClasses = []slabber.SizeClass{
{MaxSize: 64},
{MaxSize: 512},
{MaxSize: 4096},
{MaxSize: 32768},
{MaxSize: 262144},
}
DefaultClasses provides five size classes covering typical cache values: 64B, 512B, 4KB, 32KB, 256KB.
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache interface {
// Get returns the value for key and whether it was found.
// The returned slice is a direct view into slabber memory.
// Do not retain it across a subsequent Set or Del on the same key.
Get(key string) ([]byte, bool)
// GetCopy returns a heap-allocated copy of the value for key.
// The copy is made while holding the shard read lock, so it is safe
// to retain indefinitely. Use this wherever the caller cannot guarantee
// the slice will not outlive a concurrent Set or Del on the same key
// (e.g. in the server layer before writing to a network buffer).
GetCopy(key string) ([]byte, bool)
// GetInto copies the value for key into dst, growing dst if necessary,
// and returns the populated slice and whether the key was found.
// The copy is made while holding the shard read lock.
//
// Unlike GetCopy, GetInto does not allocate when cap(dst) >= len(value).
// Callers that pool or reuse dst (e.g. one buffer per server connection)
// achieve zero per-call allocations in steady state.
//
// The returned slice aliases dst. Callers must not retain it across a
// subsequent call that reuses the same dst.
GetInto(key string, dst []byte) ([]byte, bool)
// Set stores value under key with the given TTL.
// A zero TTL means the entry does not expire.
Set(key string, value []byte, ttl time.Duration)
// Del removes key. Returns true if the key existed.
Del(key string) bool
// Exists reports whether key is present and not expired.
Exists(key string) bool
// TTL returns the remaining lifetime of key.
// Returns 0, false if the key does not exist.
// Returns 0, true if the key exists but has no expiry.
// Returns remaining, true if the key exists with an expiry.
TTL(key string) (time.Duration, bool)
// Flush removes all entries from the cache.
Flush()
// Stats returns a point-in-time snapshot of cache state.
Stats() CacheStats
// Keys returns all live keys matching pattern.
// Pattern uses filepath.Match syntax: * matches any sequence, ? matches
// any single character. Use "*" to return all keys.
Keys(pattern string) []string
// MGet returns values for the given keys in order.
// Missing or expired keys produce a nil entry.
// The returned slices are direct views into slabber memory.
// Do not retain any entry across a subsequent Set or Del on any key
// in the batch — the underlying slot may be reused after a free.
MGet(keys ...string) [][]byte
// MSet sets multiple key/value pairs atomically within each shard.
// A zero TTL means no expiry. Existing keys are overwritten.
MSet(ttl time.Duration, pairs map[string][]byte)
// SetNX sets key to value only if the key does not already exist.
// Returns true if the key was set.
SetNX(key string, value []byte, ttl time.Duration) bool
// GetDel returns the value for key and removes it atomically.
GetDel(key string) ([]byte, bool)
// Rename renames key from to key to. Returns false if from does not exist.
Rename(from, to string) bool
// DBSize returns the total number of live keys across all shards.
DBSize() int
// Close stops background goroutines. The cache must not be used after Close.
Close()
}
Cache is the public interface for slabbis. All methods are safe for concurrent use.
type CacheStats ¶
type CacheStats struct {
Keys int // number of live (non-expired) keys
SlabStats []slabber.Stats // one entry per Arena size class
}
CacheStats holds a point-in-time snapshot of cache state.
type Config ¶
type Config struct {
// Shards is the number of key-space partitions.
// 0 defaults to runtime.NumCPU().
Shards int
// Classes defines the Arena size classes for value storage.
// 0 defaults to DefaultClasses.
Classes []slabber.SizeClass
// ReaperInterval controls how often the TTL reaper runs per shard.
// 0 defaults to 1 second.
ReaperInterval time.Duration
// BucketsPerShard is passed to each slabber Arena as the initial
// bucket count. 0 defaults to runtime.NumCPU().
BucketsPerShard int
}
Config controls cache construction.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server listens on a network address and dispatches RESP commands to a Cache. It supports exactly the commands slabbis exposes; anything else returns an error response rather than a panic.
Supported commands:
GET key SET key value [EX seconds | PX milliseconds] MGET key [key ...] MSET key value [key value ...] SETNX key value GETDEL key DEL key [key ...] EXISTS key [key ...] KEYS pattern RENAME from to DBSIZE TYPE key TTL key PTTL key FLUSH (non-standard; equivalent to FLUSHALL) PING [message] COMMAND (returns empty array — satisfies redis-cli startup probe) QUIT
func NewServer ¶
NewServer returns a Server bound to addr using the provided Cache. addr may be a TCP address ("127.0.0.1:6399") or a Unix socket path ("unix:///tmp/slabbis.sock" — the "unix://" prefix is stripped).
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
slabbis
command
Command slabbis is a minimal cache server speaking a Redis-compatible protocol subset over TCP or a Unix socket.
|
Command slabbis is a minimal cache server speaking a Redis-compatible protocol subset over TCP or a Unix socket. |
|
internal
|
|
|
resp
Package resp implements a minimal subset of the Redis Serialisation Protocol (RESP2) sufficient for slabbis's supported command set.
|
Package resp implements a minimal subset of the Redis Serialisation Protocol (RESP2) sufficient for slabbis's supported command set. |