2017-10-31 13:45:57 -07:00
|
|
|
package store
|
|
|
|
|
|
|
|
import (
|
2017-12-12 22:17:20 -08:00
|
|
|
"bytes"
|
|
|
|
|
2017-10-31 13:45:57 -07:00
|
|
|
"github.com/tendermint/go-wire/data"
|
2017-12-12 20:13:51 -08:00
|
|
|
"github.com/tendermint/tmlibs/db"
|
2017-10-31 13:45:57 -07:00
|
|
|
)
|
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
//----------------------------------------
|
|
|
|
// MultiStore
|
2017-10-31 13:45:57 -07:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
type MultiStore interface {
|
2017-10-31 13:45:57 -07:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
// Last commit, or the zero CommitID.
|
|
|
|
// If not zero, CommitID.Version is CurrentVersion()-1.
|
|
|
|
LastCommitID() CommitID
|
2017-10-31 13:45:57 -07:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
// Current version being worked on now, not yet committed.
|
|
|
|
// Should be greater than 0.
|
|
|
|
CurrentVersion() int64
|
2017-11-30 07:05:06 -08:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
// Cache wrap MultiStore.
|
|
|
|
// NOTE: Caller should probably not call .Write() on each, but
|
|
|
|
// call CacheMultiStore.Write().
|
|
|
|
CacheMultiStore() CacheMultiStore
|
2017-11-30 07:05:06 -08:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
// Convenience
|
|
|
|
GetStore(name string) interface{}
|
|
|
|
GetKVStore(name string) KVStore
|
2017-11-30 07:05:06 -08:00
|
|
|
}
|
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
type CacheMultiStore interface {
|
|
|
|
MultiStore
|
|
|
|
Write() // Writes operations to underlying KVStore
|
2017-12-03 22:55:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
type CommitStore interface {
|
|
|
|
Committer
|
|
|
|
CacheWrapper
|
|
|
|
}
|
|
|
|
|
|
|
|
type CommitStoreLoader func(id CommitID) (CommitStore, error)
|
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
type Committer interface {
|
|
|
|
// Commit persists the state to disk.
|
|
|
|
Commit() CommitID
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
|
// KVStore
|
|
|
|
|
2017-10-31 13:45:57 -07:00
|
|
|
// KVStore is a simple interface to get/set data
|
|
|
|
type KVStore interface {
|
2017-12-11 23:30:44 -08:00
|
|
|
|
|
|
|
// 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
|
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
// Set sets the key. Panics on nil key.
|
|
|
|
Set(key, value []byte)
|
|
|
|
|
|
|
|
// Delete deletes the key. Panics on nil key.
|
|
|
|
Delete(key []byte)
|
2017-12-01 09:24:02 -08:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
// 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
|
2017-12-03 22:55:15 -08:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
// 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
|
2017-12-01 09:24:02 -08:00
|
|
|
}
|
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
// db.DB implements KVStore so we can CacheKVStore it.
|
|
|
|
var _ KVStore = db.DB(nil)
|
|
|
|
|
|
|
|
// Alias iterator to db's Iterator for convenience.
|
|
|
|
type Iterator = db.Iterator
|
|
|
|
|
|
|
|
// CacheKVStore cache-wraps a KVStore. After calling .Write() on the
|
|
|
|
// CacheKVStore, all previously created CacheKVStores on the object expire.
|
2017-12-01 09:24:02 -08:00
|
|
|
type CacheKVStore interface {
|
|
|
|
KVStore
|
|
|
|
Write() // Writes operations to underlying KVStore
|
2017-10-31 13:45:57 -07:00
|
|
|
}
|
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
//----------------------------------------
|
|
|
|
// CacheWrap
|
2017-10-31 13:45:57 -07:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
/*
|
|
|
|
CacheWrap() makes the most appropriate cache-wrap. For example,
|
|
|
|
IAVLStore.CacheWrap() returns a CacheKVStore.
|
2017-10-31 13:45:57 -07:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
CacheWrap() should not return a Committer, since Commit() on
|
|
|
|
cache-wraps make no sense. It can return KVStore, HeapStore,
|
|
|
|
SpaceStore, etc.
|
|
|
|
*/
|
|
|
|
type CacheWrapper interface {
|
|
|
|
CacheWrap() CacheWrap
|
|
|
|
}
|
2017-12-10 00:24:55 -08:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
type CacheWrap interface {
|
2017-12-01 09:24:02 -08:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
// Write syncs with the underlying store.
|
|
|
|
Write()
|
2017-12-03 22:55:15 -08:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
// CacheWrap recursively wraps again.
|
|
|
|
CacheWrap() CacheWrap
|
2017-12-01 09:24:02 -08:00
|
|
|
}
|
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
//----------------------------------------
|
|
|
|
// etc
|
2017-10-31 13:45:57 -07:00
|
|
|
|
|
|
|
type KVPair struct {
|
|
|
|
Key data.Bytes
|
|
|
|
Value data.Bytes
|
|
|
|
}
|
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
// CommitID contains the tree version number and its merkle root.
|
|
|
|
type CommitID struct {
|
|
|
|
Version int64
|
|
|
|
Hash []byte
|
2017-12-03 22:55:15 -08:00
|
|
|
}
|
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
func (cid CommitID) IsZero() bool {
|
|
|
|
return cid.Version == 0 && len(cid.Hash) == 0
|
2017-12-03 22:55:15 -08:00
|
|
|
}
|
2017-12-12 22:17:20 -08:00
|
|
|
|
|
|
|
// bytes.Compare but bounded on both sides by nil.
|
|
|
|
// both (k1, nil) and (nil, k2) return -1
|
|
|
|
func keyCompare(k1, k2 []byte) int {
|
|
|
|
if k1 == nil && k2 == nil {
|
|
|
|
return 0
|
|
|
|
} else if k1 == nil || k2 == nil {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
return bytes.Compare(k1, k2)
|
|
|
|
}
|