nitro

package module
v0.0.0-...-937fe99 Latest Latest
Warning

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

Go to latest
Published: Dec 27, 2016 License: Apache-2.0 Imports: 20 Imported by: 1

README

nitro

A high performance in-memory key-value item storage engine written in golang. The storage engine is based lock-free data structures and scales well with multicore CPUs.

Build Status Go Report Card GoDoc

Features
  • Operations: insert, delete, iterator (lookup, range queries)
  • Supports multiple concurrent readers and writers which scales almost linearly
  • Database snapshots which facilitates stable and repeatable scans
  • Lock-free data structures ensures that concurrent readers and writers doesn't block each other
  • The memory overhead of metadata of an item is 64 bytes
  • Fast snapshotting: Minimal overhead snapshots and they can be created frequently (eg,. every 10ms)
  • Optional memory manager based on jemalloc to avoid golang garbage collector for higher performance
  • Custom key comparator
  • Fast backup and restore on disk
Example usage
// Create a nitro instance with default config
db := nitro.New()
defer db.Close()

// Create a writer
// A writer should be created for every concurrent thread
w := db.NewWriter()
for i := 0; i < 100; i++ {
	itm := []byte(fmt.Sprintf("item-%02d", i))
	w.Put(itm)
}

// Create an immutable snapshot
snap1, _ := db.NewSnapshot()

for i := 0; i < 100; i++ {
	if i%2 == 0 {
		itm := []byte(fmt.Sprintf("item-%02d", i))
		w.Delete(itm)
	}
}

// Create an immutable snapshot
snap2, _ := db.NewSnapshot()

// Create an iterator for a snapshot
it1 := snap1.NewIterator()
count1 := 0
for it1.SeekFirst(); it1.Valid(); it1.Next() {
	fmt.Println("snap-1", string(it1.Get()))
	count1++
}

// Close snapshot and iterator once you have finished using them
it1.Close()
snap1.Close()

// Create an iterator for a snapshot
it2 := snap2.NewIterator()
count2 := 0
for it2.SeekFirst(); it2.Valid(); it2.Next() {
	fmt.Println("snap-2", string(it2.Get()))
	count2++
}

// Close snapshot and iterator once you have finished using them
it2.Close()
snap2.Close()

fmt.Println(count2 == count1/2)
License

Apache 2.0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrMaxSnapshotsLimitReached means 32 bit integer overflow of snap number
	ErrMaxSnapshotsLimitReached = fmt.Errorf("Maximum snapshots limit reached")
	// ErrShutdown means an operation on a shutdown Nitro instance
	ErrShutdown = fmt.Errorf("Nitro instance has been shutdown")
)
View Source
var (
	// DiskBlockSize - backup file reader and writer
	DiskBlockSize = 512 * 1024
)

Functions

func CompareKV

func CompareKV(a []byte, b []byte) int

CompareKV is a comparator for KV item

func CompareNitro

func CompareNitro(this unsafe.Pointer, that unsafe.Pointer) int

CompareNitro implements comparator for Nitro instances based on its id

func CompareSnapshot

func CompareSnapshot(this, that unsafe.Pointer) int

CompareSnapshot implements comparator for snapshots based on snapshot number

func Debug

func Debug(flag bool)

Debug enables debug mode Additional details will be logged in the statistics

func ItemSize

func ItemSize(p unsafe.Pointer) int

ItemSize returns total bytes consumed by item representation

func KVFromBytes

func KVFromBytes(bs []byte) (k, v []byte)

KVFromBytes extracts key-value pair from item bytes returned by iterator

func KVToBytes

func KVToBytes(k, v []byte) []byte

KVToBytes encodes key-value pair to item bytes which can be passed to the Put() and Delete() methods.

func MemoryInUse

func MemoryInUse() (sz int64)

MemoryInUse returns total memory used by all Nitro instances in the current process

func SnapshotSize

func SnapshotSize(p unsafe.Pointer) int

SnapshotSize returns the memory used by Nitro snapshot metadata

Types

type Config

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

Config - Nitro instance configuration

func DefaultConfig

func DefaultConfig() Config

DefaultConfig - Nitro configuration

func (*Config) SetKeyComparator

func (cfg *Config) SetKeyComparator(cmp KeyCompare)

SetKeyComparator provides key comparator for the Nitro item data

func (*Config) UseDeltaInterleaving

func (cfg *Config) UseDeltaInterleaving()

UseDeltaInterleaving option enables to avoid additional memory required during disk backup as due to locking of older snapshots. This non-intrusive backup mode eliminates the need for locking garbage collectable old snapshots. But, it may use additional amount of disk space for backup.

