Commit Graph
2777 Commits
Author SHA1 Message Date
Luca Cominardi ef0bed7ea3 Simplify tie-breaker start bound and doc comment 2026-10-02 09:18:57 +02:00
Luca Cominardi 547524adbe fix: keep tiebreaker values u32-compatible for now 2026-10-02 09:08:06 +02:00
Luca Cominardi a68b80ea94 Draw tie-breaker starts from the full u64 range 2026-10-01 16:25:38 +02:00
Luca Cominardi af3ad76251 Reject tie-breaker fields as index sort fields 2026-10-01 14:30:35 +02:00
Luca Cominardi 6a6378fa1f feat: add generated tie-breaker fast fields 2026-10-01 14:24:04 +02:00
Luca Cominardi a102eed940 Merge remote-tracking branch 'origin/main' into mallets/seqnum-field 2026-10-01 11:40:33 +02:00
Paul MasurelandPaul Masurel 1f9e49da6b Abstracting columnar from aggregation. (#3112)
* Changing the way aggregation access their value.

They now get values via a ValueSource abstraction.
The aggregation collector also gets the possibility to
register ValueSourceProvider describing value columns that are computed
on the fly.

Finally, segment aggregation that require a full column
now manipulates a Arc<dyn ColumnValue> directly.

* CR comments

* Clippy

* Fixing regression

---------

Co-authored-by: Paul Masurel <paul.masurel@datadoghq.com>
2026-09-30 19:12:20 +02:00
Walter Woodall d5e2842575 fix: stream positions during sorted segment merges (#3116)
Sorted segment merges copied every document's positions for a term into a vector before sorting by mapped document ID. Common terms with many positions therefore consumed memory proportional to documents × positions, outside the indexing writer budget.

Stream shuffled postings through a min-heap with one cursor per input segment and one reusable positions buffer. The mapping preserves each segment's document order; deleted/filtered postings are skipped. The stacked path continues to stream directly.
2026-09-29 16:55:20 -07:00
palmoni5 637803de99 Add RegexPhraseQuery::from_regexes (#3138)
RegexQuery can be built from a compiled Regex, but RegexPhraseQuery always compiled its patterns with Regex::new and its default DFA state limit. from_regexes takes the compiled regexes directly, so a caller can build them with its own limits, or reuse ones it already compiled.
2026-09-29 11:45:00 +02:00
palmoni5 9e1b0de23a Expose the Levenshtein automaton of FuzzyTermQuery (#3136)
* Expose the Levenshtein automaton of FuzzyTermQuery

Callers that need the terms a fuzzy query expands to (e.g. to highlight them) had to copy the private DfaWrapper and depend on the same levenshtein_automata version as tantivy, or their expansion could silently diverge from the query's. FuzzyTermQuery::automaton returns the automaton the query matches with, built from the same cached LevenshteinAutomatonBuilder.

* Export DfaWrapper outside of tests

The re-export was still behind #[cfg(test)], so FuzzyTermQuery::automaton returned a type other crates could not name. A doctest now uses it from outside the crate.
2026-09-29 09:50:24 +02:00
palmoni5 88a17da8e9 Expose the fragment byte range on Snippet (#3134)
Snippet only kept a copy of the fragment text, so callers that need to extend the fragment or map it back to the source (e.g. to keep punctuation that the tokenizer leaves outside the last token) had to search for it, which picks the wrong occurrence when the same text appears earlier.
2026-09-29 09:28:29 +02:00
palmoni5 1d294ea6dc Cache RegexPhraseQuery's compiled regexes in the query (#3137)
Following up on #3135, the regexes are compiled on first use and kept in the query, so a query reused across searchers, or cloned, determinizes each pattern once. RegexPhraseQuery::regexes exposes them for callers that inspect the patterns before searching, e.g. to count a phrase's per-segment expansions against max_expansions, instead of compiling them a second time.
2026-09-29 09:19:07 +02:00
Paul MasurelandPaul Masurel 047464cf92 Accelerating jitexpr conditions using necessary conditions (#3129)
* jitexpr

* Added possible necessary conditions to jitexpr.

A function makes it possible to infer a necessary query from an expression to match.
We can then accelerate queries involving a calculated field by not even evaluating the expression
on docs that trivially do not match.

* CR comment

* CR comment

* Fixing unit tests

---------

Co-authored-by: Paul Masurel <paul.masurel@datadoghq.com>
2026-09-28 18:46:37 +02:00
palmoni5 b9125aad55 Compile RegexPhraseQuery regexes once per weight (#3135)
RegexPhraseWeight::phrase_scorer compiled every phrase term's regex again for each segment. Determinizing a wide pattern (e.g. an alternation of typo or morphology expansions) costs milliseconds to tens of milliseconds, so on a multi-segment index the query was dominated by recompiling the same automata. The regexes are now compiled in RegexPhraseQuery::regex_phrase_weight and shared through Arc.

An invalid pattern is now reported when the weight is built, instead of when the first segment is scored.
2026-09-28 11:37:50 +02:00
dayaffe 53e90ab192 Merge main into datasketches 0.5 update 2026-09-23 18:39:37 +00:00
Pascal Seitz e229de6db7 Collect decoded multi-term keys before assigning bucket positions 2026-09-22 19:53:52 +08:00
Pascal Seitz 7d3a3d6bfe Use unwrap_or(false) for missing bucket value check 2026-09-22 19:53:52 +08:00
Pascal Seitz 62f3d4b4dd Apply multi-terms cutoff before final bucket conversion
Avoid formatting keys and finalizing sub-aggregations for buckets
discarded by the final size limit. Preallocate the retained bucket vector
and reuse the cutoff helper with intermediate tuple keys.

Preserve final-key ordering and finalize the ordering metric when sorting
by a sub-aggregation. Cover mixed key types, empty sums, and discarded
document counts in tests.
2026-09-22 19:53:52 +08:00
Pascal Seitz 3655e6f8cb Batch multi-terms dictionary lookups after pruning
Resolve retained string ordinals in sorted batches per field instead
of decoding dictionary blocks separately for each tuple component.
Reuse decoding for repeated ordinals while preserving tuple order
and existing numeric and missing-value handling.
2026-09-22 19:53:52 +08:00
Pascal Seitz 085a8327d3 Merge incoming aggregation buckets into the accumulator
Probe the accumulated map only for incoming keys rather than rehashing every accumulated key on each merge. This removes quadratic work when folding many disjoint multi-terms results. The same helper serves range and composite buckets; existing bucket values still merge left-to-right and the wire representation and pruning rules are unchanged.

Cover overlapping/disjoint tuple keys, empty inputs, recursive range subaggregations, postcard round trips, error/count bookkeeping, and merging after pruning.

Same benchmark and configuration as 0062d2f0d (Apple M4 Max, rustc 1.98.0):
Median milliseconds for 10 / 100 / 1000 inputs:
shared 8:     0.006365 / 0.0656 / 0.6449
disjoint 16:  0.0126   / 0.1486 / 1.6882
disjoint 160: 0.1336   / 1.5558 / 20.4019
At 1000 inputs this is 52.4x and 61.6x faster for the disjoint cases, with unchanged measured peak allocation. Shared-key control remains within approximately 2% of baseline.

Validation: 308 aggregation tests pass with default features and 308 with quickwit; changed-file rustfmt and git diff checks pass. Clippy --lib --bench agg_bench passes with the pre-existing clippy::drop_non_drop warning allowed (unchanged drop(add_document) in the benchmark).
2026-09-22 19:53:52 +08:00
Paul MasurelandPaul Masurel 507e1760aa Minor refactor of the cardinality aggregation. (#3120)
The Str path and the non string path are very different.
This PR isolates them as different segment aggregation collector.

Co-authored-by: Paul Masurel <paul.masurel@datadoghq.com>
2026-09-22 10:47:49 +02:00
Paul Masurel b91a405ee9 Make aggregation request-data types crate-internal (#3110)
Hiding the per segment *AggReqData members

FilterAggReqData::reqandMultiTermsAggReqData::sub_aggregations` were dead code so they were removed.
2026-09-18 07:27:01 +02:00
Paul Masurel 1496f58963 Added jitexpr compilation cache (#3107)
* Added jitexpr compilation cache
* Added jitexpr to the CI test matrix
2026-09-17 10:34:15 +02:00
David Yaffe e69acca220 Fix cardinality calls for datasketches 0.5 2026-09-16 14:55:28 -04:00
Pascal Seitz 1680885e68 Report active RamDirectory writers as existing 2026-09-16 23:39:47 +08:00
Pascal Seitz e56587f3df Rename memory usage tracker finish to release 2026-09-16 23:39:47 +08:00
Pascal Seitz dfe904667e Minimize unrelated changes 2026-09-16 23:39:47 +08:00
Pascal Seitz a9d3f1a026 Run nightly fmt 2026-09-16 23:39:47 +08:00
Pascal Seitz bbc1b9e1d1 Restore TerminatingWrite API 2026-09-16 23:39:47 +08:00
Pascal Seitz 1c8a4801b3 Shrink RamDirectory files before storing 2026-09-16 23:39:47 +08:00
Pascal Seitz 2ab4fb80f0 Buffer RamDirectory writes
Use the standard BufWriter capacity to avoid forwarding every small write
directly to the underlying VecWriter.
2026-09-16 23:39:47 +08:00
Pascal Seitz e46d44c388 Finalize mmap writers in directory tests
Use finish instead of flush before reading completed files and clarify
when file data is synchronized.
2026-09-16 23:39:47 +08:00
Pascal Seitz f2a106df1c Prevent concurrent RamDirectory writers
Reserve paths when writers are opened and release reservations when
writers finish or drop.
2026-09-16 23:39:47 +08:00
Pascal Seitz 98d91f0436 Remove intermediate flush from directory contract
Intermediate writes are an implementation detail. From Tantivy side we only decide when a file is finished. This change is done to remove flush overhead for VecWriter. On finalization we just move the Vec to the directory.

Rename TerminatingWrite to FinishableWrite to reflect these semantics.
2026-09-16 23:39:47 +08:00
Pascal Seitz b06d8e9a04 Track active RamDirectory writer memory
Include VecWriter allocations in total_mem_usage so callers can account
for memory before writers are flushed or terminated.
2026-09-16 23:39:47 +08:00
Pascal Seitz 54b82e582f Report unsupported whitespace as a syntax error 2026-09-16 22:53:35 +08:00
Pascal SeitzandOleksii Syniakov 34edbf7821 Fix query parser panics on malformed input
Treat a fieldless exists leaf as match-all and make the lenient set parser
stop when parsing no longer consumes input. Add public QueryParser proptests
covering both regressions.

Findings and original fixes by Oleksii Syniakov in osyniakov/tantivy#4.

Co-authored-by: Oleksii Syniakov <1282756+osyniakov@users.noreply.github.com>
2026-09-16 22:53:35 +08:00
Pascal Seitz 4dddea5a5f Preserve tie breakers during columnar merges
Generate one random-offset linear tie-breaker sequence per segment and
preserve its values through normal columnar merging. Enable the linear
codec to keep initial segments compact.
2026-09-15 17:55:32 +02:00
Paul Masurel 94a116f103 (Calculated fields) Add feature-gated JIT expression document predicate (#3081) 2026-09-15 16:28:53 +02:00
Pascal Seitz e7ba845037 add FieldType::TieBreaker 2026-09-14 19:18:22 +02:00
Pascal Seitz 46ee982b52 add tie_breaker option 2026-09-14 17:26:01 +02:00
Paul MasurelandPaul Masurel 3bad51518a Fix clippy warnings in test code (#3091)
Silence the 7 warnings reported by `cargo clippy --all --tests`:

- Replace manual `% n == 0` parity checks with `is_multiple_of`
  (`manual_is_multiple_of`) in index_writer, doc_predicate_query and
  seek_danger tests. `is_multiple_of` is stable for unsigned integers as
  of 1.87, which matches the crate MSRV.
- Prefix the intentionally unused `other_segment_meta` binding with an
  underscore. The binding is kept rather than dropped because the
  inventory only tracks live `SegmentMeta`s, so dropping it would
  invalidate the `inventory.all()` assertion in the same test.

No behavior change.

Co-authored-by: Paul Masurel <paul.masurel@datadoghq.com>
2026-09-10 21:26:45 +02:00
Pascal Seitz 66ff8466d5 fix: disable buffered union seek_danger override
Use the default seek-based implementation until the optimized path can handle invalid child states safely. A child miss followed by another child hit previously allowed refill to consume an unaligned scorer.

Add shared seek_danger contract proptests, a regression for #3086, and a source inventory guard for future overrides.
2026-09-08 16:34:05 +02:00
pascal 780395c1db improve BufferedUnionScorer::advance 2026-09-08 18:12:08 +08:00
pascal 6929bae13f fix union performance regression 2026-09-08 18:12:08 +08:00
Paul MasurelandPaul Masurel 1020eba2b9 Expose segment file listing on IndexMeta (#3080)
Co-authored-by: Paul Masurel <paul.masurel@datadoghq.com>
2026-09-07 13:55:06 +02:00
Pascal Seitz 906fb8ef87 update comment 2026-09-07 18:26:37 +08:00
Pascal Seitz b586087392 fmt 2026-09-07 18:26:37 +08:00
Pascal Seitz ed1287a07f Preserve intermediate aggregation wire compatibility
Serialize vector-backed term entries as a map so Quickwit nodes running
different versions can exchange Postcard aggregation results. Add a legacy
fixture covering nested terms and histogram aggregations.
2026-09-07 18:26:37 +08:00
Pascal Seitz 921e98c63c Make count tie pruning deterministic at segment level 2026-09-07 18:26:37 +08:00