From 435e1c549bcb0ab7c3b67ed1158a484eafa31c70 Mon Sep 17 00:00:00 2001 From: WJL3333 Date: Sat, 3 Feb 2024 00:55:28 +0800 Subject: [PATCH] perf(s3stream): cache parsed DataBlockIndex for IndexBlock --- .../java/com/automq/stream/s3/ObjectReader.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/s3stream/src/main/java/com/automq/stream/s3/ObjectReader.java b/s3stream/src/main/java/com/automq/stream/s3/ObjectReader.java index 271147a55..2832f2b90 100644 --- a/s3stream/src/main/java/com/automq/stream/s3/ObjectReader.java +++ b/s3stream/src/main/java/com/automq/stream/s3/ObjectReader.java @@ -200,12 +200,14 @@ public static class IndexBlock { private final ByteBuf buf; private final int size; private final int count; + private DataBlockIndex[] dataBlockIndices; public IndexBlock(S3ObjectMetadata s3ObjectMetadata, ByteBuf buf) { this.s3ObjectMetadata = s3ObjectMetadata; this.buf = buf; this.size = buf.readableBytes(); this.count = buf.readableBytes() / INDEX_BLOCK_UNIT_SIZE; + this.dataBlockIndices = new DataBlockIndex[count]; } public Iterator iterator() { @@ -227,6 +229,12 @@ public DataBlockIndex get(int index) { if (index < 0 || index >= count) { throw new IllegalArgumentException("index" + index + " is out of range [0, " + count + ")"); } + + // the buf is readonly so just check if the entry have been parsed. + if (dataBlockIndices[index] != null) { + return dataBlockIndices[index]; + } + int base = index * INDEX_BLOCK_UNIT_SIZE; long streamId = buf.getLong(base); long startOffset = buf.getLong(base + 8); @@ -234,7 +242,12 @@ public DataBlockIndex get(int index) { int recordCount = buf.getInt(base + 20); long blockPosition = buf.getLong(base + 24); int blockSize = buf.getInt(base + 32); - return new DataBlockIndex(streamId, startOffset, endOffsetDelta, recordCount, blockPosition, blockSize); + + DataBlockIndex idx = + new DataBlockIndex(streamId, startOffset, endOffsetDelta, recordCount, blockPosition, blockSize); + dataBlockIndices[index] = idx; + + return idx; } public FindIndexResult find(long streamId, long startOffset, long endOffset) {