db

package
v0.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: UNKNOWN, Apache-2.0, UNKNOWN not legal advice Imports: 0 Imported by: 0

README

DB

Database abstractions to be used in applications. These abstractions are not only meant to be used in applications built on Tendermint, but can be used in a variety of applications.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func InternalRegisterDBCreator

func InternalRegisterDBCreator(backend BackendType, creator dbCreator, force bool)

InternalRegisterDBCreator is used by the init functions of imported databases to register their own dbCreators.

This function is not meant for usage outside of db/.

func IsKeyInDomain

func IsKeyInDomain(key, start, end []byte) bool

See DB interface documentation for more information.

Types

type BackendType

type BackendType string
const (
	// GoLevelDBBackend represents goleveldb (github.com/syndtr/goleveldb - most
	// popular implementation)
	//   - stable
	GoLevelDBBackend BackendType = "goleveldb"

	// PebbleDBBackend represents pebble (github.com/cockroachdb/pebble)
	//   - stable
	PebbleDBBackend BackendType = "pebbledb"

	// MemDBBackend represents in-memory key value store, which is mostly used
	// for testing.
	MemDBBackend BackendType = "memdb"

	// BoltDBBackend represents bolt (uses etcd's fork of bolt -
	// go.etcd.io/bbolt)
	//   - EXPERIMENTAL
	//   - may be faster is some use-cases (random reads - indexer)
	BoltDBBackend BackendType = "boltdb"
)

These are valid backend types.

The backends themselves must be imported to be used (ie. using the blank import, `import _ "github.com/gnolang/gno/tm2/pkg/db/goleveldb"`). To allow for end-user customization at build time, the package "github.com/gnolang/gno/tm2/pkg/db/_tags" can be imported -- this package will import each database depending on whether its build tag is provided.

This can be used in conjunction with specific to provide defaults, for instance:

package main

import (
	"github.com/gnolang/gno/tm2/pkg/db"
	_ "github.com/gnolang/gno/tm2/pkg/db/_tags" // allow user to customize with build tags
	_ "github.com/gnolang/gno/tm2/pkg/db/memdb" // always support memdb
)

func main() {
	db.NewDB("mydb", db.BackendType(userProvidedBackend), "./data")
}

func BackendList

func BackendList() []BackendType

BackendList returns a list of available db backends. The list is sorted.

func (BackendType) String

func (b BackendType) String() string

type Batch

type Batch interface {
	// Set sets a key/value pair.
	// CONTRACT: key, value readonly []byte
	Set(key, value []byte) error

	// Delete deletes a key/value pair.
	// CONTRACT: key readonly []byte
	Delete(key []byte) error

	// Write writes the batch, possibly without flushing to disk. Only Close() can be called after,
	// other methods will error.
	Write() error

	// WriteSync writes the batch and flushes it to disk. Only Close() can be called after, other
	// methods will error.
	WriteSync() error

	// Close closes the batch. It is idempotent, but calls to other methods afterwards will error.
	Close() error

	// GetByteSize that returns the current size of the batch in bytes. Depending on the implementation,
	// this may return the size of the underlying LSM batch, including the size of additional metadata
	// on top of the expected key and value total byte count.
	GetByteSize() (int, error)
}

Batch represents a group of writes. They may or may not be written atomically depending on the backend. Callers must call Close on the batch when done.

Batch Close must be called when the program no longer needs the object.

type BatchCollector

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

BatchCollector accumulates Set/Delete operations in memory without touching disk. It backs CollectingDB and lets rootmulti fuse multiple sub-store write sites (dbadapter flush, IAVL SaveVersion, rootmulti metadata) into one atomic disk write: each writer appends via a batchHandle, and the caller drains the accumulated ops into a real Batch at the end of the commit.

pending indexes the last op per key so CollectingDB can serve read-your- writes without touching the underlying DB — required when a caller writes and then reads back before the next drain (e.g. deploying a package in one tx and importing it in the next, before the block-level Commit runs).

Set/Delete/Get are safe for concurrent use. Reset and Drain must not race with writers; they are called before/after the commit window when no writer is active.

func NewBatchCollector

func NewBatchCollector() *BatchCollector

NewBatchCollector returns an empty collector.

func (*BatchCollector) Drain

func (c *BatchCollector) Drain(dst Batch) error

Drain replays every collected op into dst in the order recorded, then clears the collector. The caller flushes dst (typically via WriteSync) to persist them atomically.

func (*BatchCollector) Len

func (c *BatchCollector) Len() int

Len returns the number of ops currently buffered.

func (*BatchCollector) NewBatch

func (c *BatchCollector) NewBatch() Batch

NewBatch returns a Batch that appends into this collector. Callers use it to write into the same op-log as CollectingDB-wrapped sub-stores; it lets rootmulti feed its own metadata (commitInfo, latestVersion) into the same atomic drain as IAVL and dbadapter writes.

func (*BatchCollector) Reset

func (c *BatchCollector) Reset()

Reset drops all accumulated ops. Call at the start of a commit window.

type CollectingDB

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

CollectingDB wraps a real DB and routes every write through a shared BatchCollector while reads pass through untouched. It is installed under rootmulti's sub-stores so that IAVL, dbadapter, and rootmulti's own metadata writes accumulate in one place during CommitAll and get flushed as a single atomic batch.

Reads always hit the underlying real DB — the collector never serves reads. This is safe because:

  • IAVL's SaveVersion never re-reads a node it just wrote in the same call (newly-created nodes live in ndb.nodeCache, which GetNode checks before falling through to db.Get).
  • dbadapter's cache flush uses NewBatch()/batch.Set/batch.Write and never reads back its own uncommitted writes.

func NewCollectingDB

func NewCollectingDB(db DB, c *BatchCollector) *CollectingDB

NewCollectingDB returns a DB whose writes accumulate in c and whose reads pass through to db. Reads and writes may run concurrently.

func (*CollectingDB) Close

func (c *CollectingDB) Close() error

Close is a no-op — the caller owns the real DB.

func (*CollectingDB) Delete

func (c *CollectingDB) Delete(key []byte) error

func (*CollectingDB) DeleteSync

func (c *CollectingDB) DeleteSync(key []byte) error

func (*CollectingDB) Get

func (c *CollectingDB) Get(key []byte) ([]byte, error)

Get consults the collector first for read-your-writes, then falls through to the real DB. A pending Delete masks any real value for the key.

func (*CollectingDB) Has

func (c *CollectingDB) Has(key []byte) (bool, error)

Has mirrors Get: a pending Set makes the key present, a pending Delete makes it absent regardless of real DB state, and otherwise we defer to the real DB.

func (*CollectingDB) Iterator

func (c *CollectingDB) Iterator(start, end []byte) (Iterator, error)

Iterator and ReverseIterator do NOT merge pending writes with the real DB. Callers that iterate before the next Drain will miss pending Sets and see stale keys through pending Deletes. Current consumers (IAVL SaveVersion, dbadapter cache flush, rootmulti metadata) don't iterate during a commit window, so this is safe today; revisit if that changes.

func (*CollectingDB) NewBatch

func (c *CollectingDB) NewBatch() Batch

NewBatch and NewBatchWithSize return a Batch whose Set/Delete route into the same collector as direct writes. Write/WriteSync/Close are no-ops so IAVL's BatchWithFlusher can auto-flush freely without losing ops or forcing early disk writes — the collector is drained externally when the commit closes.

func (*CollectingDB) NewBatchWithSize

func (c *CollectingDB) NewBatchWithSize(int) Batch

func (*CollectingDB) NewSnapshot

func (c *CollectingDB) NewSnapshot() (Snapshot, error)

func (*CollectingDB) Print

func (c *CollectingDB) Print() error

func (*CollectingDB) ReverseIterator

