Skip to content

Commit

Permalink
add docs & make internal types hidden (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
mtrossbach authored Aug 29, 2024
1 parent 3b3c4ad commit bc50240
Show file tree
Hide file tree
Showing 15 changed files with 51 additions and 37 deletions.
9 changes: 9 additions & 0 deletions conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import (
"strings"
)

// ConditionSet represents a rule and consists of one or more items of type Condition
type ConditionSet []Condition

// MarshalJSON marshals a ConditionSet into an easy readable JSON object
func (c ConditionSet) MarshalJSON() ([]byte, error) {
// CAUTION: this must not be a pointer-receiver!
data := make(map[string]Pattern, len(c))
Expand All @@ -17,6 +19,7 @@ func (c ConditionSet) MarshalJSON() ([]byte, error) {
return json.Marshal(data)
}

// UnmarshalJSON unmarshal the JSON back to a ConditionSet
func (c *ConditionSet) UnmarshalJSON(data []byte) error {
// CAUTION: this must be a pointer-receiver!
var r map[string]Pattern
Expand All @@ -35,18 +38,21 @@ func (c *ConditionSet) UnmarshalJSON(data []byte) error {
return nil
}

// Condition represents a single condition inside a ConditionSet. It defines a Path (=reference to property in an event) and a Pattern to check against the value.
type Condition struct {
Path string `json:"path"`
Pattern Pattern `json:"pattern"`
}

// MarshalJSON marshals a Condition into an easy readable JSON object
func (c Condition) MarshalJSON() ([]byte, error) {
// CAUTION: this must not be a pointer-receiver!
return json.Marshal(map[string]Pattern{
c.Path: c.Pattern,
})
}

// UnmarshalJSON unmarshal the JSON back to a Condition
func (c *Condition) UnmarshalJSON(data []byte) error {
// CAUTION: this must be a pointer-receiver!
var r map[string]Pattern
Expand All @@ -61,12 +67,14 @@ func (c *Condition) UnmarshalJSON(data []byte) error {
return nil
}

// Pattern defines how a value should be compared. It consists of a Type and either a Value or Sub-patterns depending on the used Type.
type Pattern struct {
Type PatternType `json:"type"`
Value string `json:"value,omitempty"`
Sub []Pattern `json:"sub,omitempty"`
}

// MarshalJSON marshals a Pattern into an easy readable JSON object
func (p Pattern) MarshalJSON() ([]byte, error) {
// CAUTION: this must not be a pointer-receiver!

Expand All @@ -81,6 +89,7 @@ func (p Pattern) MarshalJSON() ([]byte, error) {
}
}

// UnmarshalJSON unmarshal the JSON back to a Pattern
func (p *Pattern) UnmarshalJSON(data []byte) error {
// CAUTION: this must be a pointer-receiver!

Expand Down
1 change: 1 addition & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package hypermatch

// RuleIdentifier is a type alias to represent the identifier for a rule, so that the user of hypermatch get identify which of the rules matches an event.
type RuleIdentifier any

const (
Expand Down
3 changes: 3 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Package hypermatch is a high-performance Go library that enables rapid matching of a large number of rules against events.
// Designed for speed and efficiency, hypermatch handles thousands of events per second with low latency.
package hypermatch
1 change: 1 addition & 0 deletions event.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package hypermatch

// Property represents a property and a slice of values inside an event. An Event is defined as a slice of Property objects.
type Property struct {
Path string
Values []string
Expand Down
20 changes: 10 additions & 10 deletions field_matcher.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
package hypermatch

type FieldMatcher struct {
Transitions map[string]*ValueMatcher `json:"t,omitempty"`
type fieldMatcher struct {
Transitions map[string]*valueMatcher `json:"t,omitempty"`
MatchingRuleIdentifiers []RuleIdentifier `json:"m,omitempty"`
MatchingAnythingButRuleIdentifiers []RuleIdentifier `json:"n,omitempty"`
AnythingButTransitions map[string]map[RuleIdentifier]*FieldMatcher `json:"o,omitempty"`
AnythingButTransitions map[string]map[RuleIdentifier]*fieldMatcher `json:"o,omitempty"`
Exclusive bool `json:"e,omitempty"`
}

func newFieldMatcher() *FieldMatcher {
return &FieldMatcher{
Transitions: make(map[string]*ValueMatcher),
func newFieldMatcher() *fieldMatcher {
return &fieldMatcher{
Transitions: make(map[string]*valueMatcher),
MatchingRuleIdentifiers: nil,
MatchingAnythingButRuleIdentifiers: nil,
AnythingButTransitions: nil,
}
}

func (f *FieldMatcher) AddAnythingButTransition(id RuleIdentifier, path string, fm *FieldMatcher) {
func (f *fieldMatcher) AddAnythingButTransition(id RuleIdentifier, path string, fm *fieldMatcher) {
if f.AnythingButTransitions == nil {
f.AnythingButTransitions = make(map[string]map[RuleIdentifier]*FieldMatcher)
f.AnythingButTransitions = make(map[string]map[RuleIdentifier]*fieldMatcher)
}
if _, ok := f.AnythingButTransitions[path]; !ok {
f.AnythingButTransitions[path] = make(map[RuleIdentifier]*FieldMatcher)
f.AnythingButTransitions[path] = make(map[RuleIdentifier]*fieldMatcher)
}
f.AnythingButTransitions[path][id] = fm
}

func (f *FieldMatcher) GetTransition(key string) *ValueMatcher {
func (f *fieldMatcher) GetTransition(key string) *valueMatcher {
vm, ok := f.Transitions[key]
if !ok {
vm = newValueMatcher()
Expand Down
8 changes: 4 additions & 4 deletions hypermatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

type HyperMatch struct {
matcher *FieldMatcher
matcher *fieldMatcher
rulesCount uint64
}

Expand Down Expand Up @@ -71,7 +71,7 @@ func (m *HyperMatch) Match(properties []Property) []RuleIdentifier {
return matches.All()
}

func tryToMatch(properties []Property, i int, fm *FieldMatcher, set *matchSet) {
func tryToMatch(properties []Property, i int, fm *fieldMatcher, set *matchSet) {
if i >= len(properties) {
return
}
Expand All @@ -86,13 +86,13 @@ func tryToMatch(properties []Property, i int, fm *FieldMatcher, set *matchSet) {
}
}

func match(f *FieldMatcher, field string, values []string) []*FieldMatcher {
func match(f *fieldMatcher, field string, values []string) []*fieldMatcher {
vm, ok := f.Transitions[field]
if !ok {
return nil
}

var afms []*FieldMatcher
var afms []*fieldMatcher

for _, value := range values {
v := str2value(value, nil, nil)
Expand Down
18 changes: 9 additions & 9 deletions nfa.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ package hypermatch

import "slices"

type NfaStep struct {
ValueTransitions map[byte]*NfaStep `json:"v,omitempty"`
FieldTransition []*FieldMatcher `json:"f,omitempty"`
type nfaStep struct {
ValueTransitions map[byte]*nfaStep `json:"v,omitempty"`
FieldTransition []*fieldMatcher `json:"f,omitempty"`
}

func newNfaStep() *NfaStep {
return &NfaStep{
ValueTransitions: make(map[byte]*NfaStep),
func newNfaStep() *nfaStep {
return &nfaStep{
ValueTransitions: make(map[byte]*nfaStep),
FieldTransition: nil,
}
}

func (n *NfaStep) MakeStep(char byte) *NfaStep {
func (n *nfaStep) MakeStep(char byte) *nfaStep {
s, ok := n.ValueTransitions[char]
if !ok {
s = newNfaStep()
Expand All @@ -23,7 +23,7 @@ func (n *NfaStep) MakeStep(char byte) *NfaStep {
return s
}

func (n *NfaStep) addOrReuseOrCreateFieldTransition(fm *FieldMatcher) *FieldMatcher {
func (n *nfaStep) addOrReuseOrCreateFieldTransition(fm *fieldMatcher) *fieldMatcher {
if fm != nil {
if slices.Index(n.FieldTransition, fm) == -1 {
n.FieldTransition = append(n.FieldTransition, fm)
Expand All @@ -43,7 +43,7 @@ func (n *NfaStep) addOrReuseOrCreateFieldTransition(fm *FieldMatcher) *FieldMatc
}
}

func transitionNfa(step *NfaStep, value []byte, transitions []*FieldMatcher) []*FieldMatcher {
func transitionNfa(step *nfaStep, value []byte, transitions []*fieldMatcher) []*fieldMatcher {
if len(value) == 0 {
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion pattern_allof.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func validatePatternAllOf(path string, pattern *Pattern) error {
return nil
}

func compilePatternAllOf(id RuleIdentifier, path string, pattern *Pattern, sourceFm *FieldMatcher, exitFm *FieldMatcher) *FieldMatcher {
func compilePatternAllOf(id RuleIdentifier, path string, pattern *Pattern, sourceFm *fieldMatcher, exitFm *fieldMatcher) *fieldMatcher {
lastSourceFm := sourceFm

for i, p := range pattern.Sub {
Expand Down
2 changes: 1 addition & 1 deletion pattern_allof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestCompilePatternAllOf(t *testing.T) {
}
}

func matchAny(start *FieldMatcher, values []string) *FieldMatcher {
func matchAny(start *fieldMatcher, values []string) *fieldMatcher {
for _, v := range values {
fm := transitionNfa(start.GetTransition("test").Nfa, str2value(v, nil, nil), nil)
if len(fm) > 0 {
Expand Down
2 changes: 1 addition & 1 deletion pattern_anyof.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func validatePatternAnyOf(path string, pattern *Pattern) error {
return nil
}

func compilePatternAnyOf(id RuleIdentifier, path string, pattern *Pattern, sourceFm *FieldMatcher, exitFm *FieldMatcher) *FieldMatcher {
func compilePatternAnyOf(id RuleIdentifier, path string, pattern *Pattern, sourceFm *fieldMatcher, exitFm *fieldMatcher) *fieldMatcher {
if exitFm != nil && !exitFm.Exclusive {
exitFm.Exclusive = true
}
Expand Down
2 changes: 1 addition & 1 deletion pattern_anythingbut.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func validatePatternAnythingBut(path string, pattern *Pattern) error {
return nil
}

func compilePatternAnythingBut(id RuleIdentifier, path string, pattern *Pattern, sourceFm *FieldMatcher, exitFm *FieldMatcher) *FieldMatcher {
func compilePatternAnythingBut(id RuleIdentifier, path string, pattern *Pattern, sourceFm *fieldMatcher, exitFm *fieldMatcher) *fieldMatcher {
exitFm = compilePatternAnyOf(id, path, pattern, sourceFm, exitFm)
exitFm.MatchingAnythingButRuleIdentifiers = append(exitFm.MatchingAnythingButRuleIdentifiers, id)

Expand Down
4 changes: 2 additions & 2 deletions pattern_compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"strings"
)

func compileCondition(fm *FieldMatcher, id RuleIdentifier, cond *Condition) *FieldMatcher {
func compileCondition(fm *fieldMatcher, id RuleIdentifier, cond *Condition) *fieldMatcher {
if cond == nil || len(cond.Path) == 0 {
return fm
}
Expand All @@ -32,7 +32,7 @@ func charReplace(data []byte, search byte, replace byte) []byte {
return data
}

func compilePattern(id RuleIdentifier, path string, pattern *Pattern, sourceFm *FieldMatcher, exitFm *FieldMatcher) *FieldMatcher {
func compilePattern(id RuleIdentifier, path string, pattern *Pattern, sourceFm *fieldMatcher, exitFm *fieldMatcher) *fieldMatcher {
if pattern == nil || len(path) == 0 {
return sourceFm
}
Expand Down
2 changes: 1 addition & 1 deletion pattern_equals.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func validatePatternEquals(pattern *Pattern) error {
return nil
}

func compilePatternEquals(start *NfaStep, value []byte, exitFm *FieldMatcher) *FieldMatcher {
func compilePatternEquals(start *nfaStep, value []byte, exitFm *fieldMatcher) *fieldMatcher {
step := start
for _, char := range value {
step = step.MakeStep(char)
Expand Down
4 changes: 2 additions & 2 deletions pattern_wildcard.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ func validatePatternWildcard(pattern *Pattern) error {
return nil
}

func compilePatternWildcard(start *NfaStep, value []byte, exitFm *FieldMatcher) *FieldMatcher {
func compilePatternWildcard(start *nfaStep, value []byte, exitFm *fieldMatcher) *fieldMatcher {
step := start
var lastWildcardStep *NfaStep
var lastWildcardStep *nfaStep
for i, char := range value {
if char == byteWildcard {
if (i == len(value)-2 && value[len(value)-1] == byteValueTerminator) || i == len(value)-1 {
Expand Down
10 changes: 5 additions & 5 deletions value_matcher.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package hypermatch

type ValueMatcher struct {
Nfa *NfaStep `json:"s,omitempty"`
type valueMatcher struct {
Nfa *nfaStep `json:"s,omitempty"`
// Maybe shortcuts here in the future
}

func newValueMatcher() *ValueMatcher {
return &ValueMatcher{Nfa: newNfaStep()}
func newValueMatcher() *valueMatcher {
return &valueMatcher{Nfa: newNfaStep()}
}

func (v *ValueMatcher) Transition(value []byte) []*FieldMatcher {
func (v *valueMatcher) Transition(value []byte) []*fieldMatcher {
return transitionNfa(v.Nfa, value, nil)
}

0 comments on commit bc50240

Please sign in to comment.