fix: use same strClone function

This commit is contained in:
gVisor bot 2022-11-30 20:38:03 +08:00
parent b48387d9f4
commit 19b8af7ebc

View file

@ -4,21 +4,21 @@ import "strings"
// Node is the trie's node // Node is the trie's node
type Node[T any] struct { type Node[T any] struct {
childMap map[string]*Node[T]
childNode *Node[T] // optimize for only one child childNode *Node[T] // optimize for only one child
childStr string childStr string
children map[string]*Node[T]
inited bool inited bool
data T data T
} }
func (n *Node[T]) getChild(s string) *Node[T] { func (n *Node[T]) getChild(s string) *Node[T] {
if n.children == nil { if n.childMap == nil {
if n.childNode != nil && n.childStr == s { if n.childNode != nil && n.childStr == s {
return n.childNode return n.childNode
} }
return nil return nil
} }
return n.children[s] return n.childMap[s]
} }
func (n *Node[T]) hasChild(s string) bool { func (n *Node[T]) hasChild(s string) bool {
@ -26,21 +26,21 @@ func (n *Node[T]) hasChild(s string) bool {
} }
func (n *Node[T]) addChild(s string, child *Node[T]) { func (n *Node[T]) addChild(s string, child *Node[T]) {
if n.children == nil { if n.childMap == nil {
if n.childNode == nil { if n.childNode == nil {
n.childStr = s n.childStr = s
n.childNode = child n.childNode = child
return return
} }
n.children = map[string]*Node[T]{} n.childMap = map[string]*Node[T]{}
if n.childNode != nil { if n.childNode != nil {
n.children[n.childStr] = n.childNode n.childMap[n.childStr] = n.childNode
} }
n.childStr = "" n.childStr = ""
n.childNode = nil n.childNode = nil
} }
n.children[s] = child n.childMap[s] = child
} }
func (n *Node[T]) getOrNewChild(s string) *Node[T] { func (n *Node[T]) getOrNewChild(s string) *Node[T] {
@ -54,45 +54,54 @@ func (n *Node[T]) getOrNewChild(s string) *Node[T] {
func (n *Node[T]) optimize() { func (n *Node[T]) optimize() {
if len(n.childStr) > 0 { if len(n.childStr) > 0 {
n.childStr = strings.Clone(n.childStr) n.childStr = strClone(n.childStr)
} }
if n.childNode != nil { if n.childNode != nil {
n.childNode.optimize() n.childNode.optimize()
} }
if n.children == nil { if n.childMap == nil {
return return
} }
switch len(n.children) { switch len(n.childMap) {
case 0: case 0:
n.children = nil n.childMap = nil
return return
case 1: case 1:
for key := range n.children { for key := range n.childMap {
n.childStr = key n.childStr = key
n.childNode = n.children[key] n.childNode = n.childMap[key]
} }
n.children = nil n.childMap = nil
n.optimize() n.optimize()
return return
} }
children := make(map[string]*Node[T], len(n.children)) // avoid map reallocate memory children := make(map[string]*Node[T], len(n.childMap)) // avoid map reallocate memory
for key := range n.children { for key := range n.childMap {
child := n.children[key] child := n.childMap[key]
if child == nil { if child == nil {
continue continue
} }
key = strClone(key)
children[key] = child
child.optimize()
}
n.childMap = children
}
func strClone(key string) string {
switch key { // try to save string's memory switch key { // try to save string's memory
case wildcard: case wildcard:
key = wildcard key = wildcard
case dotWildcard: case dotWildcard:
key = dotWildcard key = dotWildcard
case complexWildcard:
key = complexWildcard
case domainStep:
key = domainStep
default: default:
key = strings.Clone(key) key = strings.Clone(key)
} }
children[key] = child return key
child.optimize()
}
n.children = children
} }
func (n *Node[T]) isEmpty() bool { func (n *Node[T]) isEmpty() bool {