good morning!!!!

Skip to content
Snippets Groups Projects
Commit 5cdfee51 authored by Jeffrey Wilcke's avatar Jeffrey Wilcke
Browse files

New Trie iterator

parent 4c7bd75c
Branches
Tags
No related merge requests found
...@@ -59,3 +59,18 @@ func CompactHexDecode(str string) []int { ...@@ -59,3 +59,18 @@ func CompactHexDecode(str string) []int {
return hexSlice return hexSlice
} }
func DecodeCompact(key []int) string {
base := "0123456789abcdef"
var str string
for _, v := range key {
if v < 16 {
str += string(base[v])
}
}
res, _ := hex.DecodeString(str)
return string(res)
}
...@@ -442,6 +442,8 @@ type TrieIterator struct { ...@@ -442,6 +442,8 @@ type TrieIterator struct {
shas [][]byte shas [][]byte
values []string values []string
lastNode []byte
} }
func (t *Trie) NewIterator() *TrieIterator { func (t *Trie) NewIterator() *TrieIterator {
...@@ -513,3 +515,47 @@ func (it *TrieIterator) Key() string { ...@@ -513,3 +515,47 @@ func (it *TrieIterator) Key() string {
func (it *TrieIterator) Value() string { func (it *TrieIterator) Value() string {
return "" return ""
} }
type EachCallback func(key string, node *Value)
func (it *TrieIterator) Each(cb EachCallback) {
it.fetchNode(nil, NewValue(it.trie.Root).Bytes(), cb)
}
func (it *TrieIterator) fetchNode(key []int, node []byte, cb EachCallback) {
it.iterateNode(key, it.trie.cache.Get(node), cb)
}
func (it *TrieIterator) iterateNode(key []int, currentNode *Value, cb EachCallback) {
if currentNode.Len() == 2 {
k := CompactDecode(currentNode.Get(0).Str())
if currentNode.Get(1).Str() == "" {
it.iterateNode(key, currentNode.Get(1), cb)
} else {
pk := append(key, k...)
if k[len(k)-1] == 16 {
cb(DecodeCompact(pk), currentNode.Get(1))
} else {
it.fetchNode(pk, currentNode.Get(1).Bytes(), cb)
}
}
} else {
for i := 0; i < currentNode.Len(); i++ {
pk := append(key, i)
if i == 16 && currentNode.Get(i).Len() != 0 {
cb(DecodeCompact(pk), currentNode.Get(i))
} else {
if currentNode.Get(i).Str() == "" {
it.iterateNode(pk, currentNode.Get(i), cb)
} else {
val := currentNode.Get(i).Str()
if val != "" {
it.fetchNode(pk, []byte(val), cb)
}
}
}
}
}
}
...@@ -154,7 +154,7 @@ func TestTrieDeleteWithValue(t *testing.T) { ...@@ -154,7 +154,7 @@ func TestTrieDeleteWithValue(t *testing.T) {
} }
func TestTrieIterator(t *testing.T) { func TestTriePurge(t *testing.T) {
_, trie := New() _, trie := New()
trie.Update("c", LONG_WORD) trie.Update("c", LONG_WORD)
trie.Update("ca", LONG_WORD) trie.Update("ca", LONG_WORD)
...@@ -171,16 +171,14 @@ func TestTrieIterator(t *testing.T) { ...@@ -171,16 +171,14 @@ func TestTrieIterator(t *testing.T) {
} }
} }
func TestHashes(t *testing.T) { func TestTrieIt(t *testing.T) {
_, trie := New() _, trie := New()
trie.Update("cat", "dog") trie.Update("c", LONG_WORD)
trie.Update("ca", "dude") trie.Update("ca", LONG_WORD)
trie.Update("doge", "1234567890abcdefghijklmnopqrstuvwxxzABCEFGHIJKLMNOPQRSTUVWXYZ") trie.Update("cat", LONG_WORD)
trie.Update("dog", "test")
trie.Update("test", "1234567890abcdefghijklmnopqrstuvwxxzABCEFGHIJKLMNOPQRSTUVWXYZ") it := trie.NewIterator()
fmt.Printf("%x\n", trie.Root) it.Each(func(key string, node *Value) {
trie.Delete("dog") fmt.Println(key, ":", node.Str())
fmt.Printf("%x\n", trie.Root) })
trie.Delete("test")
fmt.Printf("%x\n", trie.Root)
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment