domain_matcher.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package strmatcher
  2. import "strings"
  3. func breakDomain(domain string) []string {
  4. return strings.Split(domain, ".")
  5. }
  6. type node struct {
  7. value uint32
  8. sub map[string]*node
  9. }
  10. // DomainMatcherGroup is a IndexMatcher for a large set of Domain matchers.
  11. // Visible for testing only.
  12. type DomainMatcherGroup struct {
  13. root *node
  14. }
  15. func (g *DomainMatcherGroup) Add(domain string, value uint32) {
  16. if g.root == nil {
  17. g.root = new(node)
  18. }
  19. current := g.root
  20. parts := breakDomain(domain)
  21. for i := len(parts) - 1; i >= 0; i-- {
  22. part := parts[i]
  23. if current.sub == nil {
  24. current.sub = make(map[string]*node)
  25. }
  26. next := current.sub[part]
  27. if next == nil {
  28. next = new(node)
  29. current.sub[part] = next
  30. }
  31. current = next
  32. }
  33. current.value = value
  34. }
  35. func (g *DomainMatcherGroup) addMatcher(m domainMatcher, value uint32) {
  36. g.Add(string(m), value)
  37. }
  38. func (g *DomainMatcherGroup) Match(domain string) uint32 {
  39. current := g.root
  40. if current == nil {
  41. return 0
  42. }
  43. parts := breakDomain(domain)
  44. for i := len(parts) - 1; i >= 0; i-- {
  45. part := parts[i]
  46. if current.sub == nil {
  47. break
  48. }
  49. next := current.sub[part]
  50. if next == nil {
  51. break
  52. }
  53. current = next
  54. }
  55. return current.value
  56. }