func (c *CollectingDB) ReverseIterator(start, end []byte) (Iterator, error)

func (*CollectingDB) Set

func (c *CollectingDB) Set(key, value []byte) error

Direct writes route into the collector. SetSync/DeleteSync collapse to Set/ Delete because the collector is drained under an explicit WriteSync at the end of the commit.

func (*CollectingDB) SetSync

func (c *CollectingDB) SetSync(key, value []byte) error

func (*CollectingDB) Stats

func (c *CollectingDB) Stats() map[string]string

type DB

type DB interface {
	// Get returns nil iff key doesn't exist.
	// A nil key is interpreted as an empty byteslice.
	// CONTRACT: key, value readonly []byte
	Get([]byte) ([]byte, error)

	// Has checks if a key exists.
	// A nil key is interpreted as an empty byteslice.
	// CONTRACT: key, value readonly []byte
	Has(key []byte) (bool, error)

	// Set sets the key.
	// A nil key is interpreted as an empty byteslice.
	// CONTRACT: key, value readonly []byte
	Set([]byte, []byte) error
	SetSync([]byte, []byte) error

	// Delete deletes the key.
	// A nil key is interpreted as an empty byteslice.
	// CONTRACT: key readonly []byte
	Delete([]byte) error
	DeleteSync([]byte) error

	// Iterate over a domain of keys in ascending order. End is exclusive.
	// Start must be less than end, or the Iterator is invalid.
	// A nil start is interpreted as an empty byteslice.
	// If end is nil, iterates up to the last item (inclusive).
	// CONTRACT: No writes may happen within a domain while an iterator exists over it.
	// CONTRACT: start, end readonly []byte
	Iterator(start, end []byte) (Iterator, error)

	// Iterate over a domain of keys in descending order. End is exclusive.
	// Start must be less than end, or the Iterator is invalid.
	// If start is nil, iterates up to the first/least item (inclusive).
	// If end is nil, iterates from the last/greatest item (inclusive).
	// CONTRACT: No writes may happen within a domain while an iterator exists over it.
	// CONTRACT: start, end readonly []byte
	ReverseIterator(start, end []byte) (Iterator, error)

	// Closes the connection.
	Close() error

	// Creates a batch for atomic updates.
	NewBatch() Batch

	// NewBatchWithSize create a new batch for atomic updates, but with pre-allocated size.
	// This will does the same thing as NewBatch if the batch implementation doesn't support pre-allocation.
	NewBatchWithSize(int) Batch

	// For debugging
	Print() error

	// Stats returns a map of property values for all keys and the size of the cache.
	Stats() map[string]string

	// NewSnapshot returns a point-in-time read-only view of the DB.
	// The caller must call Close on the snapshot when done.
	NewSnapshot() (Snapshot, error)
}

DBs are goroutine safe.

func NewDB

func NewDB(name string, backend BackendType, dir string) (DB, error)

NewDB creates a new database of type backend with the given name. NOTE: function panics if:

  • backend is unknown (not registered)
  • creator function, provided during registration, returns error

type ImmutableDB

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

func NewImmutableDB

func NewImmutableDB(db DB) *ImmutableDB

NewImmutableDB wraps a db to make it immutable. ImmutableDB panics on mutation operations.

func (*ImmutableDB) Close

func (idb *ImmutableDB) Close() error

Implements DB.

func (*ImmutableDB) Delete

func (idb *ImmutableDB) Delete(key []byte) error

Implements DB.

func (*ImmutableDB) DeleteSync

func (idb *ImmutableDB) DeleteSync(key []byte) error

Implements DB.

func (*ImmutableDB) Get

func (idb *ImmutableDB) Get(key []byte) ([]byte, error)

Implements DB.

func (*ImmutableDB) Has

func (idb *ImmutableDB) Has(key []byte) (bool, error)

Implements DB.

func (*ImmutableDB) Iterator

