-
Notifications
You must be signed in to change notification settings - Fork 3
/
rune_trie_test.go
152 lines (125 loc) · 2.75 KB
/
rune_trie_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package trie
import (
"reflect"
"sort"
"testing"
)
// to prevent compiler optimizations, all benchmark results are stored
// in the package-level variable
var benchmarkResult bool
var benchmarkSetResult map[string]struct{}
var words = []string{
"c", "ce", "banana", "app", "aple", "ban", "apple1", "aaapple",
"1c", "1ce", "1banana", "1app", "1aple", "1ban", "1apple1", "1aaapple",
}
var filledTrieHashSet = (func() map[string]struct{} {
s := make(map[string]struct{})
for _, w := range words {
s[w] = struct{}{}
}
return s
})()
var filledRuneTrie = (func() Trie {
t := NewRuneTrie()
for _, w := range words {
t.Insert(w)
}
return t
})()
func TestRuneTrieContains(t *testing.T) {
trie := NewRuneTrie()
trie.Insert("c")
trie.Insert("apple")
trie.Insert("banana")
cases := []struct {
word string
exists bool
}{
{"c", true},
{"cc", false},
{"ce", false},
{"banana", true},
{"app", false},
{"aple", false},
{"ban", false},
{"apple", true},
{"apple1", false},
{"aaapple", false},
}
for _, c := range cases {
actual := trie.Contains(c.word)
if actual != c.exists {
if c.exists {
t.Errorf("%s is expected to be found in the trie", c.word)
} else {
t.Errorf("%s is not expected to be found in the trie", c.word)
}
}
}
}
func TestRuneTrieStartsWith(t *testing.T) {
trie := NewRuneTrie()
trie.Insert("apple")
trie.Insert("aplhabet")
trie.Insert("tree")
if !trie.StartsWith("a") {
t.Error("trie StartsWith(a) must return true, but returned false")
}
if trie.StartsWith("try") {
t.Error("trie StartsWith(try) must return false, but returned true")
}
}
func TestRuneTrieSearchByPrefix(t *testing.T) {
trie := NewRuneTrie()
trie.Insert("c")
trie.Insert("apple")
trie.Insert("banana")
trie.Insert("alphabet")
trie.Insert("alcohol")
actual := trie.SearchByPrefix("a")
sort.Strings(actual)
expected := []string{"alcohol", "alphabet", "apple"}
if !reflect.DeepEqual(actual, expected) {
t.Errorf("%v != %v", actual, expected)
}
}
func BenchmarkRuneTrieInsert(b *testing.B) {
var r bool
for i := 0; i < b.N; i++ {
t := NewRuneTrie()
for _, w := range words {
r = t.Insert(w)
}
}
benchmarkResult = r
}
func BenchmarkRuneTrieContains(b *testing.B) {
var r bool
for i := 0; i < b.N; i++ {
for _, w := range words {
r = filledRuneTrie.Contains(w)
}
}
benchmarkResult = r
}
func BenchmarkWordHashSetInsert(b *testing.B) {
var r map[string]struct{}
for i := 0; i < b.N; i++ {
s := make(map[string]struct{})
for _, w := range words {
s[w] = struct{}{}
}
r = s
}
benchmarkSetResult = r
}
func BenchmarkWordHashSetContains(b *testing.B) {
var r bool
for i := 0; i < b.N; i++ {
for _, w := range words {
_, ok := filledTrieHashSet[w]
r = ok
}
}
benchmarkResult = r
}