Browse Source

TypedTree.

pull/9/head
Jae Kwon 10 years ago
parent
commit
8facbdf809
3 changed files with 121 additions and 8 deletions
  1. +45
    -0
      merkle/iavl_test.go
  2. +73
    -5
      merkle/iavl_tree.go
  3. +3
    -3
      merkle/types.go

+ 45
- 0
merkle/iavl_test.go View File

@ -4,7 +4,9 @@ import (
"bytes"
"crypto/sha256"
"fmt"
"time"
. "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
"github.com/tendermint/tendermint/db"
@ -232,6 +234,49 @@ func TestPersistence(t *testing.T) {
}
}
func TestTypedTree(t *testing.T) {
db := db.NewMemDB()
// Construct some tree and save it
t1 := NewTypedTree(NewIAVLTree(db), BasicCodec, BasicCodec)
t1.Set(uint8(1), "uint8(1)")
t1.Set(uint16(1), "uint16(1)")
t1.Set(uint32(1), "uint32(1)")
t1.Set(uint64(1), "uint64(1)")
t1.Set("byteslice01", []byte{byte(0x00), byte(0x01)})
t1.Set("byteslice23", []byte{byte(0x02), byte(0x03)})
t1.Set("time", time.Unix(123, 0))
t1.Set("nil", nil)
t1Hash := t1.Tree.Save()
// Reconstruct tree
t2 := NewTypedTree(LoadIAVLTreeFromHash(db, t1Hash), BasicCodec, BasicCodec)
if t2.Get(uint8(1)).(string) != "uint8(1)" {
t.Errorf("Expected string uint8(1)")
}
if t2.Get(uint16(1)).(string) != "uint16(1)" {
t.Errorf("Expected string uint16(1)")
}
if t2.Get(uint32(1)).(string) != "uint32(1)" {
t.Errorf("Expected string uint32(1)")
}
if t2.Get(uint64(1)).(string) != "uint64(1)" {
t.Errorf("Expected string uint64(1)")
}
if !bytes.Equal(t2.Get("byteslice01").([]byte), []byte{byte(0x00), byte(0x01)}) {
t.Errorf("Expected byteslice 0x00 0x01")
}
if !bytes.Equal(t2.Get("byteslice23").([]byte), []byte{byte(0x02), byte(0x03)}) {
t.Errorf("Expected byteslice 0x02 0x03")
}
if t2.Get("time").(time.Time).Unix() != 123 {
t.Errorf("Expected time 123")
}
if t2.Get("nil") != nil {
t.Errorf("Expected nil")
}
}
func BenchmarkHash(b *testing.B) {
b.StopTimer()


+ 73
- 5
merkle/iavl_tree.go View File

@ -3,12 +3,12 @@ package merkle
import (
"bytes"
"container/list"
. "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
)
const defaultCacheCapacity = 1000 // TODO make configurable.
// XXX Make Codec tree.
/*
Immutable AVL Tree (wraps the Node root)
@ -81,11 +81,11 @@ func (t *IAVLTree) HashWithCount() ([]byte, uint64) {
return t.root.HashWithCount()
}
func (t *IAVLTree) Save() {
func (t *IAVLTree) Save() []byte {
if t.root == nil {
return
return nil
}
t.root.Save(t.ndb)
return t.root.Save(t.ndb)
}
func (t *IAVLTree) Get(key []byte) (value []byte) {
@ -117,6 +117,74 @@ func (t *IAVLTree) Copy() Tree {
//-----------------------------------------------------------------------------
type TypedTree struct {
Tree Tree
keyCodec Codec
valueCodec Codec
}
func NewTypedTree(tree Tree, keyCodec, valueCodec Codec) *TypedTree {
return &TypedTree{
Tree: tree,
keyCodec: keyCodec,
valueCodec: valueCodec,
}
}
func (t *TypedTree) Has(key interface{}) bool {
bytes, err := t.keyCodec.Write(key)
if err != nil {
Panicf("Error from keyCodec: %v", err)
}
return t.Tree.Has(bytes)
}
func (t *TypedTree) Get(key interface{}) interface{} {
keyBytes, err := t.keyCodec.Write(key)
if err != nil {
Panicf("Error from keyCodec: %v", err)
}
valueBytes := t.Tree.Get(keyBytes)
if valueBytes == nil {
return nil
}
value, err := t.valueCodec.Read(valueBytes)
if err != nil {
Panicf("Error from valueCodec: %v", err)
}
return value
}
func (t *TypedTree) Set(key interface{}, value interface{}) bool {
keyBytes, err := t.keyCodec.Write(key)
if err != nil {
Panicf("Error from keyCodec: %v", err)
}
valueBytes, err := t.valueCodec.Write(value)
if err != nil {
Panicf("Error from valueCodec: %v", err)
}
return t.Tree.Set(keyBytes, valueBytes)
}
func (t *TypedTree) Remove(key interface{}) (interface{}, error) {
keyBytes, err := t.keyCodec.Write(key)
if err != nil {
Panicf("Error from keyCodec: %v", err)
}
valueBytes, err := t.Tree.Remove(keyBytes)
if valueBytes == nil {
return nil, err
}
value, err_ := t.valueCodec.Read(valueBytes)
if err_ != nil {
Panicf("Error from valueCodec: %v", err)
}
return value, err
}
//-----------------------------------------------------------------------------
type nodeElement struct {
node *IAVLNode
elem *list.Element


+ 3
- 3
merkle/types.go View File

@ -14,11 +14,11 @@ type Tree interface {
Height() uint8
Has(key []byte) bool
Get(key []byte) []byte
Set(key []byte, value []byte) bool
Remove(key []byte) ([]byte, error)
HashWithCount() ([]byte, uint64)
Hash() []byte
Save()
Set(key []byte, vlaue []byte) bool
Remove(key []byte) ([]byte, error)
Save() []byte
Copy() Tree
}


Loading…
Cancel
Save