From d3b75605d006a6e715d7b745aa090f5c2e74e4bc Mon Sep 17 00:00:00 2001 From: Bertil Chapuis Date: Thu, 27 Jun 2024 08:53:43 +0200 Subject: [PATCH] Skip bytes with a small buffer --- .../baremaps/flatgeobuf/FlatGeoBufReader.java | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBufReader.java b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBufReader.java index 086352fd7..7a2c10925 100644 --- a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBufReader.java +++ b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBufReader.java @@ -40,7 +40,10 @@ */ public class FlatGeoBufReader implements AutoCloseable { - private final ByteBuffer buffer = ByteBuffer.allocate(1 << 16).order(ByteOrder.LITTLE_ENDIAN); + private static final int DEFAULT_BUFFER_SIZE = 1 << 16; + + private final ByteBuffer featureBuffer = + ByteBuffer.allocate(DEFAULT_BUFFER_SIZE).order(ByteOrder.LITTLE_ENDIAN); private final ReadableByteChannel channel; @@ -60,11 +63,11 @@ public FlatGeoBuf.Header readHeader() throws IOException { } public Feature readFeatureBuffer() throws IOException { - return readFeatureBuffer(channel, buffer); + return readFeatureBuffer(channel, featureBuffer); } public FlatGeoBuf.Feature readFeature() throws IOException { - return readFeature(channel, header, buffer); + return readFeature(channel, header, featureBuffer); } public void skipIndex() throws IOException { @@ -338,7 +341,36 @@ public void close() throws IOException { public static void skipIndex(ReadableByteChannel channel, Header header) throws IOException { - readIndexBuffer(channel, header); + long n = PackedRTree.calcSize(header.featuresCount(), header.indexNodeSize()); + + // Define a buffer size for skipping bytes + int bufferSize = DEFAULT_BUFFER_SIZE; + ByteBuffer buffer = ByteBuffer.allocate(bufferSize); + + // Number of bytes left to skip + long remaining = n; + + while (remaining > 0) { + // Calculate how many bytes to read in this iteration + int bytesToRead = (int) Math.min(bufferSize, remaining); + + // Set the buffer limit to the number of bytes to read + buffer.limit(bytesToRead); + + // Read bytes into the buffer + int bytesRead = channel.read(buffer); + + // Check if end of stream is reached + if (bytesRead == -1) { + throw new IOException("End of stream reached before skipping the required number of bytes"); + } + + // Update the remaining bytes to skip + remaining -= bytesRead; + + // Clear the buffer for the next read + buffer.clear(); + } } public static ByteBuffer readIndexBuffer(ReadableByteChannel channel, Header header)