lbcd/claimtrie/merkletrie/collapsedtrie_test.go
Roy Lee 236cb44eee [lbry] claimtrie: import current snapshot
Sync to tip

Co-authored-by: Brannon King <countprimes@gmail.com>
2021-10-19 01:16:15 -07:00

113 lines
3.2 KiB
Go

package merkletrie
import (
"bytes"
"math/rand"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func b(value string) []byte { return []byte(value) }
func eq(x []byte, y string) bool { return bytes.Equal(x, b(y)) }
func TestInsertAndErase(t *testing.T) {
trie := NewCollapsedTrie()
assert.True(t, trie.NodeCount() == 1)
inserted, node := trie.InsertOrFind(b("abc"))
assert.True(t, inserted)
assert.NotNil(t, node)
assert.Equal(t, 2, trie.NodeCount())
inserted, node = trie.InsertOrFind(b("abd"))
assert.True(t, inserted)
assert.Equal(t, 4, trie.NodeCount())
assert.NotNil(t, node)
hit := trie.Find(b("ab"))
assert.True(t, eq(hit.key, "ab"))
assert.Equal(t, 2, len(hit.children))
hit = trie.Find(b("abc"))
assert.True(t, eq(hit.key, "c"))
hit = trie.Find(b("abd"))
assert.True(t, eq(hit.key, "d"))
hit = trie.Find(b("a"))
assert.Nil(t, hit)
indexes, path := trie.FindPath(b("abd"))
assert.Equal(t, 3, len(indexes))
assert.True(t, eq(path[1].key, "ab"))
erased := trie.Erase(b("ab"))
assert.False(t, erased)
assert.Equal(t, 4, trie.NodeCount())
erased = trie.Erase(b("abc"))
assert.True(t, erased)
assert.Equal(t, 2, trie.NodeCount())
erased = trie.Erase(b("abd"))
assert.True(t, erased)
assert.Equal(t, 1, trie.NodeCount())
}
func TestNilNameHandling(t *testing.T) {
trie := NewCollapsedTrie()
inserted, n := trie.InsertOrFind([]byte("test"))
assert.True(t, inserted)
n.claimHash = EmptyTrieHash
inserted, n = trie.InsertOrFind(nil)
assert.False(t, inserted)
n.claimHash = EmptyTrieHash
n.merkleHash = EmptyTrieHash
inserted, n = trie.InsertOrFind(nil)
assert.False(t, inserted)
assert.NotNil(t, n.claimHash)
assert.Nil(t, n.merkleHash)
nodeRemoved := trie.Erase(nil)
assert.False(t, nodeRemoved)
inserted, n = trie.InsertOrFind(nil)
assert.False(t, inserted)
assert.Nil(t, n.claimHash)
}
func TestCollapsedTriePerformance(t *testing.T) {
inserts := 100000 // increase this to 1M for more interesting results
data := make([][]byte, inserts)
rand.Seed(42)
for i := 0; i < inserts; i++ {
size := rand.Intn(70) + 4
data[i] = make([]byte, size)
rand.Read(data[i])
for j := 0; j < size; j++ {
data[i][j] %= byte(62) // shrink the range to match the old test
}
}
trie := NewCollapsedTrie()
// doing my own timing because I couldn't get the B.Run method to work:
start := time.Now()
for i := 0; i < inserts; i++ {
_, node := trie.InsertOrFind(data[i])
assert.NotNil(t, node, "Failure at %d of %d", i, inserts)
}
t.Logf("Insertion in %f sec.", time.Since(start).Seconds())
start = time.Now()
for i := 0; i < inserts; i++ {
node := trie.Find(data[i])
assert.True(t, bytes.HasSuffix(data[i], node.key), "Failure on %d of %d", i, inserts)
}
t.Logf("Lookup in %f sec. on %d nodes.", time.Since(start).Seconds(), trie.NodeCount())
start = time.Now()
for i := 0; i < inserts; i++ {
indexes, path := trie.FindPath(data[i])
assert.True(t, len(indexes) == len(path))
assert.True(t, len(path) > 1)
assert.True(t, bytes.HasSuffix(data[i], path[len(path)-1].key))
}
t.Logf("Parents in %f sec.", time.Since(start).Seconds())
start = time.Now()
for i := 0; i < inserts; i++ {
trie.Erase(data[i])
}
t.Logf("Deletion in %f sec.", time.Since(start).Seconds())
assert.Equal(t, 1, trie.NodeCount())
}