Changes for version 1.04 - 2026-08-27
- FpIndex now caches opened segments and reuses them across searches instead of reopening every segment on every query. Opening a segment is a fixed per-query cost that otherwise dominated search time on a long-lived query server, regardless of the query. Segments are immutable append-only files, so a cached handle always maps the same bytes; a handle whose segment has been compacted out of the manifest is dropped on the next search. Results are unchanged.
- score() and FpIndex::search() take an optional minimum containment; matches below it are dropped inside the scorer instead of being returned for the caller to filter. A query dominated by common fingerprints can match hundreds of thousands of contents, almost all coincidental, so applying the floor at this level avoids building and returning them. Defaults to 0 (return everything).
- score() and FpIndex::search() also take an optional max_df: query fingerprints appearing in more than that many records of a segment are ignored (boilerplate that matches nearly everything, adding only coincidental hits and skewing containment). Off by default (0). Intended for a compacted single-segment index, where a segment's record count for a fingerprint is its document frequency.
Documentation
Modules
Next-generation license pattern matcher for Cavil
Provides
in lib/Cavil/Matcher/FpIndex.pm
in lib/Cavil/Matcher.pm
in lib/Cavil/Matcher/Index.pm
in lib/Cavil/Matcher/Manifest.pm