Skip to content

Commit 2624387

Browse files
oschwaldclaude
andcommitted
Use stream channel for size lookup
`database.length()` is a path-based `stat(2)`, which can race with file replacement between the `FileInputStream` open and the size lookup — the bytes the stream then delivers may not match the size we read. Switch to `stream.getChannel().size()`, which is an `fstat` on the already-open file descriptor and therefore atomic with the open. `FileChannelImpl.getChannel()` is lazy and `.size()` is a stat-only syscall, so this does not reintroduce the per-thread direct ByteBuffer cache that the previous commit was fixing — that cache only grows when `FileChannel.read(heapByteBuffer)` is called. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent cbf83d9 commit 2624387

1 file changed

Lines changed: 3 additions & 1 deletion

File tree

src/main/java/com/maxmind/db/BufferHolder.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ final class BufferHolder {
3131
// mode that would mean chunkSize bytes of off-heap memory held per loader
3232
// thread for the JVM's lifetime.
3333
try (FileInputStream stream = new FileInputStream(database)) {
34-
long size = database.length();
34+
// Size from the open fd (fstat) so it's atomic with the open;
35+
// getChannel().size() does not populate the buffer cache.
36+
long size = stream.getChannel().size();
3537
var name = database.getName();
3638
if (size <= chunkSize) {
3739
this.buffer = SingleBuffer.wrap(readFully(stream, (int) size, name));

0 commit comments

Comments
 (0)