func (node *TrieNode) Match(data []byte) *TrieNode {
	dataLen := len(data)
	suffixLen := len(node.suffix)
	if dataLen < suffixLen {
		return nil  
	}
	for i := 0; i < suffixLen; i++ {
		if data[i] != node.suffix[i] {
			return nil  
		}
	}
	if dataLen == suffixLen {
		if node.PathLen > 0 {
			return node  
		}
		return nil  
	}
	data = data[suffixLen:]
	numChildren := len(node.children)
	for i := 0; i < numChildren; i++ {
		matchedNode := node.children[i].Match(data)
		if matchedNode != nil {
			return matchedNode  
		}
	}
	return nil  
}
Match compares the trie to the given data stream.
Match returns true if data can be completely matched to the trie.
package tcontainer
type TrieNode struct {
	suffix      []byte
	children    []*TrieNode
	longestPath int
	PathLen     int
	Payload     interface{}
}
func NewTrie(data []byte, payload interface{}) *TrieNode {
	return &TrieNode{
		suffix:      data,
		children:    []*TrieNode{},
		longestPath: len(data),
		PathLen:     len(data),
		Payload:     payload,
	}
}
func (node *TrieNode) addNewChild(data []byte, payload interface{}, pathLen int) {
	if node.longestPath < pathLen {
		node.longestPath = pathLen
	}
	idx := len(node.children)
	node.children = append(node.children, nil)
	for idx > 0 {
		nextIdx := idx - 1
		if node.children[nextIdx].longestPath > pathLen {
			break
		}
		node.children[idx] = node.children[nextIdx]
		idx = nextIdx
	}
	node.children[idx] = &TrieNode{
		suffix:      data,
		children:    []*TrieNode{},
		longestPath: pathLen,
		PathLen:     pathLen,
		Payload:     payload,
	}
}
func (node *TrieNode) replace(oldChild *TrieNode, newChild *TrieNode) {
	for i, child := range node.children {
		if child == oldChild {
			node.children[i] = newChild
			return  
		}
	}
}
func (node *TrieNode) ForEach(callback func(*TrieNode)) {
	callback(node)
	for _, child := range node.children {
		child.ForEach(callback)
	}
}
func (node *TrieNode) Add(data []byte, payload interface{}) *TrieNode {
	return node.addPath(data, payload, len(data), nil)
}
func (node *TrieNode) addPath(data []byte, payload interface{}, pathLen int, parent *TrieNode) *TrieNode {
	dataLen := len(data)
	suffixLen := len(node.suffix)
	testLen := suffixLen
	if dataLen < suffixLen {
		testLen = dataLen
	}
	var splitIdx int
	for splitIdx = 0; splitIdx < testLen; splitIdx++ {
		if data[splitIdx] != node.suffix[splitIdx] {
			break  
		}
	}
	if splitIdx == suffixLen {
		if splitIdx == dataLen {
			node.Payload = payload  
			return node             
		}
		data = data[splitIdx:]
		if suffixLen > 0 {
			for _, child := range node.children {
				if child.suffix[0] == data[0] {
					child.addPath(data, payload, pathLen, node)
					return node  
				}
			}
		}
		node.addNewChild(data, payload, pathLen)
		return node  
	}
	if splitIdx == dataLen {
		node.suffix = node.suffix[splitIdx:]
		newParent := NewTrie(data, payload)
		newParent.PathLen = pathLen
		newParent.longestPath = node.longestPath
		newParent.children = []*TrieNode{node}
		if parent != nil {
			parent.replace(node, newParent)
		}
		return newParent  
	}
	node.suffix = node.suffix[splitIdx:]
	newParent := NewTrie(data[:splitIdx], nil)
	newParent.PathLen = 0
	newParent.longestPath = node.longestPath
	newParent.children = []*TrieNode{node}
	newParent.addNewChild(data[splitIdx:], payload, pathLen)
	if parent != nil {
		parent.replace(node, newParent)
	}
	return newParent  
}