indexmatcher_mph.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package strmatcher
  2. // A MphIndexMatcher is divided into three parts:
  3. // 1. `full` and `domain` patterns are matched by Rabin-Karp algorithm and minimal perfect hash table;
  4. // 2. `substr` patterns are matched by ac automaton;
  5. // 3. `regex` patterns are matched with the regex library.
  6. type MphIndexMatcher struct {
  7. count uint32
  8. mph *MphMatcherGroup
  9. ac *ACAutomatonMatcherGroup
  10. regex *SimpleMatcherGroup
  11. }
  12. func NewMphIndexMatcher() *MphIndexMatcher {
  13. return new(MphIndexMatcher)
  14. }
  15. // Add implements IndexMatcher.Add.
  16. func (g *MphIndexMatcher) Add(matcher Matcher) uint32 {
  17. g.count++
  18. index := g.count
  19. switch matcher := matcher.(type) {
  20. case FullMatcher:
  21. if g.mph == nil {
  22. g.mph = NewMphMatcherGroup()
  23. }
  24. g.mph.AddFullMatcher(matcher, index)
  25. case DomainMatcher:
  26. if g.mph == nil {
  27. g.mph = NewMphMatcherGroup()
  28. }
  29. g.mph.AddDomainMatcher(matcher, index)
  30. case SubstrMatcher:
  31. if g.ac == nil {
  32. g.ac = NewACAutomatonMatcherGroup()
  33. }
  34. g.ac.AddSubstrMatcher(matcher, index)
  35. case *RegexMatcher:
  36. if g.regex == nil {
  37. g.regex = &SimpleMatcherGroup{}
  38. }
  39. g.regex.AddMatcher(matcher, index)
  40. }
  41. return index
  42. }
  43. // Build implements IndexMatcher.Build.
  44. func (g *MphIndexMatcher) Build() error {
  45. if g.mph != nil {
  46. g.mph.Build()
  47. }
  48. if g.ac != nil {
  49. g.ac.Build()
  50. }
  51. return nil
  52. }
  53. // Match implements IndexMatcher.Match.
  54. func (g *MphIndexMatcher) Match(input string) []uint32 {
  55. result := make([][]uint32, 0, 5)
  56. if g.mph != nil {
  57. if matches := g.mph.Match(input); len(matches) > 0 {
  58. result = append(result, matches)
  59. }
  60. }
  61. if g.ac != nil {
  62. if matches := g.ac.Match(input); len(matches) > 0 {
  63. result = append(result, matches)
  64. }
  65. }
  66. if g.regex != nil {
  67. if matches := g.regex.Match(input); len(matches) > 0 {
  68. result = append(result, matches)
  69. }
  70. }
  71. return CompositeMatches(result)
  72. }
  73. // MatchAny implements IndexMatcher.MatchAny.
  74. func (g *MphIndexMatcher) MatchAny(input string) bool {
  75. if g.mph != nil && g.mph.MatchAny(input) {
  76. return true
  77. }
  78. if g.ac != nil && g.ac.MatchAny(input) {
  79. return true
  80. }
  81. return g.regex != nil && g.regex.MatchAny(input)
  82. }
  83. // Size implements IndexMatcher.Size.
  84. func (g *MphIndexMatcher) Size() uint32 {
  85. return g.count
  86. }