github.com/TeaOSLab/EdgeNode@v1.3.8/internal/re/rune_tree.go (about) 1 // Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. 2 3 package re 4 5 type RuneMap map[rune]*RuneTree 6 7 func (this RuneMap) Lookup(s string, caseInsensitive bool) bool { 8 return this.lookup([]rune(s), caseInsensitive, 0) 9 } 10 11 func (this RuneMap) lookup(runes []rune, caseInsensitive bool, depth int) bool { 12 if len(runes) == 0 { 13 return false 14 } 15 for i, r := range runes { 16 tree, ok := this[r] 17 if !ok { 18 if caseInsensitive { 19 if r >= 'a' && r <= 'z' { 20 r -= 32 21 tree, ok = this[r] 22 } else if r >= 'A' && r <= 'Z' { 23 r += 32 24 tree, ok = this[r] 25 } 26 } 27 if !ok { 28 if depth > 0 { 29 return false 30 } 31 continue 32 } 33 } 34 if tree.IsEnd { 35 return true 36 } 37 b := tree.Children.lookup(runes[i+1:], caseInsensitive, depth+1) 38 if b { 39 return true 40 } 41 } 42 return false 43 } 44 45 type RuneTree struct { 46 Children RuneMap 47 IsEnd bool 48 } 49 50 func NewRuneTree(list []string) RuneMap { 51 var rootMap = RuneMap{} 52 for _, s := range list { 53 if len(s) == 0 { 54 continue 55 } 56 57 var lastMap = rootMap 58 var runes = []rune(s) 59 for index, r := range runes { 60 tree, ok := lastMap[r] 61 if !ok { 62 tree = &RuneTree{ 63 Children: RuneMap{}, 64 } 65 lastMap[r] = tree 66 } 67 if index == len(runes)-1 { 68 tree.IsEnd = true 69 } 70 lastMap = tree.Children 71 } 72 } 73 return rootMap 74 }