forked from BobuSumisu/aho-corasick
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcharacterize_test.go
More file actions
75 lines (68 loc) · 2.04 KB
/
Copy pathcharacterize_test.go
File metadata and controls
75 lines (68 loc) · 2.04 KB
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
package ahocorasick
import (
"fmt"
"io/ioutil"
"os"
"testing"
)
// TestCharacterize prints structural facts about the benchmark automaton.
// Lab-only diagnostic, not part of the upstream suite: it builds automata
// up to 100k patterns, so it only runs when explicitly requested.
func TestCharacterize(t *testing.T) {
if os.Getenv("AC_LAB") == "" {
t.Skip("lab-only diagnostic; set AC_LAB=1 to run")
}
patterns, err := readPatterns("./test_data/NSF-ordlisten.cleaned.txt")
if err != nil {
t.Skip(err)
}
for _, n := range []int{100, 1000, 10000, 100000} {
tr := NewTrieBuilder().AddStrings(patterns[:n]).Build()
fmt.Printf("patterns=%d states=%d failTrans16=%v stopBytes=%d maxLen=%d\n",
n, len(tr.failTrans), tr.failTrans16 != nil, countStop(tr), tr.maxLen)
}
// Which scan path does BenchmarkMatchIbsen take?
tr := NewTrieBuilder().AddStrings(patterns[:10000]).Build()
fmt.Printf("10k: rootStopBytes=%d (single-stop specializations %v)\n",
len(tr.rootStopBytes), len(tr.rootStopBytes) == 1)
ibsen, err := ioutil.ReadFile("./test_data/Ibsen.txt")
if err != nil {
t.Skip(err)
}
ms := tr.Match(ibsen)
fmt.Printf("ibsen len=%d matches(all)=%d\n", len(ibsen), len(ms))
// match density on the 100k slice
ms2 := tr.Match(ibsen[:100000])
fmt.Printf("ibsen[:100000] matches=%d\n", len(ms2))
// how many bytes leave root (stop bytes) for 10k?
fmt.Printf("10k stop bytes=%d\n", countStop(tr))
// emit stats: direct terminal states, states that emit at all (dict
// or dictLink, mirroring addOutputFlags), and dictLink chain depth.
direct, emit, deep := 0, 0, 0
for s := range tr.dict {
if tr.dict[s] != 0 {
direct++
}
if tr.dict[s] != 0 || tr.dictLink[s] != nilState {
emit++
}
d := 0
for u := tr.dictLink[s]; u != nilState; u = tr.dictLink[u] {
d++
}
if d > deep {
deep = d
}
}
fmt.Printf("10k emitting states=%d/%d (direct terminals=%d) maxDictChain=%d\n",
emit, len(tr.dict), direct, deep)
}
func countStop(tr *Trie) int {
n := 0
for b := 0; b < 256; b++ {
if tr.rootStop[b] == 1 {
n++
}
}
return n
}