func (idb *ImmutableDB) Iterator(start, end []byte) (Iterator, error)

Implements DB.

func (*ImmutableDB) NewBatch

func (idb *ImmutableDB) NewBatch() Batch

Implements DB.

func (*ImmutableDB) NewBatchWithSize

func (idb *ImmutableDB) NewBatchWithSize(_ int) Batch

Implements DB.

func (*ImmutableDB) NewSnapshot

func (idb *ImmutableDB) NewSnapshot() (Snapshot, error)

Implements DB.

func (*ImmutableDB) Print

func (idb *ImmutableDB) Print() error

Implements DB.

func (*ImmutableDB) ReverseIterator

func (idb *ImmutableDB) ReverseIterator(start, end []byte) (Iterator, error)

Implements DB.

func (*ImmutableDB) Set

func (idb *ImmutableDB) Set(key []byte, value []byte) error

Implements DB.

func (*ImmutableDB) SetSync

func (idb *ImmutableDB) SetSync(key []byte, value []byte) error

Implements DB.

func (*ImmutableDB) Stats

func (idb *ImmutableDB) Stats() map[string]string

Implements DB.

type Iterator

type Iterator interface {
	// Domain returns the start (inclusive) and end (exclusive) limits of the iterator.
	Domain() (start, end []byte)

	// Valid returns whether the current iterator is valid. Once invalid, the Iterator remains
	// invalid forever.
	Valid() bool

	// Next moves the iterator to the next key in the database, as defined by order of iteration.
	// If Valid returns false, this method will panic.
	Next()

	// Key returns the key at the current position. Panics if the iterator is invalid.
	// Note, the key returned should be a copy and thus safe for modification.
	Key() []byte

	// Value returns the value at the current position. Panics if the iterator is
	// invalid.
	// Note, the value returned should be a copy and thus safe for modification.
	Value() []byte

	// Error returns the last error encountered by the iterator, if any.
	Error() error

	// Close closes the iterator, releasing any allocated resources.
	Close() error
}

Usage:

var itr Iterator = ... defer itr.Close()

for ; itr.Valid(); itr.Next() {
	k, v := itr.Key(); itr.Value()
	// ...
}

Iterator represents an iterator over a domain of keys. Callers must call Close when done. No writes can happen to a domain while there exists an iterator over it. Some backends may take out database locks to ensure this will not happen.

Callers must make sure the iterator is valid before calling any methods on it, otherwise these methods will panic.

func IteratePrefix

func IteratePrefix(db DB, prefix []byte) Iterator

IteratePrefix is a convenience function for iterating over a key domain restricted by prefix.

type PrefixDB

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

func NewPrefixDB

func NewPrefixDB(db DB, prefix []byte) *PrefixDB

NewPrefixDB lets you namespace multiple DBs within a single DB.

func (*PrefixDB) Close

func (pdb *PrefixDB) Close() error

Implements DB.

func (*PrefixDB) Delete

func (pdb *PrefixDB) Delete(key []byte) error

Implements DB.

func (*PrefixDB) DeleteSync

func (pdb *PrefixDB) DeleteSync(key []byte) error

Implements DB.

func (*PrefixDB) Get

func (pdb *PrefixDB) Get(key []byte) ([]byte, error)

Implements DB.

func (*PrefixDB) Has

func (pdb *PrefixDB) Has(key []byte) (bool, error)

Implements DB.

func (*PrefixDB) Iterator

func (pdb *PrefixDB) Iterator(start, end []byte) (Iterator, error)

Implements DB.

func (*PrefixDB) Mutex

func (pdb *PrefixDB) Mutex() *sync.Mutex

Implements atomicSetDeleter.

func (*PrefixDB) NewBatch

func (pdb *PrefixDB) NewBatch() Batch

Implements DB. Panics if the underlying DB is not an atomicSetDeleter.

func (*PrefixDB) NewBatchWithSize

func (pdb *PrefixDB) NewBatchWithSize(size int) Batch

