func (b *builder) Size() int {
	sz := len(b.IndexBlocks) * blockSize * b.IndexSize
	sz += len(b.ValueBlocks) * blockSize * b.ValueSize
	for _, c := range b.Compactions[1:] {
		sz += c.totalSize
	}
	if len(b.Trie) > 1 {
		sz += 2 * b.IndexSize * len(b.Trie)
	}
	return sz
}
Size returns the number of bytes the generated trie will take to store. It
needs to be exported as it is used in the templates.
package triegen  
import (
	"encoding/binary"
	"fmt"
	"hash/crc64"
	"io"
	"log"
	"unicode/utf8"
)
type builder struct {
	Name string
	ValueType string
	ValueSize int
	IndexType string
	IndexSize int
	SourceType string
	Trie []*Trie
	IndexBlocks []*node
	ValueBlocks [][]uint64
	Compactions []compaction
	Checksum    uint64
	ASCIIBlock   string
	StarterBlock string
	indexBlockIdx map[uint64]int
	valueBlockIdx map[uint64]nodeIndex
	asciiBlockIdx map[uint64]int
	Stats struct {
		NValueEntries int
		NValueBytes   int
		NIndexEntries int
		NIndexBytes   int
		NHandleBytes  int
	}
	err error
}
type nodeIndex struct {
	compaction int
	index      int
}
type compaction struct {
	c         Compacter
	blocks    []*node
	maxHandle uint32
	totalSize int
	Cutoff  uint32
	Offset  uint32
	Handler string
}
func (b *builder) setError(err error) {
	if b.err == nil {
		b.err = err
	}
}
type Option func(b *builder) error
func Compact(c Compacter) Option {
	return func(b *builder) error {
		b.Compactions = append(b.Compactions, compaction{
			c:       c,
			Handler: c.Handler() + "(n, b)"})
		return nil
	}
}
func Gen(w io.Writer, name string, tries []*Trie, opts ...Option) (sz int, err error) {
	b := &builder{
		Name:        name,
		Trie:        tries,
		IndexBlocks: []*node{{}, {}, {}},
		Compactions: []compaction{{
			Handler: name + "Values[n<<6+uint32(b)]",
		}},
		indexBlockIdx: map[uint64]int{0: 0},
		valueBlockIdx: map[uint64]nodeIndex{0: {}},
		asciiBlockIdx: map[uint64]int{},
	}
	b.Compactions[0].c = (*simpleCompacter)(b)
	for _, f := range opts {
		if err := f(b); err != nil {
			return 0, err
		}
	}
	b.build()
	if b.err != nil {
		return 0, b.err
	}
	if err = b.print(w); err != nil {
		return 0, err
	}
	return b.Size(), nil
}
type Trie struct {
	root *node
	hiddenTrie
}
type hiddenTrie struct {
	Name         string
	Checksum     uint64
	ASCIIIndex   int
	StarterIndex int
}
func NewTrie(name string) *Trie {
	return &Trie{
		&node{
			children: make([]*node, blockSize),
			values:   make([]uint64, utf8.RuneSelf),
		},
		hiddenTrie{Name: name},
	}
}
func (t *Trie) Gen(w io.Writer, opts ...Option) (sz int, err error) {
	return Gen(w, t.Name, []*Trie{t}, opts...)
}
type node struct {
	children []*node
	values []uint64
	index nodeIndex
}
func (t *Trie) Insert(r rune, value uint64) {
	if value == 0 {
		return
	}
	s := string(r)
	if []rune(s)[0] != r && value != 0 {
		panic(fmt.Sprintf("triegen: non-zero value for invalid rune %U", r))
	}
	if len(s) == 1 {
		t.root.values[s[0]] = value
		return
	}
	n := t.root
	for ; len(s) > 1; s = s[1:] {
		if n.children == nil {
			n.children = make([]*node, blockSize)
		}
		p := s[0] % blockSize
		c := n.children[p]
		if c == nil {
			c = &node{}
			n.children[p] = c
		}
		if len(s) > 2 && c.values != nil {
			log.Fatalf("triegen: insert(%U): found internal node with values", r)
		}
		n = c
	}
	if n.values == nil {
		n.values = make([]uint64, blockSize)
	}
	if n.children != nil {
		log.Fatalf("triegen: insert(%U): found leaf node that also has child nodes", r)
	}
	n.values[s[0]-0x80] = value
}