Changelog
View SourceAll notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.7.1] - 2026-07-19
Fixed
- Roaring NIF: guard the decode output allocation against a
size_tmultiply overflow, and validate a deserialized bitmap before any set op reads it (a corrupt or bit-rotted segment now fails cleanly). - A manifest-save error during freeze no longer crashes the shard: the
orphan segment is dropped and the buffer and watermark are kept (the tail
replays).
manifest:save/1tolerates anensure_direrror. refreshdrain stops when a full feed batch does not advance the watermark, so it cannot spin.open/2rolls back any shards it already started if a later shard fails, so a partial open leaves nothing orphaned; a shard is now atransientchild, so an abnormal crash restarts it instead of leaving the corpus with no live shard.- A query reads a shard's segments and buffer in one atomic call, so it never straddles a freeze.
[0.7.0] - 2026-07-19
Added
- Roaring-bitmap posting codec (opt in per corpus with
postings => roaring). Posting lists are stored as roaring bitmaps and intersected with a native AND in a self-contained NIF (barrel_ngram_roaring, vendored CRoaring), removing the delta+varint decode cost for large dense corpora. On the intersection benchmark, twelve 50k-ordinal lists intersect in ~0.1 ms versus ~140 ms for varint.varintstays the default (it wins on small lists); results are identical either way (a differential oracle holds roaring byte-for-byte against varint).
Changed
- Segment format bumped to v3 (a per-segment codec byte). This is barrel_ngram's first C: the roaring NIF is built by cmake at compile time.
Added
- Task-oriented documentation under
docs/(getting started, selectors, regex, sharding, operations, the MCP tool, and design), wired into ex_doc.
[0.6.1] - 2026-07-19
Added
barrel_ngram:is_open/1, a cheap check of whether a corpus is open (used by callers that lazily open a corpus, such as the MCP tool).
[0.6.0] - 2026-07-19
Added
- Sharding: a corpus can be spread across N shards by rendezvous hashing
on the document key (
openoptionshards => N, default 1). Each shard indexes only its slice; queries fan out across shards and merge. Because a document is owned by exactly one shard, results are identical to a single-shard corpus. New self-containedbarrel_ngram_shardsmodule.
[0.5.0] - 2026-07-19
Added
- Regex search (
barrel_ngram:regex/2,3, PCRE syntax). A regex is turned into a mandatory-trigram boolean query (Russ Cox / Google Code Search) that is intersected and unioned over the posting lists, then each candidate is confirmed with a boundedre:run. The analysis is always sound (unsure constructs contribute no constraint), so results are exact. Trigram-accelerated on dense corpora; sparse corpora brute-force since their index holds only a sample of grams. barrel_ngram_postings:union_all/1and acovers_all_grams/1selector callback (the regex planner uses the trigram query only when the index is complete).
[0.4.0] - 2026-07-19
Added
- Sparse (content-defined) gram selector: a trigram is kept only when a
hash of its local byte window passes a sampling test, shrinking the
index. The query planner intersects only over grams whose window falls
entirely inside the literal, and falls back to a brute-force scan for
short literals, so results stay exact. Opt in per corpus with
selector => barrel_ngram_selector_sparseandselector_opts.
Changed
- The selector behaviour callbacks now take an options map
(
select_grams/2,reliable_grams/2), carrying per-selector tuning.
[0.3.0] - 2026-07-19
Added
- Compaction: an offloaded worker merges live segments into one,
collapsing each key to its newest version by HLC and physically
evicting superseded and deleted entries. Fires automatically when the
segment count crosses a threshold (
compact_threshold), andbarrel_ngram:compact/1runs it synchronously. - Deletes are recorded as segment tombstones so compaction can evict them; the segment sidecar (format v2) carries a per-ordinal change HLC and deleted flag.
Changed
- Segment format bumped to v2. The manifest rename remains the sole commit point, so a crash mid-merge leaves an orphan segment that is cleaned up on the next open.
[0.2.0] - 2026-07-19
Added
- Incremental live indexing: a corpus subscribes to its database's changes
feed (push mode) and keeps in sync in the background. Updates and deletes
are reflected in results through the confirm pass, which re-fetches the
current document and drops
not_found. - Multi-segment storage with a crash-safe manifest (
barrel_ngram_manifest), written atomically (temp + rename); the manifest commit is the recovery point, and orphan segments from a crash before commit are cleared at start. - Query fans across every live segment plus the unfrozen buffer.
- Recovery replays only the feed tail since the persisted HLC watermark.
barrel_ngram:refresh/1: synchronous catch-up + freeze;index/1now delegates to it.
[0.1.0] - 2026-07-18
Added
- Dense trigram substring index over
barrel_docdb. A corpus is bound to a database and built one-shot from the changes feed; queries turn a literal into its overlapping trigrams, intersect posting lists, and confirm each candidate against the real document text. - Immutable segment format: a direct-addressed
u32offset table over the 2^24 gram space, delta+varint posting lists, and an ordinal-to-key sidecar, read withfile:pread. barrel_ngram_selectorbehaviour with a dense selector, the shared seam between the indexer and the query planner.- Public API:
open/2,index/1,search/2,3,close/1.