Repository navigation
Backport remaining Lucene 4.8.1 bug fixes #1381
Description
Is there an existing issue for this?
- I have searched the existing issues
Task description
We have effectively been targeting 4.8.1 instead of 4.8.0 for a while now, so we might as well close that gap before exploring #1293. This release includes some worthwhile bugfixes.
What follows is the analysis by Claude Code against the Lucene 4.8.1 source code and git history. There may be errors/omissions.
Background
Lucene.NET targets Lucene 4.8.1, but an audit of the upstream 4.8.0 → 4.8.1
diff (the 16 LUCENE-* bug fixes in lucene/CHANGES.txt) found that several
fixes were never ported. No existing issue tracks these. #1293 is explicitly
scoped to fixes after 4.8.1 (4.9-4.10), so this gap is currently untracked.
The fixes below match pre-fix 4.8.0 behavior in current master. They are
grouped into batches that can be broken out into sub-issues. Several are
trivial; one (LUCENE-5628) fixes a real StackOverflowException that is
already biting the port (AnalyzingSuggesterTest.TestTooLongSuggestion
sits commented out with a "currently produces a stack overflow" note).
Already ported (no action)
LUCENE-5662, LUCENE-5599/5600, LUCENE-5653, LUCENE-5559, LUCENE-5644,
LUCENE-5671 are all present, with matching tests for 5653, 5559, and 5599/5600.
Remaining work
Batch 1 — Trivial production fixes (1-5 lines each)
PR: #1413
- LUCENE-5635: move
stream.Reset()inside thetryblock in
DocInverterPerField.cs(~line 107) so an exception on reset is handled. - LUCENE-5668: change
eligible.Count >= allowedSegCountIntto>in
TieredMergePolicy.cs(~line 415); port thetestUnbalancedMergeSelection
test. - LUCENE-5656: move
dvGens.Add(gen)inside the per-gen loop in
SegmentReader.cs(~lines 197-209) instead ofAddRangeafter the loop
(rare fd leak on docvalues-update exception). - LUCENE-5644 follow-up: add the missing
PulseAll/notifyAllat the
end ofDeactivateUnreleasedStates()inDocumentsWriterPerThreadPool.cs.
Batch 2 — LUCENE-5641 (RateLimiter)
PR: #1420
- Rewrite
RateLimiter.cs: addMinPauseCheckBytes, synchronizePause,
dropnsPerByte/lastNSand thebytes == 1shortcut. - Update
RateLimitedIndexOutput.csto accumulatebytesSinceLastPause
and only callPausewhen it exceedsMinPauseCheckBytes. - Port the multithreaded
TestRateLimiter.testThreads.
Fixes the "silently rate-limits at 8 MB/sec regardless of configured rate" bug.
Batch 3 — LUCENE-5639 (Token.PositionLength)
PR: #1421
- Wire
positionLengthinto all 9 sites inToken.cs:Clear,Clone,
Equals,GetHashCode,ClearNoTermBuffer, the privateReinit, the three
Reinit(Token …)overloads,CopyTo, andReflectWith. (The field/property
exist but none of the handling is wired up.) - Add the
positionLengthattribute-map entry inTestToken.
Batch 4 — LUCENE-5628 + LUCENE-5660 (highest priority)
PR: #1422
- LUCENE-5628: make
GetFiniteStringsiterative (PathNode stack) in
SpecialOperations.csinstead of recursive (one stack frame per character). - LUCENE-5660: re-enable the suggester guard in
AnalyzingSuggester.cs
(currentlyDebugging.Assert(SpecialOperations.IsFinite(...))at ~line 982). - OfflineSorter: add the
len > short.MaxValueguard in
ByteSequencesWriter.Write(OfflineSorter.cs). - Add the
GetFiniteStringsRecursivehelper toAutomatonTestUtil.cs. - Port the full 4.8.1
TestSpecialOperationssuite and un-comment
AnalyzingSuggesterTest.TestTooLongSuggestion(AnalyzingSuggesterTest.cs
~line 1502).
Resolves an active StackOverflowException already stubbed out in the suite.
Batch 5 — LUCENE-5654 + test infrastructure (largest; gated by infra)
PR: #1424
- Production: convert the 4 close() call sites to the success-boolean
pattern:CompoundFileDirectory,CompoundFileWriter,Directory.Copy, and
FSDirectoryoutput close. (Keep the existing
DisposeWhileHandlingException(priorException, …)IOUtils overloads — only
the call sites change.) - Test framework prerequisite: port the entire cranky codec package
(9 files:CrankyCodec+CrankyDocValues/FieldInfos/LiveDocs/Norms/ Postings/SegmentInfo/StoredFields/TermVectorsFormat). OnlyCrankyTokenFilter
is ported today. - Tests (blocked on the two prerequisites above): port
TestIndexWriterExceptions2,TestIndexWriterOutOfMemory, and
TestIndexWriterThreadsToSegments(the last validates LUCENE-5644). - LUCENE-5644 follow-up (
011a35b0a, no JIRA): add active-thread-state counting + infoStream message toFindLargestNonPendingWriterinFlushPolicy.cs(~line 131) and prefix theFlushByRamOrCountsPolicy.csflush message with"trigger "(~line 100).
Suggested sequencing
Batches 1-4 are independent and deliver all user-facing production fixes;
Batch 4 first since it resolves an active stack-overflow. Batch 5 is a
larger infra investment whose production payload (5654) is lower-risk, so it's
a reasonable last step.
Activity
paulirwin commentedon Jul 12, 2026
Regarding Batch 2 (the "silently rate-limits at 8 MB/sec regardless of configured rate" bug), it's not actually a problem on .NET because of how we do our integer division math. A throwaway rate limiter benchmark found that current master code does scale properly to the configured limit:
So while we don't strictly have to "fix" this part of it since it isn't broken for the original reason, there is a possible race condition here with the
lastNSfield that was fixed by making itsynchronized, so we should backport this change regardless. It'll also help ensure we're in sync with upstream.Port partial commit 881e0836df4 for LUCENE-5635 from 4.8.1
Port RateLimiter fixes from Lucene 4.8.1, #1381 (#1420)
Port fix for Token's positionLength from Lucene 4.8.1, #1381 (#1421)
Port trivial production fixes from Lucene 4.8.1, #1381 Batch 1 (#1413)
Port Lucene 4.8.1 fixes for AnalyzingSuggester, OfflineSorter, and Sp…