github.com/lbryio/lbcd@v0.22.119/claimtrie/merkletrie/collapsedtrie_test.go (about) 1 package merkletrie 2 3 import ( 4 "bytes" 5 "math/rand" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/assert" 10 ) 11 12 func b(value string) []byte { return []byte(value) } 13 func eq(x []byte, y string) bool { return bytes.Equal(x, b(y)) } 14 15 func TestInsertAndErase(t *testing.T) { 16 trie := NewCollapsedTrie() 17 assert.True(t, trie.NodeCount() == 1) 18 inserted, node := trie.InsertOrFind(b("abc")) 19 assert.True(t, inserted) 20 assert.NotNil(t, node) 21 assert.Equal(t, 2, trie.NodeCount()) 22 inserted, node = trie.InsertOrFind(b("abd")) 23 assert.True(t, inserted) 24 assert.Equal(t, 4, trie.NodeCount()) 25 assert.NotNil(t, node) 26 hit := trie.Find(b("ab")) 27 assert.True(t, eq(hit.key, "ab")) 28 assert.Equal(t, 2, len(hit.children)) 29 hit = trie.Find(b("abc")) 30 assert.True(t, eq(hit.key, "c")) 31 hit = trie.Find(b("abd")) 32 assert.True(t, eq(hit.key, "d")) 33 hit = trie.Find(b("a")) 34 assert.Nil(t, hit) 35 indexes, path := trie.FindPath(b("abd")) 36 assert.Equal(t, 3, len(indexes)) 37 assert.True(t, eq(path[1].key, "ab")) 38 erased := trie.Erase(b("ab")) 39 assert.False(t, erased) 40 assert.Equal(t, 4, trie.NodeCount()) 41 erased = trie.Erase(b("abc")) 42 assert.True(t, erased) 43 assert.Equal(t, 2, trie.NodeCount()) 44 erased = trie.Erase(b("abd")) 45 assert.True(t, erased) 46 assert.Equal(t, 1, trie.NodeCount()) 47 } 48 49 func TestNilNameHandling(t *testing.T) { 50 trie := NewCollapsedTrie() 51 inserted, n := trie.InsertOrFind([]byte("test")) 52 assert.True(t, inserted) 53 n.claimHash = EmptyTrieHash 54 inserted, n = trie.InsertOrFind(nil) 55 assert.False(t, inserted) 56 n.claimHash = EmptyTrieHash 57 n.merkleHash = EmptyTrieHash 58 inserted, n = trie.InsertOrFind(nil) 59 assert.False(t, inserted) 60 assert.NotNil(t, n.claimHash) 61 assert.Nil(t, n.merkleHash) 62 nodeRemoved := trie.Erase(nil) 63 assert.False(t, nodeRemoved) 64 inserted, n = trie.InsertOrFind(nil) 65 assert.False(t, inserted) 66 assert.Nil(t, n.claimHash) 67 } 68 69 func TestCollapsedTriePerformance(t *testing.T) { 70 inserts := 100000 // increase this to 1M for more interesting results 71 data := make([][]byte, inserts) 72 rand.Seed(42) 73 for i := 0; i < inserts; i++ { 74 size := rand.Intn(70) + 4 75 data[i] = make([]byte, size) 76 rand.Read(data[i]) 77 for j := 0; j < size; j++ { 78 data[i][j] %= byte(62) // shrink the range to match the old test 79 } 80 } 81 82 trie := NewCollapsedTrie() 83 // doing my own timing because I couldn't get the B.Run method to work: 84 start := time.Now() 85 for i := 0; i < inserts; i++ { 86 _, node := trie.InsertOrFind(data[i]) 87 assert.NotNil(t, node, "Failure at %d of %d", i, inserts) 88 } 89 t.Logf("Insertion in %f sec.", time.Since(start).Seconds()) 90 91 start = time.Now() 92 for i := 0; i < inserts; i++ { 93 node := trie.Find(data[i]) 94 assert.True(t, bytes.HasSuffix(data[i], node.key), "Failure on %d of %d", i, inserts) 95 } 96 t.Logf("Lookup in %f sec. on %d nodes.", time.Since(start).Seconds(), trie.NodeCount()) 97 98 start = time.Now() 99 for i := 0; i < inserts; i++ { 100 indexes, path := trie.FindPath(data[i]) 101 assert.True(t, len(indexes) == len(path)) 102 assert.True(t, len(path) > 1) 103 assert.True(t, bytes.HasSuffix(data[i], path[len(path)-1].key)) 104 } 105 t.Logf("Parents in %f sec.", time.Since(start).Seconds()) 106 107 start = time.Now() 108 for i := 0; i < inserts; i++ { 109 trie.Erase(data[i]) 110 } 111 t.Logf("Deletion in %f sec.", time.Since(start).Seconds()) 112 assert.Equal(t, 1, trie.NodeCount()) 113 }