summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/text/internal/triegen/example_test.go
blob: 557a152e70384dd3889448b8988abe638a5cab57 (plain)
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
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package triegen_test

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"unicode"

	"golang.org/x/text/internal/triegen"
)

const seed = 0x12345

var genWriter = ioutil.Discard

func randomRunes() map[rune]uint8 {
	rnd := rand.New(rand.NewSource(seed))
	m := map[rune]uint8{}
	for len(m) < 100 {
		// Only set our random rune if it is a valid Unicode code point.
		if r := rune(rnd.Int31n(unicode.MaxRune + 1)); []rune(string(r))[0] == r {
			m[r] = 1
		}
	}
	return m
}

// Example_build shows how to build a simple trie. It assigns the value 1 to
// 100 random runes generated by randomRunes.
func Example_build() {
	t := triegen.NewTrie("rand")

	for r, _ := range randomRunes() {
		t.Insert(r, 1)
	}
	sz, err := t.Gen(genWriter)

	fmt.Printf("Trie size: %d bytes\n", sz)
	fmt.Printf("Error:     %v\n", err)

	// Output:
	// Trie size: 9280 bytes
	// Error:     <nil>
}

// Example_lookup demonstrates how to use the trie generated by Example_build.
func Example_lookup() {
	trie := newRandTrie(0)

	// The same set of runes used by Example_build.
	runes := randomRunes()

	// Verify the right value is returned for all runes.
	for r := rune(0); r <= unicode.MaxRune; r++ {
		// Note that the return type of lookup is uint8.
		if v, _ := trie.lookupString(string(r)); v != runes[r] {
			fmt.Println("FAILURE")
			return
		}
	}
	fmt.Println("SUCCESS")

	// Output:
	// SUCCESS
}

// runeValues generates some random values for a set of interesting runes.
func runeValues() map[rune]uint64 {
	rnd := rand.New(rand.NewSource(seed))
	m := map[rune]uint64{}
	for p := 4; p <= unicode.MaxRune; p <<= 1 {
		for d := -1; d <= 1; d++ {
			m[rune(p+d)] = uint64(rnd.Int63())
		}
	}
	return m
}

// ExampleGen_build demonstrates the creation of multiple tries sharing common
// blocks. ExampleGen_lookup demonstrates how to use the generated tries.
func ExampleGen_build() {
	var tries []*triegen.Trie

	rv := runeValues()
	for _, c := range []struct {
		include func(rune) bool
		name    string
	}{
		{func(r rune) bool { return true }, "all"},
		{func(r rune) bool { return r < 0x80 }, "ASCII only"},
		{func(r rune) bool { return r < 0x80 }, "ASCII only 2"},
		{func(r rune) bool { return r <= 0xFFFF }, "BMP only"},
		{func(r rune) bool { return r > 0xFFFF }, "No BMP"},
	} {
		t := triegen.NewTrie(c.name)
		tries = append(tries, t)

		for r, v := range rv {
			if c.include(r) {
				t.Insert(r, v)
			}
		}
	}
	sz, err := triegen.Gen(genWriter, "multi", tries)

	fmt.Printf("Trie size: %d bytes\n", sz)
	fmt.Printf("Error:     %v\n", err)

	// Output:
	// Trie size: 18250 bytes
	// Error:     <nil>
}

// ExampleGen_lookup shows how to look up values in the trie generated by
// ExampleGen_build.
func ExampleGen_lookup() {
	rv := runeValues()
	for i, include := range []func(rune) bool{
		func(r rune) bool { return true },        // all
		func(r rune) bool { return r < 0x80 },    // ASCII only
		func(r rune) bool { return r < 0x80 },    // ASCII only 2
		func(r rune) bool { return r <= 0xFFFF }, // BMP only
		func(r rune) bool { return r > 0xFFFF },  // No BMP
	} {
		t := newMultiTrie(i)

		for r := rune(0); r <= unicode.MaxRune; r++ {
			x := uint64(0)
			if include(r) {
				x = rv[r]
			}
			// As we convert from a valid rune, we know it is safe to use
			// lookupStringUnsafe.
			if v := t.lookupStringUnsafe(string(r)); x != v {
				fmt.Println("FAILURE")
				return
			}
		}
	}
	fmt.Println("SUCCESS")

	// Output:
	// SUCCESS
}