Section navigation

Added

  • Pluggable stored-field compression via the IFieldCompressionCodec interface and CompressionCodecRegistry; any codec can be registered at startup without modifying core library code.
  • BCL codecs for None, Deflate, and Brotli policies using System.IO.Compression; available in the core package with no additional dependencies.
  • Optional Rowles.LeanCorpus.Compression.* packages:
    • Rowles.LeanCorpus.Compression.LZ4, via K4os.Compression.LZ4.
    • Rowles.LeanCorpus.Compression.Snappy, via Snappier.
    • Rowles.LeanCorpus.Compression.Zstandard, via ZstdSharp.
  • Rowles.LeanCorpus.Benchmarks.Compression project benchmarking compress and decompress throughput across all six policies at three payload sizes (128 B, 4 KB, 64 KB).
  • Richer DocValues support with sorted-set (.dss), sorted-numeric (.dsn), and binary (.dvb) sidecars for repeated StringField, repeated NumericField, and stored-field values, letting facets, grouping fallback, sorting fallback, and numeric aggregations avoid stored-field scans.
  • Public index format inventory API through IndexFormatInspector.Inspect, reporting commit generation, segment IDs, codec files, codec versions, DocValues sidecars, vector files, HNSW files, live-doc generations, and orphan files.
  • Public compatibility API through IndexCompatibility.Check, plus reader and writer open guardrails for unsupported future formats, required migrations, and incomplete migration markers.
  • Public codec migration API through IndexCodecMigrator.Plan and IndexCodecMigrator.Migrate, with dry-run planning, staged migration, migration markers, rollback, abandon, and executable rewrites for readable term dictionary, numeric DocValues, sorted DocValues, field-length, and stored-field codec upgrades.
  • Public IndexValidator.Check API and System.CommandLine based leancorpus-cli.exe commands for check, inspect, compat, and migrate.
  • Public IndexBackup API and leancorpus-cli.exe backup/restore commands for manifest-backed snapshot backups. Manifests record commit generation, content token, file names, file lengths, CRC-32 checksums, and file roles before restore validation.
  • Maintenance diagnostics for IndexFormatInspector, IndexCodecMigrator, and IndexBackup using ActivitySource spans and Meter instruments under Rowles.LeanCorpus.
  • Rowles.LeanCorpus.Example.NewsgroupsIndexer, a console example using the shared bench\data\20newsgroups data for creating checker test indexes.
  • Script documentation and a send-for-bench.ps1 helper for starting remote Debian benchmark runs in tmux.

Changed

  • Renamed the project, package family, namespaces, command-line tool, scripts, workflows, and documentation to Rowles.LeanCorpus and LeanCorpus.
  • Prepared the optional compression packages for their first NuGet release at version 1.0.0, with package metadata, README, and licence files.
  • Default stored-field compression policy changed from Brotli (via NativeCompressions) to FieldCompressionPolicy.Deflate using BCL DeflateStream.
  • Extension package assemblies auto-register their codec via [ModuleInitializer] in standard .NET hosts; Native AOT consumers must call Register() explicitly at startup.
  • src/ reorganised into src/core/ (main library and compression packages) and src/devops/ (benchmarks and tests).
  • SortedNumericDocValues reduced per-document allocations on the read path by reusing buffers and avoiding redundant array materialisation.
  • DocValues presence-bitmap writers now write directly from the underlying MemoryStream buffer instead of materialising a new array.
  • Postings writer caches HasFreqs/HasPositions per field and adds a bulk AddPositions path to reduce per-token virtual dispatch.
  • IndexSort serialised field list is pre-computed once per snapshot rather than per segment.
  • StoredFieldsWriter pools the distinct field-id dedup buffer across documents.
  • Pending-delete handling reuses a qualified-term list rather than allocating per flush.
  • Norms and field-length writes are fused into a single loop, term-vector dictionaries are built lazily, and DocValues key snapshots are pooled.
  • Vector field lookup is pre-built once per writer and DocValues key snapshots are pooled.
  • Field-sorted top-N selection now uses PriorityQueue<TElement, TPriority> with an int[] doc-id map in place of SortedSet<T>.
  • DocumentsWriterPerThread migrated to flat stored-field buffers with a bulk position-merge path, removing per-document list allocations during indexing.
  • Zstandard compression now pools compressor and decompressor instances rather than allocating a native wrapper per block.
  • IndexValidator now reports structured issues with severity, stable codes, segment IDs, file names, and repairability flags, and can opt into deep checks for postings, stored fields, DocValues, vectors, HNSW, and live docs.
  • The command-line checker project now builds as leancorpus-cli.exe, uses System.CommandLine, and supports JSON and file output across validation, inspection, compatibility, and migration commands.
  • Commit, segment metadata, live-doc, segment stats, and migration marker writes now share the same temp-file publication helper, and validation reports recognised stale temp files and partial migration markers.
  • The test suite is split into Rowles.LeanCorpus.Tests.Unit, Rowles.LeanCorpus.Tests.Integration, Rowles.LeanCorpus.Tests.Chaos, and Rowles.LeanCorpus.Tests.Shared, with test sources moved into their owning projects.
  • Common target framework, nullable, implicit using, xUnit using, packability, package versions, and NuGet source mapping configuration is centralised through Directory.Build.props, Directory.Packages.props, and root NuGet.config.
  • The GitHub build workflow now runs on main and 1.3.0, and includes the compression parity test project.

Fixed

  • BinaryDocValuesReader, SortedNumericDocValuesReader, and SortedSetDocValuesReader now reject corrupt offset tables. Initial offsets must be zero, and binary terminal offsets must equal the total payload length; previously, malformed sidecars could silently skip or expose unrelated bytes.
  • LZ4 and uncompressed stored-field codecs now reject impossible compressed/original length combinations instead of accepting corrupt empty or oversized payload metadata.
  • Stored-field codec migration now streams existing documents into temporary .fdt.tmp and .fdx.tmp files before publication, avoiding Windows file-handle conflicts without buffering the whole segment.
  • Codec migration now plans richer DocValues rewrites, publishes in-place rewrites through temporary files, removes published staging directories, and marks unexpected migration failures as failed.
  • Fuzzy term lookup, searcher refresh observation, and query cache top-N keying now behave deterministically under the full test suite.
  • Integration tests migrated from Assert.True(...Any(...)) to Assert.Contains with StringComparison.Ordinal; fuzzy-query test corrected to use well-defined edit-distance data.
  • Docs site header was missing the Coverage link; toc.yml and docfx.json updated to include the coverage report.
  • Build workflow branch list updated from 1.3.0 to 1.4.0.
  • Benchmark result method names corrected from LeanCorpus_ to LeanLucene_.

Removed

  • Dependency on NativeCompressions (preview package) removed from the core library.