mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 06:42:16 +00:00
.
This commit is contained in:
parent
795e183273
commit
19726afc96
130
merkle/iavl.go
130
merkle/iavl.go
@ -2,7 +2,8 @@ package merkle
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
//"fmt"
|
//"fmt"
|
||||||
"hash"
|
"math"
|
||||||
|
//"hash"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,20 +25,24 @@ func (self *IAVLTree) Size() int {
|
|||||||
return self.root.Size()
|
return self.root.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *IAVLTree) Has(key Sortable) bool {
|
func (self *IAVLTree) Has(key Key) bool {
|
||||||
return self.root.Has(key)
|
return self.root.Has(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *IAVLTree) Put(key Sortable, value interface{}) (err error) {
|
func (self *IAVLTree) Put(key Key, value Value) (err error) {
|
||||||
self.root, _ = self.root.Put(key, value)
|
self.root, _ = self.root.Put(key, value)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *IAVLTree) Get(key Sortable) (value interface{}, err error) {
|
func (self *IAVLTree) Hash() []byte {
|
||||||
|
return self.root.Hash()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *IAVLTree) Get(key Key) (value Value, err error) {
|
||||||
return self.root.Get(key)
|
return self.root.Get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *IAVLTree) Remove(key Sortable) (value interface{}, err error) {
|
func (self *IAVLTree) Remove(key Key) (value Value, err error) {
|
||||||
new_root, value, err := self.root.Remove(key)
|
new_root, value, err := self.root.Remove(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -49,8 +54,8 @@ func (self *IAVLTree) Remove(key Sortable) (value interface{}, err error) {
|
|||||||
// Node
|
// Node
|
||||||
|
|
||||||
type IAVLNode struct {
|
type IAVLNode struct {
|
||||||
key Sortable
|
key Key
|
||||||
value interface{}
|
value Value
|
||||||
height int
|
height int
|
||||||
hash []byte
|
hash []byte
|
||||||
left *IAVLNode
|
left *IAVLNode
|
||||||
@ -75,7 +80,32 @@ func (self *IAVLNode) Copy(copyHash bool) *IAVLNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *IAVLNode) Has(key Sortable) (has bool) {
|
func (self *IAVLNode) Key() Key {
|
||||||
|
return self.key
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *IAVLNode) Value() Value {
|
||||||
|
return self.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *IAVLNode) Left() Node {
|
||||||
|
if self.left == nil { return nil }
|
||||||
|
return self.left
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *IAVLNode) Right() Node {
|
||||||
|
if self.right == nil { return nil }
|
||||||
|
return self.right
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *IAVLNode) Size() int {
|
||||||
|
if self == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1 + self.left.Size() + self.right.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *IAVLNode) Has(key Key) (has bool) {
|
||||||
if self == nil {
|
if self == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -88,7 +118,7 @@ func (self *IAVLNode) Has(key Sortable) (has bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *IAVLNode) Get(key Sortable) (value interface{}, err error) {
|
func (self *IAVLNode) Get(key Key) (value Value, err error) {
|
||||||
if self == nil {
|
if self == nil {
|
||||||
return nil, NotFound(key)
|
return nil, NotFound(key)
|
||||||
}
|
}
|
||||||
@ -101,6 +131,47 @@ func (self *IAVLNode) Get(key Sortable) (value interface{}, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *IAVLNode) Hash() []byte {
|
||||||
|
if self == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if self.hash != nil { return self.hash }
|
||||||
|
hasher := sha256.New()
|
||||||
|
|
||||||
|
// node descriptor
|
||||||
|
nodeDesc := byte(0)
|
||||||
|
if self.value != nil { nodeDesc |= 0x01 }
|
||||||
|
if self.left != nil { nodeDesc |= 0x02 }
|
||||||
|
if self.right != nil { nodeDesc |= 0x04 }
|
||||||
|
hasher.Write([]byte{nodeDesc})
|
||||||
|
|
||||||
|
// node key
|
||||||
|
keyBytes := self.key.Bytes()
|
||||||
|
if len(keyBytes) > 255 { panic("key is too long") }
|
||||||
|
hasher.Write([]byte{byte(len(keyBytes))})
|
||||||
|
hasher.Write(keyBytes)
|
||||||
|
|
||||||
|
// node value
|
||||||
|
if self.value != nil {
|
||||||
|
valueBytes := self.value.Bytes()
|
||||||
|
if len(valueBytes) > math.MaxUint32 { panic("value is too long") }
|
||||||
|
hasher.Write([]byte{byte(len(valueBytes))})
|
||||||
|
hasher.Write(valueBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// left child
|
||||||
|
if self.left != nil {
|
||||||
|
hasher.Write(self.left.Hash())
|
||||||
|
}
|
||||||
|
|
||||||
|
// right child
|
||||||
|
if self.right != nil {
|
||||||
|
hasher.Write(self.right.Hash())
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasher.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
// Returns a new tree (unless node is the root) & a copy of the popped node.
|
// Returns a new tree (unless node is the root) & a copy of the popped node.
|
||||||
// Can only pop nodes that have one or no children.
|
// Can only pop nodes that have one or no children.
|
||||||
func (self *IAVLNode) pop_node(node *IAVLNode) (new_self, new_node *IAVLNode) {
|
func (self *IAVLNode) pop_node(node *IAVLNode) (new_self, new_node *IAVLNode) {
|
||||||
@ -231,7 +302,7 @@ func (self *IAVLNode) balance() (new_self *IAVLNode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: don't clear the hash if the value hasn't changed.
|
// TODO: don't clear the hash if the value hasn't changed.
|
||||||
func (self *IAVLNode) Put(key Sortable, value interface{}) (_ *IAVLNode, updated bool) {
|
func (self *IAVLNode) Put(key Key, value Value) (_ *IAVLNode, updated bool) {
|
||||||
if self == nil {
|
if self == nil {
|
||||||
return &IAVLNode{key: key, value: value, height: 1, hash: nil}, false
|
return &IAVLNode{key: key, value: value, height: 1, hash: nil}, false
|
||||||
}
|
}
|
||||||
@ -256,7 +327,7 @@ func (self *IAVLNode) Put(key Sortable, value interface{}) (_ *IAVLNode, updated
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *IAVLNode) Remove(key Sortable) (new_self *IAVLNode, value interface{}, err error) {
|
func (self *IAVLNode) Remove(key Key) (new_self *IAVLNode, value Value, err error) {
|
||||||
if self == nil {
|
if self == nil {
|
||||||
return nil, nil, NotFound(key)
|
return nil, nil, NotFound(key)
|
||||||
}
|
}
|
||||||
@ -318,32 +389,6 @@ func (self *IAVLNode) Height() int {
|
|||||||
return self.height
|
return self.height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *IAVLNode) Size() int {
|
|
||||||
if self == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return 1 + self.left.Size() + self.right.Size()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func (self *IAVLNode) Key() Sortable {
|
|
||||||
return self.key
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *IAVLNode) Value() interface{} {
|
|
||||||
return self.value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *IAVLNode) Left() Node {
|
|
||||||
if self.left == nil { return nil }
|
|
||||||
return self.left
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *IAVLNode) Right() Node {
|
|
||||||
if self.right == nil { return nil }
|
|
||||||
return self.right
|
|
||||||
}
|
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
func (self *IAVLNode) _md(side func(*IAVLNode)*IAVLNode) (*IAVLNode) {
|
func (self *IAVLNode) _md(side func(*IAVLNode)*IAVLNode) (*IAVLNode) {
|
||||||
@ -377,14 +422,3 @@ func max(a, b int) int {
|
|||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the hash of hasher over buf.
|
|
||||||
func CalcHash(buf []byte, hasher hash.Hash) []byte {
|
|
||||||
hasher.Write(buf)
|
|
||||||
return hasher.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate hash256 which is sha256(sha256(data))
|
|
||||||
func CalcSha256(buf []byte) []byte {
|
|
||||||
return CalcHash(buf, sha256.New())
|
|
||||||
}
|
|
||||||
|
@ -50,7 +50,7 @@ func TestImmutableAvlPutHasGetRemove(t *testing.T) {
|
|||||||
records := make([]*record, 400)
|
records := make([]*record, 400)
|
||||||
var tree *IAVLNode
|
var tree *IAVLNode
|
||||||
var err error
|
var err error
|
||||||
var val interface{}
|
var val Value
|
||||||
var updated bool
|
var updated bool
|
||||||
|
|
||||||
ranrec := func() *record {
|
ranrec := func() *record {
|
||||||
@ -155,7 +155,7 @@ func TestTraversals(t *testing.T) {
|
|||||||
test := func(T Tree) {
|
test := func(T Tree) {
|
||||||
t.Logf("%T", T)
|
t.Logf("%T", T)
|
||||||
for j := range order {
|
for j := range order {
|
||||||
if err := T.Put(Int(data[order[j]]), order[j]); err != nil {
|
if err := T.Put(Int(data[order[j]]), Int(order[j])); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,28 +174,17 @@ func TestTraversals(t *testing.T) {
|
|||||||
test(NewIAVLTree())
|
test(NewIAVLTree())
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkSha256(b *testing.B) {
|
|
||||||
b.StopTimer()
|
|
||||||
|
|
||||||
str := []byte(randstr(32))
|
|
||||||
|
|
||||||
ransha256 := func() []byte {
|
|
||||||
return CalcSha256(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.StartTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
ransha256()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// from http://stackoverflow.com/questions/3955680/how-to-check-if-my-avl-tree-implementation-is-correct
|
// from http://stackoverflow.com/questions/3955680/how-to-check-if-my-avl-tree-implementation-is-correct
|
||||||
func TestGriffin(t *testing.T) {
|
func TestGriffin(t *testing.T) {
|
||||||
|
|
||||||
|
// Convenience for a new node
|
||||||
N := func(l *IAVLNode, i int, r *IAVLNode) *IAVLNode {
|
N := func(l *IAVLNode, i int, r *IAVLNode) *IAVLNode {
|
||||||
n := &IAVLNode{Int32(i), nil, -1, nil, l, r}
|
n := &IAVLNode{Int32(i), nil, -1, nil, l, r}
|
||||||
n.calc_height()
|
n.calc_height()
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convenience for simple printing of keys & tree structure
|
||||||
var P func(*IAVLNode) string
|
var P func(*IAVLNode) string
|
||||||
P = func(n *IAVLNode) string {
|
P = func(n *IAVLNode) string {
|
||||||
if n.left == nil && n.right == nil {
|
if n.left == nil && n.right == nil {
|
||||||
@ -273,3 +262,17 @@ func TestGriffin(t *testing.T) {
|
|||||||
expectRemove(n6, 1, "(((2 3 4) 5 (6 7 -)) 8 (9 10 (- 11 12)))")
|
expectRemove(n6, 1, "(((2 3 4) 5 (6 7 -)) 8 (9 10 (- 11 12)))")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHash(t *testing.T) {
|
||||||
|
|
||||||
|
// Maybe, construct some tree & determine the number of new hashes calculated.
|
||||||
|
// Make sure the number of new hashings is expected, as well as the hash value.
|
||||||
|
// Then, nuke the hash values and reconstruct, ensure that the resulting hash is the same.
|
||||||
|
|
||||||
|
tree := NewIAVLTree()
|
||||||
|
tree.Put(String("foo"), String("bar"))
|
||||||
|
fmt.Println(tree.Hash())
|
||||||
|
|
||||||
|
tree.Put(String("foo2"), String("bar"))
|
||||||
|
fmt.Println(tree.Hash())
|
||||||
|
}
|
||||||
|
101
merkle/int.go
101
merkle/int.go
@ -1,5 +1,8 @@
|
|||||||
package merkle
|
package merkle
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
)
|
||||||
|
|
||||||
type Int8 int8
|
type Int8 int8
|
||||||
type UInt8 uint8
|
type UInt8 uint8
|
||||||
@ -13,7 +16,7 @@ type Int int
|
|||||||
type UInt uint
|
type UInt uint
|
||||||
|
|
||||||
|
|
||||||
func (self Int8) Equals(other Sortable) bool {
|
func (self Int8) Equals(other Key) bool {
|
||||||
if o, ok := other.(Int8); ok {
|
if o, ok := other.(Int8); ok {
|
||||||
return self == o
|
return self == o
|
||||||
} else {
|
} else {
|
||||||
@ -21,7 +24,7 @@ func (self Int8) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Int8) Less(other Sortable) bool {
|
func (self Int8) Less(other Key) bool {
|
||||||
if o, ok := other.(Int8); ok {
|
if o, ok := other.(Int8); ok {
|
||||||
return self < o
|
return self < o
|
||||||
} else {
|
} else {
|
||||||
@ -29,12 +32,12 @@ func (self Int8) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Int8) Hash() int {
|
func (self Int8) Bytes() []byte {
|
||||||
return int(self)
|
return []byte{byte(self)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (self UInt8) Equals(other Sortable) bool {
|
func (self UInt8) Equals(other Key) bool {
|
||||||
if o, ok := other.(UInt8); ok {
|
if o, ok := other.(UInt8); ok {
|
||||||
return self == o
|
return self == o
|
||||||
} else {
|
} else {
|
||||||
@ -42,7 +45,7 @@ func (self UInt8) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self UInt8) Less(other Sortable) bool {
|
func (self UInt8) Less(other Key) bool {
|
||||||
if o, ok := other.(UInt8); ok {
|
if o, ok := other.(UInt8); ok {
|
||||||
return self < o
|
return self < o
|
||||||
} else {
|
} else {
|
||||||
@ -50,12 +53,12 @@ func (self UInt8) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self UInt8) Hash() int {
|
func (self UInt8) Bytes() []byte {
|
||||||
return int(self)
|
return []byte{byte(self)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (self Int16) Equals(other Sortable) bool {
|
func (self Int16) Equals(other Key) bool {
|
||||||
if o, ok := other.(Int16); ok {
|
if o, ok := other.(Int16); ok {
|
||||||
return self == o
|
return self == o
|
||||||
} else {
|
} else {
|
||||||
@ -63,7 +66,7 @@ func (self Int16) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Int16) Less(other Sortable) bool {
|
func (self Int16) Less(other Key) bool {
|
||||||
if o, ok := other.(Int16); ok {
|
if o, ok := other.(Int16); ok {
|
||||||
return self < o
|
return self < o
|
||||||
} else {
|
} else {
|
||||||
@ -71,12 +74,14 @@ func (self Int16) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Int16) Hash() int {
|
func (self Int16) Bytes() []byte {
|
||||||
return int(self)
|
b := [2]byte{}
|
||||||
|
binary.LittleEndian.PutUint16(b[:], uint16(self))
|
||||||
|
return b[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (self UInt16) Equals(other Sortable) bool {
|
func (self UInt16) Equals(other Key) bool {
|
||||||
if o, ok := other.(UInt16); ok {
|
if o, ok := other.(UInt16); ok {
|
||||||
return self == o
|
return self == o
|
||||||
} else {
|
} else {
|
||||||
@ -84,7 +89,7 @@ func (self UInt16) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self UInt16) Less(other Sortable) bool {
|
func (self UInt16) Less(other Key) bool {
|
||||||
if o, ok := other.(UInt16); ok {
|
if o, ok := other.(UInt16); ok {
|
||||||
return self < o
|
return self < o
|
||||||
} else {
|
} else {
|
||||||
@ -92,12 +97,14 @@ func (self UInt16) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self UInt16) Hash() int {
|
func (self UInt16) Bytes() []byte {
|
||||||
return int(self)
|
b := [2]byte{}
|
||||||
|
binary.LittleEndian.PutUint16(b[:], uint16(self))
|
||||||
|
return b[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (self Int32) Equals(other Sortable) bool {
|
func (self Int32) Equals(other Key) bool {
|
||||||
if o, ok := other.(Int32); ok {
|
if o, ok := other.(Int32); ok {
|
||||||
return self == o
|
return self == o
|
||||||
} else {
|
} else {
|
||||||
@ -105,7 +112,7 @@ func (self Int32) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Int32) Less(other Sortable) bool {
|
func (self Int32) Less(other Key) bool {
|
||||||
if o, ok := other.(Int32); ok {
|
if o, ok := other.(Int32); ok {
|
||||||
return self < o
|
return self < o
|
||||||
} else {
|
} else {
|
||||||
@ -113,12 +120,14 @@ func (self Int32) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Int32) Hash() int {
|
func (self Int32) Bytes() []byte {
|
||||||
return int(self)
|
b := [4]byte{}
|
||||||
|
binary.LittleEndian.PutUint32(b[:], uint32(self))
|
||||||
|
return b[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (self UInt32) Equals(other Sortable) bool {
|
func (self UInt32) Equals(other Key) bool {
|
||||||
if o, ok := other.(UInt32); ok {
|
if o, ok := other.(UInt32); ok {
|
||||||
return self == o
|
return self == o
|
||||||
} else {
|
} else {
|
||||||
@ -126,7 +135,7 @@ func (self UInt32) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self UInt32) Less(other Sortable) bool {
|
func (self UInt32) Less(other Key) bool {
|
||||||
if o, ok := other.(UInt32); ok {
|
if o, ok := other.(UInt32); ok {
|
||||||
return self < o
|
return self < o
|
||||||
} else {
|
} else {
|
||||||
@ -134,12 +143,14 @@ func (self UInt32) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self UInt32) Hash() int {
|
func (self UInt32) Bytes() []byte {
|
||||||
return int(self)
|
b := [4]byte{}
|
||||||
|
binary.LittleEndian.PutUint32(b[:], uint32(self))
|
||||||
|
return b[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (self Int64) Equals(other Sortable) bool {
|
func (self Int64) Equals(other Key) bool {
|
||||||
if o, ok := other.(Int64); ok {
|
if o, ok := other.(Int64); ok {
|
||||||
return self == o
|
return self == o
|
||||||
} else {
|
} else {
|
||||||
@ -147,7 +158,7 @@ func (self Int64) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Int64) Less(other Sortable) bool {
|
func (self Int64) Less(other Key) bool {
|
||||||
if o, ok := other.(Int64); ok {
|
if o, ok := other.(Int64); ok {
|
||||||
return self < o
|
return self < o
|
||||||
} else {
|
} else {
|
||||||
@ -155,12 +166,14 @@ func (self Int64) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Int64) Hash() int {
|
func (self Int64) Bytes() []byte {
|
||||||
return int(self>>32) ^ int(self)
|
b := [8]byte{}
|
||||||
|
binary.LittleEndian.PutUint64(b[:], uint64(self))
|
||||||
|
return b[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (self UInt64) Equals(other Sortable) bool {
|
func (self UInt64) Equals(other Key) bool {
|
||||||
if o, ok := other.(UInt64); ok {
|
if o, ok := other.(UInt64); ok {
|
||||||
return self == o
|
return self == o
|
||||||
} else {
|
} else {
|
||||||
@ -168,7 +181,7 @@ func (self UInt64) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self UInt64) Less(other Sortable) bool {
|
func (self UInt64) Less(other Key) bool {
|
||||||
if o, ok := other.(UInt64); ok {
|
if o, ok := other.(UInt64); ok {
|
||||||
return self < o
|
return self < o
|
||||||
} else {
|
} else {
|
||||||
@ -176,12 +189,14 @@ func (self UInt64) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self UInt64) Hash() int {
|
func (self UInt64) Bytes() []byte {
|
||||||
return int(self>>32) ^ int(self)
|
b := [8]byte{}
|
||||||
|
binary.LittleEndian.PutUint64(b[:], uint64(self))
|
||||||
|
return b[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (self Int) Equals(other Sortable) bool {
|
func (self Int) Equals(other Key) bool {
|
||||||
if o, ok := other.(Int); ok {
|
if o, ok := other.(Int); ok {
|
||||||
return self == o
|
return self == o
|
||||||
} else {
|
} else {
|
||||||
@ -189,7 +204,7 @@ func (self Int) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Int) Less(other Sortable) bool {
|
func (self Int) Less(other Key) bool {
|
||||||
if o, ok := other.(Int); ok {
|
if o, ok := other.(Int); ok {
|
||||||
return self < o
|
return self < o
|
||||||
} else {
|
} else {
|
||||||
@ -197,12 +212,14 @@ func (self Int) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Int) Hash() int {
|
func (self Int) Bytes() []byte {
|
||||||
return int(self)
|
b := [8]byte{}
|
||||||
|
binary.LittleEndian.PutUint64(b[:], uint64(self))
|
||||||
|
return b[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (self UInt) Equals(other Sortable) bool {
|
func (self UInt) Equals(other Key) bool {
|
||||||
if o, ok := other.(UInt); ok {
|
if o, ok := other.(UInt); ok {
|
||||||
return self == o
|
return self == o
|
||||||
} else {
|
} else {
|
||||||
@ -210,7 +227,7 @@ func (self UInt) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self UInt) Less(other Sortable) bool {
|
func (self UInt) Less(other Key) bool {
|
||||||
if o, ok := other.(UInt); ok {
|
if o, ok := other.(UInt); ok {
|
||||||
return self < o
|
return self < o
|
||||||
} else {
|
} else {
|
||||||
@ -218,8 +235,8 @@ func (self UInt) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self UInt) Hash() int {
|
func (self UInt) Bytes() []byte {
|
||||||
return int(self)
|
b := [8]byte{}
|
||||||
|
binary.LittleEndian.PutUint64(b[:], uint64(self))
|
||||||
|
return b[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import "bytes"
|
|||||||
type String string
|
type String string
|
||||||
type ByteSlice []byte
|
type ByteSlice []byte
|
||||||
|
|
||||||
func (self String) Equals(other Sortable) bool {
|
func (self String) Equals(other Key) bool {
|
||||||
if o, ok := other.(String); ok {
|
if o, ok := other.(String); ok {
|
||||||
return self == o
|
return self == o
|
||||||
} else {
|
} else {
|
||||||
@ -13,7 +13,7 @@ func (self String) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self String) Less(other Sortable) bool {
|
func (self String) Less(other Key) bool {
|
||||||
if o, ok := other.(String); ok {
|
if o, ok := other.(String); ok {
|
||||||
return self < o
|
return self < o
|
||||||
} else {
|
} else {
|
||||||
@ -21,16 +21,11 @@ func (self String) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self String) Hash() int {
|
func (self String) Bytes() []byte {
|
||||||
bytes := []byte(self)
|
return []byte(self)
|
||||||
hash := 0
|
|
||||||
for i, c := range bytes {
|
|
||||||
hash += (i+1)*int(c)
|
|
||||||
}
|
|
||||||
return hash
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self ByteSlice) Equals(other Sortable) bool {
|
func (self ByteSlice) Equals(other Key) bool {
|
||||||
if o, ok := other.(ByteSlice); ok {
|
if o, ok := other.(ByteSlice); ok {
|
||||||
return bytes.Equal(self, o)
|
return bytes.Equal(self, o)
|
||||||
} else {
|
} else {
|
||||||
@ -38,7 +33,7 @@ func (self ByteSlice) Equals(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self ByteSlice) Less(other Sortable) bool {
|
func (self ByteSlice) Less(other Key) bool {
|
||||||
if o, ok := other.(ByteSlice); ok {
|
if o, ok := other.(ByteSlice); ok {
|
||||||
return bytes.Compare(self, o) < 0 // -1 if a < b
|
return bytes.Compare(self, o) < 0 // -1 if a < b
|
||||||
} else {
|
} else {
|
||||||
@ -46,12 +41,6 @@ func (self ByteSlice) Less(other Sortable) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self ByteSlice) Hash() int {
|
func (self ByteSlice) Bytes() []byte {
|
||||||
hash := 0
|
return []byte(self)
|
||||||
for i, c := range self {
|
|
||||||
hash += (i+1)*int(c)
|
|
||||||
}
|
|
||||||
return hash
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,38 +4,45 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Sortable interface {
|
type Value interface {
|
||||||
Equals(b Sortable) bool
|
Bytes() []byte
|
||||||
Less(b Sortable) bool
|
}
|
||||||
|
|
||||||
|
type Key interface {
|
||||||
|
Equals(b Key) bool
|
||||||
|
Less(b Key) bool
|
||||||
|
Bytes() []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tree interface {
|
type Tree interface {
|
||||||
Root() Node
|
Root() Node
|
||||||
|
|
||||||
Size() int
|
Size() int
|
||||||
Has(key Sortable) bool
|
Has(key Key) bool
|
||||||
Get(key Sortable) (value interface{}, err error)
|
Get(key Key) (value Value, err error)
|
||||||
|
Hash() []byte
|
||||||
|
|
||||||
Put(key Sortable, value interface{}) (err error)
|
Put(key Key, value Value) (err error)
|
||||||
Remove(key Sortable) (value interface{}, err error)
|
Remove(key Key) (value Value, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Node interface {
|
type Node interface {
|
||||||
Key() Sortable
|
Key() Key
|
||||||
Value() interface{}
|
Value() Value
|
||||||
Left() Node
|
Left() Node
|
||||||
Right() Node
|
Right() Node
|
||||||
|
|
||||||
Size() int
|
Size() int
|
||||||
Has(key Sortable) bool
|
Has(key Key) bool
|
||||||
Get(key Sortable) (value interface{}, err error)
|
Get(key Key) (value Value, err error)
|
||||||
|
Hash() []byte
|
||||||
|
|
||||||
Put(key Sortable, value interface{}) (_ *IAVLNode, updated bool)
|
Put(key Key, value Value) (_ *IAVLNode, updated bool)
|
||||||
Remove(key Sortable) (_ *IAVLNode, value interface{}, err error)
|
Remove(key Key) (_ *IAVLNode, value Value, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeIterator func() (node Node, next NodeIterator)
|
type NodeIterator func() (node Node, next NodeIterator)
|
||||||
|
|
||||||
func NotFound(key Sortable) error {
|
func NotFound(key Key) error {
|
||||||
return fmt.Errorf("Key was not found.")
|
return fmt.Errorf("Key was not found.")
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user