fix: wildcard match

This commit is contained in:
Skyxim 2023-03-31 20:43:49 +08:00
parent 752074c68e
commit 1e989b68bd
2 changed files with 33 additions and 36 deletions

View File

@ -38,12 +38,14 @@ func TestDomainWildcard(t *testing.T) {
"*.baidu.com", "*.baidu.com",
"www.baidu.com", "www.baidu.com",
"*.*.qq.com", "*.*.qq.com",
"test.*.baidu.com",
} }
set := trie.NewDomainSet(domainSet) set := trie.NewDomainSet(domainSet)
assert.NotNil(t, set) assert.NotNil(t, set)
// assert.True(t, set.Has("www.baidu.com")) assert.True(t, set.Has("www.baidu.com"))
// assert.False(t, set.Has("test.test.baidu.com")) assert.True(t, set.Has("test.test.baidu.com"))
assert.True(t,set.Has("test.test.qq.com")) assert.True(t, set.Has("test.test.qq.com"))
assert.False(t,set.Has("test.qq.com")) assert.False(t, set.Has("test.baidu.com"))
assert.False(t,set.Has("test.test.test.qq.com")) assert.False(t, set.Has("test.qq.com"))
assert.False(t, set.Has("test.test.test.qq.com"))
} }

View File

@ -108,28 +108,34 @@ func (ss *DomainSet) Has(key string) bool {
// go to next level // go to next level
nodeId, bmIdx := 0, 0 nodeId, bmIdx := 0, 0
type wildcardCursor struct { type wildcardCursor struct {
index, bmIdx int nodeId, bmIdx, index int
find bool find bool
}
cursor := wildcardCursor{
find: false,
} }
cursor := wildcardCursor{}
for i := 0; i < len(key); i++ { for i := 0; i < len(key); i++ {
RESTART:
c := key[i] c := key[i]
for ; ; bmIdx++ { for ; ; bmIdx++ {
if getBit(ss.labelBitmap, bmIdx) != 0 { if getBit(ss.labelBitmap, bmIdx) != 0 {
if cursor.find { if cursor.find {
// gets the node next to the cursor // back wildcard and find next node
wildcardNextNodeId := countZeros(ss.labelBitmap, ss.ranks, cursor.bmIdx+1) nextNodeId := countZeros(ss.labelBitmap, ss.ranks, cursor.bmIdx+1)
// next is a leaf, and the domain name has no next level nextBmIdx := selectIthOne(ss.labelBitmap, ss.ranks, ss.selects, nextNodeId-1) + 1
if getBit(ss.leaves, wildcardNextNodeId) != 0 && cursor.index == len(key) { j := cursor.index
return true for ; j < len(key) && key[j] != domainStepByte; j++ {
}
if j == len(key) {
return getBit(ss.leaves, nextNodeId) != 0
}
for ; ; nextBmIdx++ {
if ss.labels[nextBmIdx-nextNodeId] == domainStepByte {
bmIdx = nextBmIdx
nodeId = nextNodeId
i = j
cursor.find=false
goto RESTART
}
} }
// reset, and jump to the cursor location
cursor.find = false
i = cursor.index
bmIdx = cursor.bmIdx
break
} }
return false return false
} }
@ -139,18 +145,10 @@ func (ss *DomainSet) Has(key string) bool {
} else if ss.labels[bmIdx-nodeId] == wildcardByte { } else if ss.labels[bmIdx-nodeId] == wildcardByte {
cursor.find = true cursor.find = true
cursor.bmIdx = bmIdx cursor.bmIdx = bmIdx
// gets the first domain step that follows cursor.nodeId = nodeId
// If not, it is the last domain level, which is represented by len(key) cursor.index = i
if index := strings.Index(key[i:], domainStep); index > 0 {
cursor.index = index + i - 1
} else {
cursor.index = len(key)
}
break
} else if ss.labels[bmIdx-nodeId] == c { } else if ss.labels[bmIdx-nodeId] == c {
if ss.labels[bmIdx-nodeId] == domainStepByte { cursor.find=false
cursor.find = false
}
break break
} }
} }
@ -158,11 +156,8 @@ func (ss *DomainSet) Has(key string) bool {
bmIdx = selectIthOne(ss.labelBitmap, ss.ranks, ss.selects, nodeId-1) + 1 bmIdx = selectIthOne(ss.labelBitmap, ss.ranks, ss.selects, nodeId-1) + 1
} }
if getBit(ss.leaves, nodeId) != 0 { return getBit(ss.leaves, nodeId) != 0
return true
} else {
return false
}
} }
func setBit(bm *[]uint64, i int, v int) { func setBit(bm *[]uint64, i int, v int) {