Library API
Every exported type, method, and Options field in the github.com/tamnd/kv package, with exact signatures and semantics.
This is the complete public surface of the kv package.
Import it as github.com/tamnd/kv.
The whole API is Open, an Options struct, and five methods on *DB.
For task-oriented walkthroughs, see the guides; this page is the exact reference.
Opening
func Open(path string, opts Options) (*DB, error)
Open opens the store at path, creating it if it does not exist and running recovery if it does.
It takes two arguments: the path and an Options value.
The zero value Options{} is valid, and every field falls back to a default, so kv.Open(path, kv.Options{}) just works.
The store is one file at path plus a small sibling commit-watermark file.
db, err := kv.Open("app.kv", kv.Options{})
if err != nil {
log.Fatal(err)
}
defer db.Close()
Options
type Options struct {
KeyCapacity int // expected distinct key count; sizes the resident key index. Default 1<<20.
HotBytes int64 // size of one in-memory hot segment; writes land here. Default 8 MiB.
HotKeys int // records one hot segment's index is sized for. Zero uses a heuristic from HotBytes.
ResidentBytes int64 // cold log's resident tail window in bytes. Default 64 MiB.
ReadCacheCells int // cells in the read cache over cold reads; rounded up to a power of two. Default 1<<16.
SyncWrites bool // durability contract. Default false (background group commit).
}
| Field | Default | Meaning |
|---|---|---|
KeyCapacity |
1 << 20 (~1M) |
Expected distinct key count. Sizes the resident key index, which holds an entry per key, so it is the memory floor and the one knob worth setting for a large store. |
HotBytes |
8 MiB | Size of one in-memory hot segment, where writes land. Bounds the resident write buffer (at most two segments live) and, under the default durability, the crash-loss window. |
HotKeys |
heuristic from HotBytes |
Records one hot segment's index is sized for; set it when the value size is known. Too small only causes an earlier seal, never a lost write. Zero uses a heuristic. |
ResidentBytes |
64 MiB | Cold log's resident tail window: how much recently-migrated cold data stays in RAM for fast reads. |
ReadCacheCells |
1 << 16 |
Cells in the read cache over cold reads, rounded up to a power of two. |
SyncWrites |
false |
Durability contract. false is background group commit; true is synchronous group commit, where a write waits for the group-commit fsync before it returns. See Durability. |
The sizing guide walks these in the order they matter.
Methods
The whole method surface is five methods on *DB.
func (d *DB) Set(key, value []byte)
func (d *DB) Delete(key []byte)
func (d *DB) Get(key, scratch []byte) ([]byte, bool, error)
func (d *DB) Sync() error
func (d *DB) Close() error
Set
func (d *DB) Set(key, value []byte)
Set writes value under key, overwriting any existing value.
It does not return an error.
The write lands in the in-memory hot tier and returns; under the default durability a background flusher fsyncs it a moment later, and with SyncWrites true it does not return until the group-commit fsync has persisted the record.
Delete
func (d *DB) Delete(key []byte)
Delete removes key.
It does not return an error.
A later Get on that key returns ok == false.
Deleting a key that is not present is a no-op.
Get
func (d *DB) Get(key, scratch []byte) ([]byte, bool, error)
Get looks up key and returns three values: the value, whether the key was found, and an error.
It decodes the value into scratch and returns a slice aliased to it, so a hot loop can reuse one buffer and allocate nothing.
Pass nil as scratch to let the engine allocate a fresh slice for you.
A missing key is ok == false, not an error.
Check ok, not the error, to tell present from absent; the error is reserved for a real read failure.
scratch := make([]byte, 0, 256)
v, ok, err := db.Get([]byte("user:1"), scratch)
if err != nil {
log.Fatal(err)
}
if !ok {
// the key is not present
}
_ = v
Sync
func (d *DB) Sync() error
Sync forces a durability barrier now, under either durability mode.
After it returns, everything written so far is on disk.
Close
func (d *DB) Close() error
Close syncs and then releases the store.
It syncs before returning, so a clean shutdown never sits in the loss window.
Always close the store on the way out, typically with defer db.Close().
Durability contract
Options.SyncWrites picks the contract, and both modes are durable.
With SyncWrites false, the default, a write returns as soon as it lands in the hot tier and a background flusher fsyncs it a moment later.
A crash between the ack and the next flush loses at most the un-flushed hot records, bounded to two segments, the same bounded sub-second window Redis gives with appendfsync everysec.
With SyncWrites true, a Set does not return until the group-commit fsync has persisted its record, so an acked write survives a crash with zero loss, the same contract Redis gives with appendfsync always.
Concurrent writers coalesce onto one shared fsync, so a burst pays one flush rather than one per write; a lone sequential writer pays one fsync per commit.
Sync() forces a barrier on demand under either mode, and Close() syncs before returning.
The durability guide covers when to pick which.
Next
- The configuration reference covers every option's default and the files kv writes on disk.
- The server reference covers the Redis-protocol server.