zerokv

package module
v1.0.104 Latest Latest
Warning

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

Go to latest
Published: Apr 1, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

README

ZeroKV - Minimal Key-Value Store Abstraction for Go

Go Report Card Test and Benchmark Go Version PkgGoDev GitHub last commit GitHub Release GitHub issues

ZeroKV is a minimal, zero-overhead key-value store abstraction for Go. Write your data logic once, then switch databases by changing a single import. Perfect for applications that need flexibility in database choice.

Key Features

  • Minimal Abstraction - Small, focused interface (Core, Batch, Iterator)
  • Zero Overhead - No reflection, no wrappers, just direct calls
  • Raw Bytes - Full control over serialization (JSON, Protobuf, msgpack, etc.)
  • Context Aware - Full support for cancellation, timeouts, and deadlines
  • Pluggable Backends - Switch databases without changing application code
  • Production Ready - Well-tested with multiple implementations
  • Comprehensive Testing - 80%+ test coverage with shared integration tests

Philosophy

ZeroKV is built on three core principles:

  1. Minimal API - Only essential operations: Put, Get, Delete, Batch, Scan, Close
  2. Zero Wrapper Overhead - Direct database calls, no unnecessary abstractions
  3. You Control Serialization - Work with raw bytes, serialize however you want
  4. Context Support - Proper Go idioms with context.Context
  5. Explicit Over Implicit - Clear behavior, no hidden complexity

Quick Start

Installation
go get github.com/rawbytedev/zerokv
Basic Usage
package main

import (
    "context"
    "github.com/rawbytedev/zerokv/badgerdb"
)

func main() {
    // Initialize database
    db, err := badgerdb.NewBadgerDB(badgerdb.Config{Dir: "/tmp/mydb"})
    if err != nil {
        panic(err)
    }
    defer db.Close()

    ctx := context.Background()

    // Put - Insert or update
    db.Put(ctx, []byte("hello"), []byte("world"))

    // Get - Retrieve
    value, err := db.Get(ctx, []byte("hello"))
    if err == nil {
        println(string(value)) // Output: world
    }

    // Delete - Remove
    db.Delete(ctx, []byte("hello"))
}
Switching Databases

One of ZeroKV's superpowers is database portability:

// Using BadgerDB
db, _ := badgerdb.NewBadgerDB(badgerdb.Config{Dir: "/tmp/data"})

// Switch to PebbleDB - zero code changes needed
// db, _ := pebbledb.NewPebbleDB(pebbledb.Config{Dir: "/tmp/data"})

// All existing code works unchanged
db.Put(ctx, []byte("key"), []byte("value"))

Implementations

Built-in Backends
Database Features Best For
BadgerDB High-performance LSM tree Write-heavy workloads, strong consistency
PebbleDB RocksDB-compatible, flexible Read-heavy workloads, compatibility needs
MemDB In-memory, fast Testing, caching, development (no Scan support)
Custom Implementations

Implementing your own backend is straightforward. See IMPLEMENTATION.md for a complete guide.

Documentation

Core Operations

CRUD Operations
// Put - Insert or update
db.Put(ctx, []byte("name"), []byte("Alice"))

// Get - Retrieve
value, err := db.Get(ctx, []byte("name"))

// Delete - Remove
db.Delete(ctx, []byte("name"))
Batch Operations
batch := db.Batch()
batch.Put([]byte("user:1"), []byte("Alice"))
batch.Put([]byte("user:2"), []byte("Bob"))
batch.Delete([]byte("old_user"))
err := batch.Commit(ctx)
Iteration
iter := db.Scan([]byte("user:"))
defer iter.Release()

for iter.Next() {
    key := iter.Key()
    value := iter.Value()
    // Process key-value pair
}

if iter.Error() != nil {
    panic(iter.Error())
}

Advanced Features

Context Support
// Timeouts
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

value, err := db.Get(ctx, []byte("key"))
if errors.Is(err, context.DeadlineExceeded) {
    log.Println("Operation timed out")
}

// Cancellation
ctx, cancel := context.WithCancel(context.Background())
cancel()

err := db.Put(ctx, []byte("key"), []byte("value"))
// Returns context.Cancelled error
Error Handling

Different backends may handle errors differently. Always refer to ERROR_HANDLING.md:

// BadgerDB returns error on batch reuse
batch.Put(key, value)
batch.Commit(ctx)
err := batch.Put(key2, value2) // Error

// PebbleDB panics on batch reuse
batch.Put(key, value)
batch.Commit(ctx)
batch.Put(key2, value2) // Panic - create new batch!

Performance

ZeroKV adds minimal overhead:

  • No reflection or interface{} conversions
  • Direct method calls to underlying database
  • Zero-copy where possible
  • Efficient memory handling

See benchmark results in BENCHMARK.md (if available).

Project Structure

zerokv/
├── interface.go            # Core interfaces
├── badgerdb/               # BadgerDB implementation
│   ├── badgerdb.go         # Main code
│   ├── badgerdb_test.go    # Tests
│   └── options.go          # Configuration
├── pebbledb/               # PebbleDB implementation
│   ├── pebbledb.go
│   ├── pebbledb_test.go
│   └── options.go
├── tests/                  # Shared integration tests
├── helpers/                # Test utilities
├── examples/               # Usage examples

Testing

Comprehensive test coverage across implementations:

# Run all tests
go test ./... -v

# Run with coverage
go test ./... -cover

# Run with race detector
go test ./... -race

# Run specific implementation
go test ./badgerdb -v
go test ./pebbledb -v

Examples

Example 1: User Store with JSON
import "encoding/json"

type User struct {
    ID   string
    Name string
    Age  int
}

// Store user
user := User{ID: "1", Name: "Alice", Age: 30}
data, _ := json.Marshal(user)
db.Put(ctx, []byte("user:1"), data)

// Retrieve and deserialize
value, _ := db.Get(ctx, []byte("user:1"))
var retrieved User
json.Unmarshal(value, &retrieved)
Example 2: Batch Insert
batch := db.Batch()
for i := 0; i < 1000; i++ {
    key := []byte(fmt.Sprintf("key:%d", i))
    value := []byte(fmt.Sprintf("value:%d", i))
    batch.Put(key, value)
}
batch.Commit(ctx)
Example 3: Database Failover
func getValue(primary, backup zerokv.Core, key []byte) ([]byte, error) {
    value, err := primary.Get(ctx, key)
    if err == nil {
        return value, nil
    }
    
    log.Println("Primary failed, trying backup")
    return backup.Get(ctx, key)
}

Contributing

Contributions are welcome! Please read CONTRIBUTING.md for guidelines.

To Implement a New Backend
  1. Read IMPLEMENTATION.md
  2. Create your package (e.g., mydb/)
  3. Implement Core, Batch, and Iterator interfaces
  4. Add tests
  5. Submit a pull request
Requirements
  • Go 1.25.2+
  • Chosen Database

License

Apache License 2.0 - See LICENSE for details.

Support

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Batch

type Batch interface {
	// Flush commits all batched operations to the database
	Commit(ctx context.Context) error
	// Put inserts or updates a key-value pair in the database
	Put(key []byte, data []byte) error
	// Delete deletes a key-value pair from the database
	Delete(key []byte) error
}

Batch defines methods for batching multiple write operations together

type Core

type Core interface {
	// Put inserts or updates a key-value pair in the database
	Put(ctx context.Context, key []byte, data []byte) error
	// Get retrieves the value for a given key
	Get(ctx context.Context, key []byte) ([]byte, error)
	// Delete removes a key-value pair from the database
	Delete(ctx context.Context, key []byte) error
	// Batch creates a new write batch that needs to be committed separately
	Batch() Batch
	// Scan returns an iterator to traverse key-value pairs with the specified prefix
	Scan(prefix []byte) Iterator
	// Close closes the database connection
	Close() error
}

Core defines the main interface for a key-value database

type Iterator

type Iterator interface {
	Next() bool    // advances the iterator to the next key-value pair
	Key() []byte   // returns the current key
	Value() []byte // returns the current value
	Release()      // releases the iterator resources
	Error() error  // returns any error encountered during iteration
}

Iterator defines methods for iterating over key-value pairs in the database

Directories

Path Synopsis
Switch during runtimes to recover from errors or to balance load
Switch during runtimes to recover from errors or to balance load

Jump to

Keyboard shortcuts

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