Added CommitterLoader for IAVLStore
This commit is contained in:
parent
a2a1151a4f
commit
6a410607b8
|
@ -1,106 +1,106 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
// import (
|
||||
// "encoding/binary"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
)
|
||||
// sdk "github.com/cosmos/cosmos-sdk"
|
||||
// )
|
||||
|
||||
var (
|
||||
headKey = []byte("h")
|
||||
tailKey = []byte("t")
|
||||
dataKey = []byte("d")
|
||||
)
|
||||
// var (
|
||||
// headKey = []byte("h")
|
||||
// tailKey = []byte("t")
|
||||
// dataKey = []byte("d")
|
||||
// )
|
||||
|
||||
// QueueHeadKey gives us the key for the height at head of the queue
|
||||
func QueueHeadKey() []byte {
|
||||
return headKey
|
||||
}
|
||||
// // QueueHeadKey gives us the key for the height at head of the queue
|
||||
// func QueueHeadKey() []byte {
|
||||
// return headKey
|
||||
// }
|
||||
|
||||
// QueueTailKey gives us the key for the height at tail of the queue
|
||||
func QueueTailKey() []byte {
|
||||
return tailKey
|
||||
}
|
||||
// // QueueTailKey gives us the key for the height at tail of the queue
|
||||
// func QueueTailKey() []byte {
|
||||
// return tailKey
|
||||
// }
|
||||
|
||||
// QueueItemKey gives us the key to look up one item by sequence
|
||||
func QueueItemKey(i uint64) []byte {
|
||||
return makeKey(i)
|
||||
}
|
||||
// // QueueItemKey gives us the key to look up one item by sequence
|
||||
// func QueueItemKey(i uint64) []byte {
|
||||
// return makeKey(i)
|
||||
// }
|
||||
|
||||
// Queue allows us to fill up a range of the db, and grab from either end
|
||||
type Queue struct {
|
||||
store sdk.KVStore
|
||||
head uint64 // if Size() > 0, the first element is here
|
||||
tail uint64 // this is the first empty slot to Push() to
|
||||
}
|
||||
// // Queue allows us to fill up a range of the db, and grab from either end
|
||||
// type Queue struct {
|
||||
// store sdk.KVStore
|
||||
// head uint64 // if Size() > 0, the first element is here
|
||||
// tail uint64 // this is the first empty slot to Push() to
|
||||
// }
|
||||
|
||||
// NewQueue will load or initialize a queue in this state-space
|
||||
//
|
||||
// Generally, you will want to stack.PrefixStore() the space first
|
||||
func NewQueue(store sdk.KVStore) *Queue {
|
||||
q := &Queue{store: store}
|
||||
q.head = q.getCount(headKey)
|
||||
q.tail = q.getCount(tailKey)
|
||||
return q
|
||||
}
|
||||
// // NewQueue will load or initialize a queue in this state-space
|
||||
// //
|
||||
// // Generally, you will want to stack.PrefixStore() the space first
|
||||
// func NewQueue(store sdk.KVStore) *Queue {
|
||||
// q := &Queue{store: store}
|
||||
// q.head = q.getCount(headKey)
|
||||
// q.tail = q.getCount(tailKey)
|
||||
// return q
|
||||
// }
|
||||
|
||||
// Tail returns the next slot that Push() will use
|
||||
func (q *Queue) Tail() uint64 {
|
||||
return q.tail
|
||||
}
|
||||
// // Tail returns the next slot that Push() will use
|
||||
// func (q *Queue) Tail() uint64 {
|
||||
// return q.tail
|
||||
// }
|
||||
|
||||
// Size returns how many elements are in the queue
|
||||
func (q *Queue) Size() int {
|
||||
return int(q.tail - q.head)
|
||||
}
|
||||
// // Size returns how many elements are in the queue
|
||||
// func (q *Queue) Size() int {
|
||||
// return int(q.tail - q.head)
|
||||
// }
|
||||
|
||||
// Push adds an element to the tail of the queue and returns it's location
|
||||
func (q *Queue) Push(value []byte) uint64 {
|
||||
key := makeKey(q.tail)
|
||||
q.store.Set(key, value)
|
||||
q.tail++
|
||||
q.setCount(tailKey, q.tail)
|
||||
return q.tail - 1
|
||||
}
|
||||
// // Push adds an element to the tail of the queue and returns it's location
|
||||
// func (q *Queue) Push(value []byte) uint64 {
|
||||
// key := makeKey(q.tail)
|
||||
// q.store.Set(key, value)
|
||||
// q.tail++
|
||||
// q.setCount(tailKey, q.tail)
|
||||
// return q.tail - 1
|
||||
// }
|
||||
|
||||
// Pop gets an element from the end of the queue
|
||||
func (q *Queue) Pop() []byte {
|
||||
if q.Size() <= 0 {
|
||||
return nil
|
||||
}
|
||||
key := makeKey(q.head)
|
||||
value := q.store.Get(key)
|
||||
q.head++
|
||||
q.setCount(headKey, q.head)
|
||||
return value
|
||||
}
|
||||
// // Pop gets an element from the end of the queue
|
||||
// func (q *Queue) Pop() []byte {
|
||||
// if q.Size() <= 0 {
|
||||
// return nil
|
||||
// }
|
||||
// key := makeKey(q.head)
|
||||
// value := q.store.Get(key)
|
||||
// q.head++
|
||||
// q.setCount(headKey, q.head)
|
||||
// return value
|
||||
// }
|
||||
|
||||
// Item looks at any element in the queue, without modifying anything
|
||||
func (q *Queue) Item(seq uint64) []byte {
|
||||
if seq >= q.tail || seq < q.head {
|
||||
return nil
|
||||
}
|
||||
return q.store.Get(makeKey(seq))
|
||||
}
|
||||
// // Item looks at any element in the queue, without modifying anything
|
||||
// func (q *Queue) Item(seq uint64) []byte {
|
||||
// if seq >= q.tail || seq < q.head {
|
||||
// return nil
|
||||
// }
|
||||
// return q.store.Get(makeKey(seq))
|
||||
// }
|
||||
|
||||
func (q *Queue) setCount(key []byte, val uint64) {
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, val)
|
||||
q.store.Set(key, b)
|
||||
}
|
||||
// func (q *Queue) setCount(key []byte, val uint64) {
|
||||
// b := make([]byte, 8)
|
||||
// binary.BigEndian.PutUint64(b, val)
|
||||
// q.store.Set(key, b)
|
||||
// }
|
||||
|
||||
func (q *Queue) getCount(key []byte) (val uint64) {
|
||||
b := q.store.Get(key)
|
||||
if b != nil {
|
||||
val = binary.BigEndian.Uint64(b)
|
||||
}
|
||||
return val
|
||||
}
|
||||
// func (q *Queue) getCount(key []byte) (val uint64) {
|
||||
// b := q.store.Get(key)
|
||||
// if b != nil {
|
||||
// val = binary.BigEndian.Uint64(b)
|
||||
// }
|
||||
// return val
|
||||
// }
|
||||
|
||||
// makeKey returns the key for a data point
|
||||
func makeKey(val uint64) []byte {
|
||||
b := make([]byte, 8+len(dataKey))
|
||||
copy(b, dataKey)
|
||||
binary.BigEndian.PutUint64(b[len(dataKey):], val)
|
||||
return b
|
||||
}
|
||||
// // makeKey returns the key for a data point
|
||||
// func makeKey(val uint64) []byte {
|
||||
// b := make([]byte, 8+len(dataKey))
|
||||
// copy(b, dataKey)
|
||||
// binary.BigEndian.PutUint64(b[len(dataKey):], val)
|
||||
// return b
|
||||
// }
|
||||
|
|
|
@ -1,47 +1,112 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/tendermint/iavl"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
)
|
||||
|
||||
// Implements IterKVStore
|
||||
// NewIAVLLoader returns a CommitterLoader that returns
|
||||
// an IAVLStore
|
||||
func NewIAVLLoader(dbName string, cacheSize int, history uint64) CommitterLoader {
|
||||
l := iavlLoader{
|
||||
dbName: dbName,
|
||||
cacheSize: cacheSize,
|
||||
history: history,
|
||||
}
|
||||
return CommitterLoader(l.Load)
|
||||
}
|
||||
|
||||
// IAVLStore Implements IterKVStore and Committer
|
||||
type IAVLStore struct {
|
||||
//
|
||||
// we must store the last height here, as it is needed
|
||||
// for saving the versioned tree
|
||||
lastHeight uint64
|
||||
|
||||
// history is how many old versions we hold onto,
|
||||
// uses a naive "hold last X versions" algorithm
|
||||
history uint64
|
||||
|
||||
tree *iavl.VersionedTree
|
||||
}
|
||||
|
||||
// XXX
|
||||
func NewIAVLStore() {
|
||||
// Commit writes another version to the
|
||||
func (i *IAVLStore) Commit() CommitID {
|
||||
// save a new version
|
||||
i.lastHeight++
|
||||
hash, err := i.tree.SaveVersion(i.lastHeight)
|
||||
if err != nil {
|
||||
// TODO: do we want to extend Commit to
|
||||
// allow returning errors?
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// release an old version
|
||||
if i.history <= i.lastHeight {
|
||||
release := i.lastHeight - i.history
|
||||
i.tree.DeleteVersion(release)
|
||||
}
|
||||
|
||||
return CommitID{
|
||||
Version: i.lastHeight,
|
||||
Hash: hash,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// XXX GUT THIS AND TURN IT INTO AN IAVLSTORE LOADER, LoadIAVLStore()
|
||||
func loadState(dbName string, cacheSize int) (*sm.State, error) {
|
||||
// var _ IterKVStore = (*IAVLStore)(nil)
|
||||
var _ KVStore = (*IAVLStore)(nil)
|
||||
var _ Committer = (*IAVLStore)(nil)
|
||||
|
||||
// iavlLoader contains info on what store we want to load from
|
||||
type iavlLoader struct {
|
||||
dbName string
|
||||
cacheSize int
|
||||
history uint64
|
||||
}
|
||||
|
||||
// Load implements CommitLoader type
|
||||
func (l iavlLoader) Load(id CommitID) (Committer, error) {
|
||||
// memory backed case, just for testing
|
||||
if dbName == "" {
|
||||
if l.dbName == "" {
|
||||
tree := iavl.NewVersionedTree(0, dbm.NewMemDB())
|
||||
return sm.NewState(tree), nil
|
||||
store := &IAVLStore{
|
||||
tree: tree,
|
||||
history: l.history,
|
||||
}
|
||||
return store, nil
|
||||
}
|
||||
|
||||
// Expand the path fully
|
||||
dbPath, err := filepath.Abs(dbName)
|
||||
dbPath, err := filepath.Abs(l.dbName)
|
||||
if err != nil {
|
||||
return nil, errors.ErrInternal("Invalid Database Name")
|
||||
return nil, errors.New("Invalid Database Name")
|
||||
}
|
||||
|
||||
// Some external calls accidently add a ".db", which is now removed
|
||||
dbPath = strings.TrimSuffix(dbPath, path.Ext(dbPath))
|
||||
|
||||
// Split the database name into it's components (dir, name)
|
||||
dir := path.Dir(dbPath)
|
||||
name := path.Base(dbPath)
|
||||
dir := filepath.Dir(dbPath)
|
||||
name := filepath.Base(dbPath)
|
||||
|
||||
// Open database called "dir/name.db", if it doesn't exist it will be created
|
||||
db := dbm.NewDB(name, dbm.LevelDBBackendStr, dir)
|
||||
tree := iavl.NewVersionedTree(cacheSize, db)
|
||||
tree := iavl.NewVersionedTree(l.cacheSize, db)
|
||||
if err = tree.Load(); err != nil {
|
||||
return nil, errors.ErrInternal("Loading tree: " + err.Error())
|
||||
return nil, errors.New("Loading tree: " + err.Error())
|
||||
}
|
||||
|
||||
return sm.NewState(tree), nil
|
||||
// TODO: load the version stored in id
|
||||
store := &IAVLStore{
|
||||
tree: tree,
|
||||
lastHeight: tree.LatestVersion(),
|
||||
history: l.history,
|
||||
}
|
||||
|
||||
return store, nil
|
||||
}
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue