yojoudb

package module
v0.0.0-...-37009e5 Latest Latest
Warning

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

Go to latest
Published: Mar 20, 2024 License: Apache-2.0 Imports: 15 Imported by: 0

README

yojoudb

An embeddable, fast and persistent key-value storage engine based on Bitcask.

Getting Started

Basic Example
package main

import (
	"fmt"
	"github.com/berylyvos/yojoudb"
)

func main() {
	// specify the options
	options := yojoudb.DefaultOptions

	// open a database
	db, err := yojoudb.Open(options)
	if err != nil {
		panic(err)
	}
	defer func() {
		_ = db.Close()
	}()

	// put a key
	key := []byte("hello")
	if err = db.Put(key, []byte("yojoudb")); err != nil {
		panic(err)
	}

	// get a key
	val, err := db.Get(key)
	if err != nil {
		panic(err)
	}
	println(string(val))

	// delete a key
	if err = db.Delete(key); err != nil {
		panic(err)
	}

	// create a batch
	batch := db.NewBatch(yojoudb.DefaultBatchOptions)

	// batch put keys/values
	for i := 0; i < 100; i++ {
		_ = batch.Put([]byte(fmt.Sprintf("#%d", i)), []byte(fmt.Sprintf("yojoudb-%d", i)))
	}

	// commit the batch
	_ = batch.Commit()

	// create an iterator
	iter := db.NewIterator(yojoudb.DefaultIteratorOptions)
	defer iter.Close()
	// iterate over all data
	for ; iter.Valid(); iter.Next() {
		v, _ := iter.Value()
		println(string(v))
	}
}

Benchmarks

We compared how well yojoudb performs in random writes and random point lookups against several high-performing Golang-based key-value stores using the benchmarking tool pogreb-bench.

Performance Metrics
Engine PUT GET put + get file size peak sys mem
yojoudb 13.771s    145229 ops/s 2.163s    924817 ops/s 15.934s 782.15MB 1.31GB
badger 8.813s    226930 ops/s 4.939s    404921 ops/s 13.752s 250.95MB 3.60GB
pebble 13.594s    147125 ops/s 4.844s    412882 ops/s 18.438s 229.16MB 446.60MB
goleveldb 25.199s    79367 ops/s 6.956s    287539 ops/s 32.155s 714.31MB 529.79MB
bbolt 84.245s    23740 ops/s 1.555s    1286247 ops/s 85.800s 1.03GB 481.17MB
Parameters
key nums key size val size concurrency
2000000 16 ~ 64 128 ~ 512 5

In-memory Table

For yojoudb, we use ART(Adaptive Radix Tree) as the default in-memory table. Alternatively, other index types (B-tree, skiplist) can be specified by yojoudb.DefaultOptions.IndexType (IndexBTree, IndexART, IndexSKL).

Documentation

Index

Constants

View Source
const (
	B  = 1
	KB = 1024 * B
	MB = 1024 * KB
	GB = 1024 * MB
)

Variables

View Source
var (
	ErrKeyEmpty    = errors.New("the key is empty")
	ErrKeyNotFound = errors.New("key is not found in database")

	ErrDirPathIsEmpty          = errors.New("database dir path is empty")
	ErrDataFileSizeNotPositive = errors.New("database data file size must be greater than 0")
	ErrDatabaseIsUsing         = errors.New("the database directory is used by another process")

	ErrDBClosed       = errors.New("the database is closed")
	ErrReadOnlyBatch  = errors.New("the batch is read only")
	ErrMergeIsRunning = errors.New("merge is in progress, try again later")
)
View Source
var DefaultBatchOptions = BatchOptions{
	Sync:     true,
	ReadOnly: false,
}
View Source
var DefaultIteratorOptions = IteratorOptions{
	Prefix:  nil,
	Reverse: false,
}
View Source
var DefaultOptions = Options{
	DirPath:      tempDBDir(),
	SegmentSize:  GB,
	Sync:         false,
	BytesPerSync: 0,
	IndexType:    IndexART,
}

Functions

This section is empty.

Types

type Batch

type Batch struct {
	// contains filtered or unexported fields
}

Batch is a batch operation of the database. A batch can be read-only, calling Get() to get data. Otherwise, calling Delete() or Put() to put data. You must call Commit() to commit the batch, otherwise the deadlock happens.

Batch is not a transaction, for it does not guarantee isolation. But it can guarantee atomicity, consistency and durability.

func (*Batch) Commit

func (b *Batch) Commit() error

Commit commits the batch, if the batch is readonly or empty, return. It will iterate the pendingWrites and write the data to the db, then write a record to indicate the end of batch to guarantee atomicity. Finally, index will be updated.

func (*Batch) Delete

func (b *Batch) Delete(key K) error