func (*Config) UseMemoryMgmt

func (cfg *Config) UseMemoryMgmt(malloc skiplist.MallocFn, free skiplist.FreeFn)

UseMemoryMgmt provides custom memory allocator for Nitro items storage

type FileReader

type FileReader interface {
	Open(path string) error
	ReadItem() (*Item, error)
	Close() error
}

FileReader represents backup file reader

type FileType

type FileType int

FileType describes backup file format

const (

	// RawdbFile - backup file storage format
	RawdbFile FileType = iota
)

type FileWriter

type FileWriter interface {
	Open(path string) error
	WriteItem(*Item) error
	Close() error
}

FileWriter represents backup file writer

type Item

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

Item represents nitro item header The item data is followed by the header. Item data is a block of bytes. The user can store key and value into a block of bytes and provide custom key comparator.

func (*Item) Bytes

func (itm *Item) Bytes() (bs []byte)

Bytes return item data bytes

type ItemCallback

type ItemCallback func(*ItemEntry)

ItemCallback implements callback used for backup file to Nitro restore API

type ItemEntry

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

ItemEntry is a wrapper item struct used by backup file to Nitro restore callback

func (*ItemEntry) Item

func (e *ItemEntry) Item() *Item

Item returns Nitro item

func (*ItemEntry) Node

func (e *ItemEntry) Node() *skiplist.Node

Node returns the skiplist node which holds the item

type Iterator

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

Iterator implements Nitro snapshot iterator

func (*Iterator) Close

func (it *Iterator) Close()

Close executes destructor for iterator

func (*Iterator) Get

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

Get eturns the current item data from the iterator.

func (*Iterator) GetNode

func (it *Iterator) GetNode() *skiplist.Node

GetNode eturns the current skiplist node which holds current item.

func (*Iterator) Next

func (it *Iterator) Next()

Next moves iterator cursor to the next item

func (*Iterator) Refresh

func (it *Iterator) Refresh()

Refresh is a helper API to call refresh accessor tokens manually This would enable SMR to reclaim objects faster if an iterator is alive for a longer duration of time.

func (*Iterator) Seek

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

Seek to a specified key or the next bigger one if an item with key does not exist.

func (*Iterator) SeekFirst

func (it *Iterator) SeekFirst()

SeekFirst moves cursor to the beginning

func (*Iterator) SetRefreshRate

func (it *Iterator) SetRefreshRate(rate int)

SetRefreshRate sets automatic refresh frequency. By default, it is unlimited If this is set, the iterator SMR accessor will be refreshed after every `rate` items.

func (*Iterator) Valid

func (it *Iterator) Valid() bool

Valid eturns false when the iterator has reached the end.

type KeyCompare

type KeyCompare func([]byte, []byte) int

KeyCompare implements item data key comparator

type Nitro

type Nitro struct {
	Config
	// contains filtered or unexported fields
}

Nitro instance

func New

func New() *Nitro

New creates a Nitro instance using default configuration

func NewWithConfig

func NewWithConfig(cfg Config) *Nitro

NewWithConfig creates a new Nitro instance based on provided configuration.

func (*Nitro) Close

func (m *Nitro) Close()

Close shuts down the nitro instance

func (*Nitro) DecodeItem

func (m *Nitro) DecodeItem(buf []byte, r io.Reader) (*Item, error)

DecodeItem decodes encoded [2 byte len][item_bytes] format.

func (*Nitro) DumpStats

func (m *Nitro) DumpStats() string

DumpStats returns Nitro statistics

func (*Nitro) EncodeItem

func (m *Nitro) EncodeItem(itm *Item, buf []byte, w io.Writer) error

EncodeItem encodes in [2 byte len][item_bytes] format.

func (*Nitro) GC

func (m *Nitro) GC()

GC implements manual garbage collection of Nitro snapshots.

func (*Nitro) GetSnapshots

func (m *Nitro) GetSnapshots() []*Snapshot

GetSnapshots returns the list of current live snapshots This API is mainly for debugging purpose

func (*Nitro) ItemsCount

func (m *Nitro) ItemsCount() int64

ItemsCount returns the number of items in the Nitro instance

func (*Nitro) LoadFromDisk

func (m *Nitro) LoadFromDisk(dir string, concurr int, callb ItemCallback) (*Snapshot, error)

LoadFromDisk restores Nitro from a disk backup

func (*Nitro) MemoryInUse

func (m *Nitro) MemoryInUse() int64

MemoryInUse returns total memory used by the Nitro instance.

