Repository navigation
perf: reuse GetTIDsByTokenExpr results across searches via fraction index cache - #573
eguguchkin wants to merge 5 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #573 +/- ##
==========================================
+ Coverage 79.45% 79.47% +0.02%
==========================================
Files 253 255 +2
Lines 19152 19242 +90
==========================================
+ Hits 15217 15293 +76
- Misses 3935 3949 +14 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| // ExprTIDs is a value of the ExprTIDs cache layer: TIDs matched by a | ||
| // scan-heavy token expression (wildcard, regex, range) of the immutable | ||
| // fraction. Key keeps the original parser.TokenKey string to detect | ||
| // uint32 hash collisions. Exact-match literals are resolved by binary | ||
| // search alone and never enter this cache. |
| // ExprTIDs caches GetTIDsByTokenExpr results of the immutable | ||
| // fraction for scan-heavy token expressions (see ExprTIDs); | ||
| // keyed by the hash of parser.TokenKey, evicted by the | ||
| // shared cleaner. |
| // exprTIDsCache is the ExprTIDs layer of the fraction's IndexCache; | ||
| // the fraction is immutable, so cached lookups are valid for the | ||
| // fraction's whole lifetime. | ||
| exprTIDsCache cache.Cache[ExprTIDs] |
| func isExactLiteral(t parser.Token) bool { | ||
| lit, ok := t.(*parser.Literal) | ||
| return ok && len(lit.Terms) == 1 && lit.Terms[0].Kind == parser.TermText | ||
| } |
There was a problem hiding this comment.
There is the same check in pattern.newLiteralSearch (you've mentioned it yourself):
func newLiteralSearch(base baseSearch, token *parser.Literal) *literalSearch {
if len(token.Terms) != 1 || token.Terms[0].Kind != parser.TermText {
return nil
}
/* ... */
}Let's make a separate method for parser.Literal.
There was a problem hiding this comment.
I just moved IsExactLiteral into the parser package but didn’t combine it with newLiteralSearch because their signatures are different.
| // isExactLiteral reports whether t is a plain `field:value` literal — the | ||
| // only expression resolved without scanning tokens; see | ||
| // pattern.newLiteralSearch for the same condition. |
| // key, it is stable across independently parsed but equal queries. | ||
| // | ||
| // String parts are length-prefixed, so keys of different tokens cannot | ||
| // collide through concatenation. |
There was a problem hiding this comment.
Again, too wordy comment.
It will be much better to have one sentence with examples:
// TokenKey returns a canonical string uniquely identifying
// the lookup semantics of the token:
// - First example;
// - Second example;
// - ...;There was a problem hiding this comment.
// TokenKey constructs an opaque canonical key describing everything a token
// lookup needs: the selected field, the token type, term kinds and data,
// range endpoints and inclusivity, canonical IP-range bounds, or the regex
// source. Equal keys denote interchangeable lookup behavior, including for
// leaf tokens produced by independently parsed but semantically equal queries.
//
// The key encodes string components with explicit lengths so adjacent fields
// and terms cannot collide by concatenation. Derived token state is omitted:
// parsing normalizes regex data, IP bounds, and term inputs first, ensuring
// the key depends only on their observable search semantics rather than AST
// identity or cached implementation details.
//
// Callers may compare, store, or hash the result, but must not interpret its
// internal layout or rely on key ordering.
Looks better to me
There was a problem hiding this comment.
i replaced implementation with DumpSeqQL
| // | ||
| // String parts are length-prefixed, so keys of different tokens cannot | ||
| // collide through concatenation. | ||
| func TokenKey(t Token) string { |
There was a problem hiding this comment.
I wonder -- why did you decide to implement such function instead of adding DumpSeqQL into parser.Token interface or invoking DumpSeqQL directly on t?
var b strings.Builder
switch t := t.(type) {
case *Literal:
t.DumpSeqQL(&b)
case *Range:
t.DumpSeqQL(&b)
case *IPRange:
/* ... */
default:
panic(fmt.Sprintf("unknown token type: %T", t))
}Are you sure that thare are no problems with characters escaping in your approach?
🔴 Performance DegradationSome benchmarks have degraded compared to the previous run. Show table
|
If you have used LLM/AI assistance please provide model name and full prompt: