diff --git a/trie.go b/trie.go index dc83c7cfea..83a3073ae8 100644 --- a/trie.go +++ b/trie.go @@ -10,6 +10,38 @@ type Database interface { Get(key []byte) ([]byte, error) } +/* + * Trie helper functions + */ +// Helper function for printing out the raw contents of a slice +func PrintSlice(slice []string) { + fmt.Printf("[") + for i, val := range slice { + fmt.Printf("%q", val) + if i != len(slice)-1 { fmt.Printf(",") } + } + fmt.Printf("]\n") +} + +// RLP Decodes a node in to a [2] or [17] string slice +func DecodeNode(data []byte) []string { + dec, _ := Decode(data, 0) + if slice, ok := dec.([]interface{}); ok { + strSlice := make([]string, len(slice)) + + for i, s := range slice { + if str, ok := s.([]byte); ok { + strSlice[i] = string(str) + } + } + + return strSlice + } + + return nil +} + +// A (modified) Radix Trie implementation type Trie struct { root string db Database @@ -19,18 +51,9 @@ func NewTrie(db Database, root string) *Trie { return &Trie{db: db, root: ""} } -func (t *Trie) Put(node interface{}) []byte { - //if s, ok := node.([]string); ok { - // PrintSlice(s) - //} - enc := Encode(node) - sha := Sha256Bin(enc) - - t.db.Put([]byte(sha), enc) - - return sha -} - +/* + * Public (query) interface functions + */ func (t *Trie) Update(key string, value string) { k := CompactHexDecode(key) @@ -43,10 +66,29 @@ func (t *Trie) Get(key string) string { return t.GetState(t.root, k) } +/* + * State functions (shouldn't be needed directly). + */ + +// Wrapper around the regular db "Put" which generates a key and value +func (t *Trie) Put(node interface{}) []byte { + enc := Encode(node) + sha := Sha256Bin(enc) + + t.db.Put([]byte(sha), enc) + + return sha +} + +// Helper function for printing a node (using fetch, decode and slice printing) +func (t *Trie) PrintNode(n string) { + data, _ := t.db.Get([]byte(n)) + d := DecodeNode(data) + PrintSlice(d) +} + // Returns the state of an object func (t *Trie) GetState(node string, key []int) string { - //if Debug { fmt.Println("get =", key) } - // Return the node if key is empty (= found) if len(key) == 0 || node == "" { return node @@ -66,10 +108,6 @@ func (t *Trie) GetState(node string, key []int) string { k := CompactDecode(currentNode[0]) v := currentNode[1] - //fmt.Println(k, key) - //fmt.Printf("k1:%v\nk2:%v\n", k, key[:len(k)-1]) - - //fmt.Println(len(key), ">=", len(k)-1, "&&", k, key[:len(k)]) if len(key) >= len(k) && CompareIntSlice(k, key[:len(k)]) { return t.GetState(v, key[len(k):]) } else { @@ -95,47 +133,13 @@ func (t *Trie) UpdateState(node string, key []int, value string) string { return "" } -func DecodeNode(data []byte) []string { - dec, _ := Decode(data, 0) - if slice, ok := dec.([]interface{}); ok { - strSlice := make([]string, len(slice)) - - for i, s := range slice { - if str, ok := s.([]byte); ok { - strSlice[i] = string(str) - } - } - - return strSlice - } - - return nil -} - -func (t *Trie) PrintNode(n string) { - data, _ := t.db.Get([]byte(n)) - d := DecodeNode(data) - PrintSlice(d) -} - -func PrintSlice(slice []string) { - fmt.Printf("[") - for i, val := range slice { - fmt.Printf("%q", val) - if i != len(slice)-1 { fmt.Printf(",") } - } - fmt.Printf("]\n") -} func (t *Trie) InsertState(node string, key []int, value string) string { - //if Debug { fmt.Println("insrt", key, value, "node:", node) } - if len(key) == 0 { return value } - //fmt.Println(node) - // Root node! + // New node if node == "" { newNode := []string{ CompactEncode(key), value } @@ -195,4 +199,3 @@ func (t *Trie) InsertState(node string, key []int, value string) string { return "" } -