cosmos-sdk/types/store.go

265 lines
6.3 KiB
Go

package types
import (
"fmt"
abci "github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
)
// NOTE: These are implemented in cosmos-sdk/store.
type Store interface { //nolint
GetStoreType() StoreType
CacheWrapper
}
// something that can persist to disk
type Committer interface {
Commit() CommitID
LastCommitID() CommitID
}
// Stores of MultiStore must implement CommitStore.
type CommitStore interface {
Committer
Store
}
// Queryable allows a Store to expose internal state to the abci.Query
// interface. Multistore can route requests to the proper Store.
//
// This is an optional, but useful extension to any CommitStore
type Queryable interface {
Query(abci.RequestQuery) abci.ResponseQuery
}
//----------------------------------------
// MultiStore
type MultiStore interface { //nolint
Store
// Cache wrap MultiStore.
// NOTE: Caller should probably not call .Write() on each, but
// call CacheMultiStore.Write().
CacheMultiStore() CacheMultiStore
// Convenience for fetching substores.
GetStore(StoreKey) Store
GetKVStore(StoreKey) KVStore
}
// From MultiStore.CacheMultiStore()....
type CacheMultiStore interface {
MultiStore
Write() // Writes operations to underlying KVStore
}
// A non-cache MultiStore.
type CommitMultiStore interface {
Committer
MultiStore
// Mount a store of type using the given db.
// If db == nil, the new store will use the CommitMultiStore db.
MountStoreWithDB(key StoreKey, typ StoreType, db dbm.DB)
// Panics on a nil key.
GetCommitStore(key StoreKey) CommitStore
// Panics on a nil key.
GetCommitKVStore(key StoreKey) CommitKVStore
// Load the latest persisted version. Called once after all
// calls to Mount*Store() are complete.
LoadLatestVersion() error
// Load a specific persisted version. When you load an old
// version, or when the last commit attempt didn't complete,
// the next commit after loading must be idempotent (return the
// same commit id). Otherwise the behavior is undefined.
LoadVersion(ver int64) error
}
//----------------------------------------
// KVStore
// KVStore is a simple interface to get/set data
type KVStore interface {
Store
// Get returns nil iff key doesn't exist. Panics on nil key.
Get(key []byte) []byte
// Has checks if a key exists. Panics on nil key.
Has(key []byte) bool
// Set sets the key. Panics on nil key.
Set(key, value []byte)
// Delete deletes the key. Panics on nil key.
Delete(key []byte)
// Iterator over a domain of keys in ascending order. End is exclusive.
// Start must be less than end, or the Iterator is invalid.
// CONTRACT: No writes may happen within a domain while an iterator exists over it.
Iterator(start, end []byte) Iterator
// Iterator over a domain of keys in descending order. End is exclusive.
// Start must be greater than end, or the Iterator is invalid.
// CONTRACT: No writes may happen within a domain while an iterator exists over it.
ReverseIterator(start, end []byte) Iterator
// Iterator over all the keys with a certain prefix in ascending order.
// CONTRACT: No writes may happen within a domain while an iterator exists over it.
SubspaceIterator(prefix []byte) Iterator
// Iterator over all the keys with a certain prefix in descending order.
// CONTRACT: No writes may happen within a domain while an iterator exists over it.
ReverseSubspaceIterator(prefix []byte) Iterator
// TODO Not yet implemented.
// CreateSubKVStore(key *storeKey) (KVStore, error)
// TODO Not yet implemented.
// GetSubKVStore(key *storeKey) KVStore
}
// Alias iterator to db's Iterator for convenience.
type Iterator = dbm.Iterator
// CacheKVStore cache-wraps a KVStore. After calling .Write() on
// the CacheKVStore, all previously created CacheKVStores on the
// object expire.
type CacheKVStore interface {
KVStore
// Writes operations to underlying KVStore
Write()
}
// Stores of MultiStore must implement CommitStore.
type CommitKVStore interface {
Committer
KVStore
}
//----------------------------------------
// CacheWrap
/*
CacheWrap() makes the most appropriate cache-wrap. For example,
IAVLStore.CacheWrap() returns a CacheKVStore.
CacheWrap() should not return a Committer, since Commit() on
cache-wraps make no sense. It can return KVStore, HeapStore,
SpaceStore, etc.
*/
type CacheWrap interface {
// Write syncs with the underlying store.
Write()
// CacheWrap recursively wraps again.
CacheWrap() CacheWrap
}
type CacheWrapper interface { //nolint
CacheWrap() CacheWrap
}
//----------------------------------------
// CommitID
// CommitID contains the tree version number and its merkle root.
type CommitID struct {
Version int64
Hash []byte
}
func (cid CommitID) IsZero() bool { //nolint
return cid.Version == 0 && len(cid.Hash) == 0
}
func (cid CommitID) String() string {
return fmt.Sprintf("CommitID{%v:%X}", cid.Hash, cid.Version)
}
//----------------------------------------
// Store types
// kind of store
type StoreType int
const (
//nolint
StoreTypeMulti StoreType = iota
StoreTypeDB
StoreTypeIAVL
)
//----------------------------------------
// Keys for accessing substores
// StoreKey is a key used to index stores in a MultiStore.
type StoreKey interface {
Name() string
String() string
}
// KVStoreKey is used for accessing substores.
// Only the pointer value should ever be used - it functions as a capabilities key.
type KVStoreKey struct {
name string
}
// NewKVStoreKey returns a new pointer to a KVStoreKey.
// Use a pointer so keys don't collide.
func NewKVStoreKey(name string) *KVStoreKey {
return &KVStoreKey{
name: name,
}
}
func (key *KVStoreKey) Name() string {
return key.name
}
func (key *KVStoreKey) String() string {
return fmt.Sprintf("KVStoreKey{%p, %s}", key, key.name)
}
// PrefixEndBytes returns the []byte that would end a
// range query for all []byte with a certain prefix
// Deals with last byte of prefix being FF without overflowing
func PrefixEndBytes(prefix []byte) []byte {
if prefix == nil {
return nil
}
end := make([]byte, len(prefix))
copy(end, prefix)
for {
if end[len(end)-1] != byte(255) {
end[len(end)-1]++
break
} else {
end = end[:len(end)-1]
if len(end) == 0 {
end = nil
break
}
}
}
return end
}
//----------------------------------------
// key-value result for iterator queries
type KVPair cmn.KVPair