Skip to content

Commit

Permalink
chore: finish up docstrings
Browse files Browse the repository at this point in the history
Closes: #55
Signed-off-by: Tim Bray <tbray@textuality.com>
  • Loading branch information
timbray committed Jun 5, 2022
1 parent be9fd6d commit d07de36
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 24 deletions.
10 changes: 6 additions & 4 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Package quamina suports adding Patterns to Matchers and then
// presenting Events to the matcher, which will report which of
// the Patterns matched it. Patterns and Events are both represented
// Package quamina instances support adding Patterns and then
// presenting Events, generating a report of which Patterns
// match the Event. Patterns and Events are both represented
// as JSON objects, although there is a provided Flattener interface
// by which structured objects in formats other than JSON can be
// matched by quamina.
// matched by quamina. Quamina instances match Events quickly and
// with a latency that is not strongly affected by the number of
// Patterns which have been added.
package quamina
12 changes: 6 additions & 6 deletions flattener.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ package quamina
// "f", "33"
// "f", "\"x\""
//
// Let's call the first column, eg "d" and "e\ne1", the pathSegments. For each
// step i the pathSegments, e.g. "d" and "e1", the Flattener should call
// Let's call the first column, eg "d" and "e\ne1", the path. For each
// step i the path, e.g. "d" and "e1", the Flattener should call
// NameTracker.IsNameUsed(step) and if that comes back negative, not include any
// paths which don't contain that step. So in the example above, if
// nameTracker.IsNameUsed() only came back true for "a" and "f", then the output
Expand Down Expand Up @@ -53,10 +53,10 @@ type ArrayPos struct {
Pos int32
}

// Field represents a pathname/value combination, the data item which is matched against Patterns by the
// MatchesForEvent API.
// Path is \n-separated path from the event root to this field value.
// Val is the value - note no information as to type.
// Field represents a pathname/value combination, one of the data items which is matched
// against Patterns by the MatchesForEvent API.
// Path is the \n-separated path from the event root to this field value.
// Val is the value, a []byte forming a textual representation of the type
// ArrayTrail, for each array in the Path, identifies the array and the index in it.
type Field struct {
Path []byte
Expand Down
5 changes: 0 additions & 5 deletions matcher.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package quamina

// X is used in the AddPattern and MatchesForEvent APIs to identify the patterns that are added to
// a Quamina instance and are reported by that instance as matching an event. Commonly, X is a string
// used to name the event.
type X any

type matcher interface {
addPattern(x X, pat string) error
matchesForFields(fields []Field) ([]X, error)
Expand Down
13 changes: 9 additions & 4 deletions quamina.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func WithPatternStorage(ps LivePatternsState) Option {
}
}

// New returns a new Quamina instance. Consult the API's beginning with “New” for the options
// New returns a new Quamina instance. Consult the APIs beginning with “With” for the options
// that may be used to configure the new instance.
func New(opts ...Option) (*Quamina, error) {
var q Quamina
Expand All @@ -117,17 +117,22 @@ func (q *Quamina) Copy() *Quamina {
return &Quamina{matcher: q.matcher, flattener: q.flattener.Copy()}
}

// X is used in the AddPattern and MatchesForEvent APIs to identify the patterns that are added to
// a Quamina instance and are reported by that instance as matching an event. Commonly, X is a string
// used to name the event.
type X any

// AddPattern - adds a pattern, identified by the x argument, to a Quamina instance.
// patternJSON is a JSON object. error is returned in the case that the PatternJSON is invalid JSON or
// has a leaf which is not provided as an array. AddPattern is single-threaded; if it is invoked concurrently
// from multiple goroutines (in instances created using the Copy method) calls will block until any other
// call in progress succeeds.
// AddPattern call in progress succeeds.
func (q *Quamina) AddPattern(x X, patternJSON string) error {
return q.matcher.addPattern(x, patternJSON)
}

// DeletePattern removes pattnerns identified with the by the x argument from the Quamina insance; the effect
// is that return values from future calls to MatchesForEvent will not include this x value.
// DeletePattern removes pattnerns identified by the x argument from the Quamina insance; the effect
// is that return values from future calls to MatchesForEvent will not include this x value.
func (q *Quamina) DeletePatterns(x X) error {
return q.matcher.deletePatterns(x)
}
Expand Down
35 changes: 30 additions & 5 deletions stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ type stats struct {
fmCount int
fmTblCount int
fmEntries int
fmMax int
fmVisited map[*fieldMatcher]bool
vmCount int
vmVisited map[*valueMatcher]bool
stCount int
stTblCount int
stEntries int
stMax int
stVisited map[any]bool
siCount int
}

// matcherStats gathers statistics about the size of a coreMatcher, including the average and max fanout sizes of
// the transition tables, returning this information in string form
func matcherStats(m *coreMatcher) string {
s := stats{
fmVisited: make(map[*fieldMatcher]bool),
Expand All @@ -25,10 +30,13 @@ func matcherStats(m *coreMatcher) string {
fmStats(m.start().state, &s)
avgFmSize := fmt.Sprintf("%.3f", float64(s.fmEntries)/float64(s.fmTblCount))
avgStSize := "n/a"
if s.stCount > 0 {
avgStSize = fmt.Sprintf("%.3f", float64(s.stEntries)/float64(s.stCount))
if s.stTblCount > 0 {
avgStSize = fmt.Sprintf("%.3f", float64(s.stEntries)/float64(s.stTblCount))
}
return fmt.Sprintf("Field matchers: %d (avg size %s), Value matchers: %d, SmallTables %d (avg size %s), singletons %d", s.fmCount, avgFmSize, s.vmCount, s.stCount, avgStSize, s.siCount)
fmPart := fmt.Sprintf("Field matchers: %d (avg size %s, max %d), ", s.fmCount, avgFmSize, s.fmMax)
vmPart := fmt.Sprintf("Value matchers: %d, ", s.vmCount)
stPart := fmt.Sprintf("SmallTables %d (avg size %s, max %d), singletons %d", s.stCount, avgStSize, s.stMax, s.siCount)
return fmPart + vmPart + stPart
}

func fmStats(m *fieldMatcher, s *stats) {
Expand All @@ -39,6 +47,9 @@ func fmStats(m *fieldMatcher, s *stats) {
s.fmCount++
tSize := len(m.fields().transitions)
if tSize > 0 {
if tSize > s.fmMax {
s.fmMax = tSize
}
s.fmTblCount++
s.fmEntries += tSize
}
Expand Down Expand Up @@ -72,7 +83,14 @@ func dfaStats(t *smallTable[*dfaStep], s *stats) {
}
s.stVisited[t] = true
s.stCount++
s.stEntries += len(t.ceilings)
tSize := len(t.ceilings)
if tSize > 1 {
if tSize > s.stMax {
s.stMax = tSize
}
s.stTblCount++
s.stEntries += len(t.ceilings)
}
for _, step := range t.steps {
if step != nil {
if step.fieldTransitions != nil {
Expand All @@ -91,7 +109,14 @@ func nfaStats(t *smallTable[*nfaStepList], s *stats) {
}
s.stVisited[t] = true
s.stCount++
s.stEntries += len(t.ceilings)
tSize := len(t.ceilings)
if tSize > 1 {
if tSize > s.stMax {
s.stMax = tSize
}
s.stTblCount++
s.stEntries += len(t.ceilings)
}
for _, stepList := range t.steps {
if stepList == nil {
continue
Expand Down

0 comments on commit d07de36

Please sign in to comment.