redis/redis
kvstore
The slot-aware hash table that holds keys for a database. One dict per slot in cluster mode; one dict total in standalone mode.
Source layout
| File | Role |
|---|---|
src/kvstore.c |
Implementation (~42 KB). |
src/kvstore.h |
Public API. |
Why a layer above dict?
In standalone mode, all keys live in one big dict. In cluster mode, each node owns ~5,500 slots out of 16,384, and routing operations need to identify which slot a key belongs to without iterating the whole dict.
kvstore solves this by maintaining one dict per slot. The slot count is fixed (16,384) but a kvstore can be configured to allocate dicts lazily so empty slots cost nothing. The keyspace, the expiration store, and a few other per-DB structures all use kvstore.
API
typedef struct kvstore kvstore;
kvstore *kvstoreCreate(dictType *type, int num_dicts_bits, int flags);
void kvstoreRelease(kvstore *kvs);
unsigned long kvstoreSize(kvstore *kvs); /* total entries across slots */
unsigned long kvstoreDictSize(kvstore *kvs, int didx); /* slot-specific */
dict *kvstoreGetDict(kvstore *kvs, int didx);
int kvstoreFindDictIndexByKeyIndex(kvstore *kvs, unsigned long target);
int kvstoreDictAdd(kvstore *kvs, int didx, void *key, void *value);
int kvstoreDictReplace(kvstore *kvs, int didx, void *key, void *value);
void *kvstoreDictFetchValue(kvstore *kvs, int didx, const void *key);
int kvstoreDictDelete(kvstore *kvs, int didx, const void *key);
unsigned long kvstoreScan(kvstore *kvs, unsigned long cursor,
int onlydidx, dictScanFunction *fn, ...);The didx argument is the dict index (slot in cluster mode). For standalone mode, callers pass 0.
Lazy allocation
KVSTORE_ALLOCATE_DICTS_ON_DEMAND (a flag passed to kvstoreCreate) tells kvstore to leave dict pointers as NULL until a key is inserted into the slot. Empty slots cost just one pointer each instead of the full dict header.
For the per-DB keyspace this is the default — a freshly initialised cluster has one tiny dict per active slot and 14k empty slots costing ~112 KB total.
Iteration semantics
The kvstoreScan API is the cluster-aware version of dictScan. The cursor encodes both the dict index and the within-dict cursor. Callers can ask to scan only one slot (onlydidx >= 0) or all of them (onlydidx == -1). This is what SCAN, KEYS, and DBSIZE use under the hood.
For background tasks that walk all keys (active expiration, eviction, defrag), kvstore exposes kvstoreSmallestNonEmptyDictIndex, kvstoreNextNonEmptyDictIndex, etc. so the cron can spread the work across slots fairly.
Stats
kvstoreGetStats returns aggregate statistics across all slots, useful for INFO keyspace and INFO memory.
Where to start modifying
- Add a flag — extend the bitset at the top of
src/kvstore.h. - Add a per-slot stat — register a counter on the dict's
dictTypeand aggregate inkvstoreGetStats. - Use kvstore from a new module — module-defined types can use kvstore directly; the API is exported.
Related pages
- Dict — the underlying primitive.
- Cluster — slot-based routing.
- Memory management — eviction iterates kvstore slots.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.