func (*Nitro) NewIterator

func (m *Nitro) NewIterator(snap *Snapshot) *Iterator

NewIterator creates an iterator for a Nitro snapshot

func (*Nitro) NewSnapshot

func (m *Nitro) NewSnapshot() (*Snapshot, error)

NewSnapshot creates a new Nitro snapshot. This is a thread-unsafe API. While this API is invoked, no other Nitro writer should concurrently call any public APIs such as Put*() and Delete*().

func (*Nitro) NewWriter

func (m *Nitro) NewWriter() *Writer

NewWriter creates a Nitro writer

func (*Nitro) StoreToDisk

func (m *Nitro) StoreToDisk(dir string, snap *Snapshot, concurr int, itmCallback ItemCallback) (err error)

StoreToDisk backups Nitro snapshot to disk Concurrent threads are used to perform backup and concurrency can be specified.

func (*Nitro) Visitor

func (m *Nitro) Visitor(snap *Snapshot, callb VisitorCallback, shards int, concurrency int) error

Visitor implements concurrent Nitro snapshot visitor This API divides the range of keys in a snapshot into `shards` range partitions Number of concurrent worker threads used can be specified.

type NodeList

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

NodeList is a linked list of skiplist nodes

func NewNodeList

func NewNodeList(head *skiplist.Node) *NodeList

NewNodeList creates new node list

func (*NodeList) Add

func (l *NodeList) Add(node *skiplist.Node)

Add a key into the node list

func (*NodeList) Head

func (l *NodeList) Head() *skiplist.Node

Head returns head node from the list

func (*NodeList) Keys

func (l *NodeList) Keys() (keys [][]byte)

Keys returns all keys from the node list

func (*NodeList) Remove

func (l *NodeList) Remove(key []byte) *skiplist.Node

Remove a key from the node list

type Snapshot

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

Snapshot describes Nitro immutable snapshot

func (*Snapshot) Close

func (s *Snapshot) Close()

Close is the snapshot descructor Once a thread has finished using a snapshot, it can be destroyed by calling Close(). Internal garbage collector takes care of freeing the items.

func (Snapshot) Count

func (s Snapshot) Count() int64

Count returns the number of items in the Nitro snapshot

func (*Snapshot) Decode

func (s *Snapshot) Decode(buf []byte, r io.Reader) error

Decode implements binary decoder for snapshot metadata

func (*Snapshot) Encode

func (s *Snapshot) Encode(buf []byte, w io.Writer) error

Encode implements Binary encoder for snapshot metadata

func (*Snapshot) NewIterator

func (s *Snapshot) NewIterator() *Iterator

NewIterator creates a new snapshot iterator

func (*Snapshot) Open

func (s *Snapshot) Open() bool

Open implements reference couting and garbage collection for snapshots When snapshots are shared by multiple threads, each thread should Open the snapshot. This API internally tracks the reference count for the snapshot.

type VisitorCallback

type VisitorCallback func(*Item, int) error

VisitorCallback implements Nitro snapshot visitor callback

type Writer

type Writer struct {
	*Nitro
	// contains filtered or unexported fields
}

Writer provides a handle for concurrent access Nitro writer is thread-unsafe and should initialize separate Nitro writers to perform concurrent writes from multiple threads.

func (*Writer) Delete

func (w *Writer) Delete(bs []byte) (success bool)

Delete an item Delete always succeed if an item exists.

func (*Writer) Delete2

func (w *Writer) Delete2(bs []byte) (n *skiplist.Node, success bool)

Delete2 is same as Delete(). Additionally returns the deleted item's node

func (*Writer) DeleteNode

func (w *Writer) DeleteNode(x *skiplist.Node) (success bool)

DeleteNode deletes an item by specifying its skiplist Node. Using this API can avoid a O(logn) lookup during Delete().

func (*Writer) GetNode

func (w *Writer) GetNode(bs []byte) *skiplist.Node

GetNode implements lookup of an item and return its skiplist Node This API enables to lookup an item without using a snapshot handle.

func (*Writer) Put

func (w *Writer) Put(bs []byte)

Put implements insert of an item into Intro Put fails if an item already exists

func (*Writer) Put2

func (w *Writer) Put2(bs []byte) (n *skiplist.Node)

Put2 returns the skiplist node of the item if Put() succeeds

Directories

Path Synopsis
Package nodetable implements high performance GC optimized Node lookup table for Nitro index storage.
Package nodetable implements high performance GC optimized Node lookup table for Nitro index storage.

Jump to

Keyboard shortcuts

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