Implements DB. Panics if the underlying DB is not an atomicSetDeleter.

func (*PrefixDB) NewSnapshot

func (*PrefixDB) NewSnapshot() (Snapshot, error)

func (*PrefixDB) Print

func (pdb *PrefixDB) Print() error

Implements DB.

func (*PrefixDB) ReverseIterator

func (pdb *PrefixDB) ReverseIterator(start, end []byte) (Iterator, error)

Implements DB.

func (*PrefixDB) Set

func (pdb *PrefixDB) Set(key []byte, value []byte) error

Implements DB.

func (*PrefixDB) SetSync

func (pdb *PrefixDB) SetSync(key []byte, value []byte) error

Implements DB.

func (*PrefixDB) Stats

func (pdb *PrefixDB) Stats() map[string]string

Implements DB.

type Snapshot

type Snapshot interface {
	// Get returns nil iff key doesn't exist.
	// A nil key is interpreted as an empty byteslice.
	// CONTRACT: key, value readonly []byte
	Get([]byte) ([]byte, error)

	// Has checks if a key exists.
	// A nil key is interpreted as an empty byteslice.
	// CONTRACT: key, value readonly []byte
	Has(key []byte) (bool, error)

	// Iterate over a domain of keys in ascending order. End is exclusive.
	// Start must be less than end, or the Iterator is invalid.
	// A nil start is interpreted as an empty byteslice.
	// If end is nil, iterates up to the last item (inclusive).
	// CONTRACT: No writes may happen within a domain while an iterator exists over it.
	// CONTRACT: start, end readonly []byte
	Iterator(start, end []byte) (Iterator, error)

	// Iterate over a domain of keys in descending order. End is exclusive.
	// Start must be less than end, or the Iterator is invalid.
	// If start is nil, iterates up to the first/least item (inclusive).
	// If end is nil, iterates from the last/greatest item (inclusive).
	// CONTRACT: No writes may happen within a domain while an iterator exists over it.
	// CONTRACT: start, end readonly []byte
	ReverseIterator(start, end []byte) (Iterator, error)

	// Close releases the resources associated with the snapshot.
	Close() error
}

Snapshot is a read-only, point-in-time view of the DB. Callers must call Close when done to release resources.

type SnapshotDB

type SnapshotDB struct {
	Snapshot
}

SnapshotDB wraps a Snapshot to implement the DB interface. All read operations delegate to the snapshot. Write operations panic. Close is a no-op — the caller owns the snapshot lifecycle.

func NewSnapshotDB

func NewSnapshotDB(snap Snapshot) *SnapshotDB

NewSnapshotDB returns a read-only DB backed by snap.

func (*SnapshotDB) Close

func (s *SnapshotDB) Close() error

func (*SnapshotDB) Delete

func (s *SnapshotDB) Delete([]byte) error

func (*SnapshotDB) DeleteSync

func (s *SnapshotDB) DeleteSync([]byte) error

func (*SnapshotDB) NewBatch

func (s *SnapshotDB) NewBatch() Batch

NewBatch and NewBatchWithSize return a no-op batch. IAVL creates a BatchWithFlusher eagerly in its constructor even for immutable loads, but never commits it when skipFastStorageUpgrade=true. The no-op batch panics on Write/WriteSync to catch any unexpected write attempts.

func (*SnapshotDB) NewBatchWithSize

func (s *SnapshotDB) NewBatchWithSize(int) Batch

func (*SnapshotDB) NewSnapshot

func (s *SnapshotDB) NewSnapshot() (Snapshot, error)

func (*SnapshotDB) Print

func (s *SnapshotDB) Print() error

func (*SnapshotDB) Set

func (s *SnapshotDB) Set([]byte, []byte) error

func (*SnapshotDB) SetSync

func (s *SnapshotDB) SetSync([]byte, []byte) error

func (*SnapshotDB) Stats

func (s *SnapshotDB) Stats() map[string]string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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