Skip to content

Commit a2347c6

Browse files
paulirwinclaude
andcommitted
Document why MapChunks doesn't allocate a trailing zero-length sentinel
Upstream Java's MMapDirectory.map allocates nrBuffers = floor + 1 and tolerates a final 0-byte ByteBuffer at `buffers[N]`. That sentinel exists because ByteBufferIndexInput's read loop unconditionally advances its buffer cursor past the end of each buffer, so indexing `buffers[N]` must remain valid after reading the last byte of a file whose length is a whole multiple of chunkSize. Our ReadInternal bounds-checks `pos + len` before indexing and only advances `chunkIdx` while `len > 0`, so no sentinel is needed. Also, MemoryMappedFile.CreateViewAccessor rejects a zero-length view, which would force a special-case code path anyway. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 3da3c56 commit a2347c6

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

src/Lucene.Net/Store/MMapDirectory.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,18 @@ private static Chunk[] MapChunks(MemoryMappedFile? mmf, long offset, long length
808808
}
809809

810810
long chunkSize = 1L << chunkSizePower;
811+
// LUCENENET specific: ceiling-divide, so nChunks covers exactly
812+
// the requested range with no trailing empty slot. Upstream
813+
// Java (MMapDirectory.map) instead allocates nrBuffers = floor + 1
814+
// and tolerates a final 0-byte ByteBuffer — a sentinel required
815+
// because ByteBufferIndexInput's read loop unconditionally
816+
// advances the buffer cursor past the end of each buffer, so
817+
// indexing `buffers[N]` must be valid after the last byte of a
818+
// file whose length is a whole multiple of chunkSize. We don't
819+
// need that here: ReadInternal bounds-checks `pos + len` before
820+
// indexing and only advances `chunkIdx` while `len > 0`. Also,
821+
// MemoryMappedFile.CreateViewAccessor rejects a zero-length view,
822+
// so a sentinel would require a special-case code path anyway.
811823
int nChunks = (int)((length + chunkSize - 1) >> chunkSizePower);
812824
var result = new Chunk[nChunks];
813825

0 commit comments

Comments
 (0)