domain_matcher.go 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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 = &node{
  18. sub: make(map[string]*node),
  19. }
  20. }
  21. current := g.root
  22. parts := breakDomain(domain)
  23. for i := len(parts) - 1; i >= 0; i-- {
  24. part := parts[i]
  25. next := current.sub[part]
  26. if next == nil {
  27. next = &node{sub: make(map[string]*node)}
  28. current.sub[part] = next
  29. }
  30. current = next
  31. }
  32. current.value = value
  33. }
  34. func (g *DomainMatcherGroup) addMatcher(m domainMatcher, value uint32) {
  35. g.Add(string(m), value)
  36. }
  37. func (g *DomainMatcherGroup) Match(domain string) uint32 {
  38. current := g.root
  39. if current == nil {
  40. return 0
  41. }
  42. parts := breakDomain(domain)
  43. for i := len(parts) - 1; i >= 0; i-- {
  44. part := parts[i]
  45. next := current.sub[part]
  46. if next == nil {
  47. break
  48. }
  49. current = next
  50. }
  51. return current.value
  52. }