Delete adds a key to the batch for pending delete.

func (*Batch) Exist

func (b *Batch) Exist(key K) (bool, error)

Exist checks if the key exists in the database.

func (*Batch) Get

func (b *Batch) Get(key K) (V, error)

Get gets the value of the given key. The key could still be in pendingWrites and haven't committed yet, return the value if the record type is not LRDeleted. Otherwise, get the value from WAL.

func (*Batch) Put

func (b *Batch) Put(key K, value V) error

Put adds a key/val to the batch for pending write.

func (*Batch) Rollback

func (b *Batch) Rollback() error

Rollback discards a uncommitted batch instance. It will clear pendingWrites and release db.lock.

type BatchOptions

type BatchOptions struct {
	Sync     bool
	ReadOnly bool
}

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB is a database instance. It's built on a log-structured model, the Bitcask. Read and write data based on WAL(Write-Ahead Log). An in-memory index is for holding the keys and the corresponding locations. The index is rebuilt each time the database is restarted.

func Open

func Open(options Options) (*DB, error)

Open opens a db instance with specified options. It will open the WAL files and build the index.

func (*DB) Close

func (db *DB) Close() error

Close closes the db instance.

func (*DB) Delete

func (db *DB) Delete(key K) error

Delete deletes the given key.

func (*DB) Exist

func (db *DB) Exist(key K) (bool, error)

Exist checks if the given key exists.

func (*DB) Fold

func (db *DB) Fold(fn func(key []byte, value []byte) bool) error

Fold iterates every key/val, executes func on it, stops when func return false.

func (*DB) Get

func (db *DB) Get(key K) (V, error)

Get gets the value of the given key. Returns nil if key is not found.

func (*DB) GetDirPath

func (db *DB) GetDirPath() string

func (*DB) ListKeys

func (db *DB) ListKeys() [][]byte

ListKeys returns all keys in db instance.

func (*DB) Merge

func (db *DB) Merge() error

Merge merges all the data files. It will iterate all over the WAL, filtering valid data, then writing them to a new WAL in the merge directory.

Calling this method is up to the users, it may be very time-consuming when the database is large.

func (*DB) NewBatch

func (db *DB) NewBatch(options BatchOptions) *Batch

func (*DB) NewIterator

func (db *DB) NewIterator(options IteratorOptions) *Iterator

func (*DB) Put

func (db *DB) Put(key K, val V) error

Put puts the given key/val.

func (*DB) Stat

func (db *DB) Stat() *Stat

func (*DB) Sync

func (db *DB) Sync() error

Sync syncs all data files into disk.

type IndexRecord

type IndexRecord struct {
	// contains filtered or unexported fields
}

IndexRecord is the index record of the key. Only used in start up to build in-mem index.

type IndexType

type IndexType = uint8
const (
	IndexBTree IndexType = iota
	IndexART
	IndexSKL
)

type Iterator

type Iterator struct {
	IndexIter meta.Iterator
	// contains filtered or unexported fields
}

Iterator is the iterator of db based on IndexIter.

func (*Iterator) Close

func (it *Iterator) Close()

Close closes the iterator.

func (*Iterator) Key

func (it *Iterator) Key() []byte

Key gets the current key in the iterator.

func (*Iterator) Next

func (it *Iterator) Next()

Next moves the iterator to the next key.

func (*Iterator) Rewind

func (it *Iterator) Rewind()

Rewind seeks the first key in the iterator.

func (*Iterator) Seek

func (it *Iterator) Seek(key []byte)

Seek moves the iterator to the key which is greater(or less when reverse) than or equal to the specified key.

func (*Iterator) Valid

func (it *Iterator) Valid() bool

Valid checks if the iterator is in valid position.

func (*Iterator) Value

func (it *Iterator) Value() ([]byte, error)

Value gets the current val in the iterator.

type IteratorOptions

type IteratorOptions struct {
	Prefix  []byte
	Reverse bool
}

type K

type K = []byte

K key alias for []byte

type LR

type LR = LogRecord

LR alias for LogRecord

type LRType

type LRType = byte
const (
	LRNormal LRType = iota
	LRDeleted
	LRBatchFin
)

type Loc

type Loc = wal.ChunkLoc

Loc alias for wal.ChunkLoc

type LogRecord

type LogRecord struct {
	Key     K
	Val     V
	Type    LRType
	BatchId uint64
}

LogRecord is the log record of the key/val.

type Options

type Options struct {
	DirPath      string
	SegmentSize  int64
	Sync         bool
	BytesPerSync uint32
	IndexType    IndexType
}

type Stat

type Stat struct {
	KeyNum          uint64
	DataFileNum     uint32
	ReclaimableSize int64
	DiskSize        int64
}

type V

type V = []byte

V value alias for []byte

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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