fix radix tree

This commit is contained in:
wanyaoqi
2019-02-27 21:07:55 +08:00
parent 39c0ac797b
commit 485d6fc290
2 changed files with 41 additions and 24 deletions
+29 -24
View File
@@ -5,6 +5,8 @@ import (
"path"
"regexp"
"strings"
"yunion.io/x/log"
)
type RadixNode struct {
@@ -44,14 +46,8 @@ func (r *RadixNode) add(segments []string, data interface{}, depth int, segNames
if r.data != nil {
return fmt.Errorf("Duplicate data for node")
} else {
if depth == 1 {
node := NewRadix()
node.data = data
r.regexpNodes[".*"] = node
} else {
r.data = data
r.segNames = segNames
}
r.data = data
r.segNames = segNames
return nil
}
} else {
@@ -96,7 +92,7 @@ func (r *RadixNode) add(segments []string, data interface{}, depth int, segNames
}
func (r *RadixNode) Match(segments []string, params map[string]string) interface{} {
node := r.match(segments, true)
node, _ := r.match(segments)
if node == nil {
return nil
}
@@ -106,32 +102,41 @@ func (r *RadixNode) Match(segments []string, params map[string]string) interface
return node.data
}
func (r *RadixNode) match(segments []string, isRoot bool) *RadixNode {
func (r *RadixNode) match(segments []string) (*RadixNode, bool) {
if len(segments) == 0 {
return r
}
if len(r.stringNodes) == 0 && len(r.regexpNodes) == 0 {
if isRoot {
return nil
} else {
return r
}
return r, true
} else if len(r.stringNodes) == 0 && len(r.regexpNodes) == 0 {
return r, false
}
if node, ok := r.stringNodes[segments[0]]; ok {
if rnode := node.match(segments[1:], false); rnode != nil && rnode.data != nil {
return rnode
if rnode, _ := node.match(segments[1:]); rnode != nil && rnode.data != nil {
return rnode, true
}
}
var nodeTmp *RadixNode
for regstr, node := range r.regexpNodes {
if regexp.MustCompile(regstr).MatchString(segments[0]) {
if rnode := node.match(segments[1:], false); rnode != nil && rnode.data != nil {
return rnode
if rnode, fullMatch := node.match(segments[1:]); rnode != nil && rnode.data != nil {
if fullMatch {
return rnode, fullMatch
} else {
if nodeTmp != nil {
log.Errorf("segments %v match mutil node", segments)
continue
}
nodeTmp = rnode
}
}
}
}
return nil
if nodeTmp != nil {
return nodeTmp, false
} else {
return r, false
}
}
func (r *RadixNode) Walk(f func(spath string, data interface{})) {
+12
View File
@@ -23,6 +23,11 @@ func TestRadixNode(t *testing.T) {
}
r.Walk(f)
params := make(map[string]string)
ret = r.Match([]string{"layer1", "layer1.0", "layer2.0"}, params)
if ret.(string) != "layer1.0" {
t.Error("0 Unexpect result:", ret, "!= layer1.0")
}
ret = r.Match([]string{"layer1", "layer1.0"}, params)
if ret.(string) != "layer1.0" {
t.Error("0 Unexpect result:", ret, "!= layer1.0")
@@ -73,6 +78,13 @@ func TestRadixNode(t *testing.T) {
if ret.(string) != "root" {
t.Error("9 Unexpect result:", ret, "!= root")
}
r.Add([]string{"<phone_number:^1[0-9-]{10}$>"}, "phonelayer1")
ret = r.Match([]string{"12345678900"}, params)
if ret.(string) != "phonelayer1" {
t.Error("13 Unexpect result:", ret, "!= phonelayer1")
}
if r.Add([]string{"layer1"}, "layer1") == nil {
t.Error("10 Add duplicate data should fail")
}