Skip to content

perf: reuse GetTIDsByTokenExpr results across searches via fraction index cache - #573

Open
eguguchkin wants to merge 5 commits into
mainfrom
0-search-context-1
Open

eguguchkin wants to merge 5 commits into
mainfrom
0-search-context-1

Conversation

@eguguchkin

@eguguchkin eguguchkin commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor
  • I have read and followed all requirements in CONTRIBUTING.md;
  • I used LLM/AI assistance to make this pull request;

If you have used LLM/AI assistance please provide model name and full prompt:

Model: {{model-name}}
Prompt: {{prompt}}

@codecov-commenter

codecov-commenter commented Oct 13, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.66667% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.47%. Comparing base (9b4b426) to head (2f57d92).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
frac/sealed_index.go 80.00% 3 Missing ⚠️
parser/token.go 80.00% 1 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread frac/index_cache.go Outdated
Comment on lines +10 to +14
// 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Useless comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

Comment thread frac/index_cache.go Outdated
Comment on lines +61 to +64
// 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Useless comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

Comment thread frac/sealed_index.go Outdated
Comment on lines +39 to +42
// 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]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Useless comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

Comment thread frac/sealed_index.go Outdated
Comment on lines +297 to +300
func isExactLiteral(t parser.Token) bool {
lit, ok := t.(*parser.Literal)
return ok && len(lit.Terms) == 1 && lit.Terms[0].Kind == parser.TermText
}

@dkharms dkharms Oct 14, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just moved IsExactLiteral into the parser package but didn’t combine it with newLiteralSearch because their signatures are different.

Comment thread frac/sealed_index.go Outdated
Comment on lines +294 to +296
// isExactLiteral reports whether t is a plain `field:value` literal — the
// only expression resolved without scanning tokens; see
// pattern.newLiteralSearch for the same condition.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Useless comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

Comment thread parser/token.go Outdated
// key, it is stable across independently parsed but equal queries.
//
// String parts are length-prefixed, so keys of different tokens cannot
// collide through concatenation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
// - ...;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// 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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i replaced implementation with DumpSeqQL

Comment thread parser/token.go
//
// String parts are length-prefixed, so keys of different tokens cannot
// collide through concatenation.
func TokenKey(t Token) string {

@dkharms dkharms Oct 14, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@github-actions

Copy link
Copy Markdown
Contributor

🔴 Performance Degradation

Some benchmarks have degraded compared to the previous run.
Click on Show table button to see full list of degraded benchmarks.

Show table
Name Previous Current Ratio Verdict
MutexListAppend-4 028e70 9200e1
181.32 MB/s 162.97 MB/s 0.90 🔴

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants