xiangfu0 commented on code in PR #19906:
URL: https://github.com/apache/pinot/pull/19906#discussion_r4296688465


##########
pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/memory/CompoundDataBuffer.java:
##########
@@ -112,21 +113,19 @@ private static DataBuffer[] 
asDataBufferArray(List<ByteBuffer> buffers) {
   }
 
   private int getBufferIndex(long offset) {
-    // this optimistically assumes that lookups are going to be in ascending 
order
-    // we don't care about concurrency here given that this is only used to 
speed up the lookup
+    // Most lookups land in the same buffer as the previous one, so check it 
first. Otherwise use a binary search,
+    // which keeps random and backward access at O(log n) instead of a scan 
from the first buffer.
+    // We don't care about concurrency here given that this is only used to 
speed up the lookup.
     int lastBufferIndex = _lastBufferIndex;
-    if (_bufferOffsets[lastBufferIndex] > offset) {
-      lastBufferIndex = 0;
-    }
-
-    for (int i = lastBufferIndex; i < _bufferOffsets.length; i++) {
-      if (offset < _bufferOffsets[i]) {
-        int result = i - 1;
-        _lastBufferIndex = result;
-        return result;
-      }
-    }
-    int result = _bufferOffsets.length - 1;
+    int nextBufferIndex = lastBufferIndex + 1;
+    if (_bufferOffsets[lastBufferIndex] <= offset
+        && (nextBufferIndex == _bufferOffsets.length || offset < 
_bufferOffsets[nextBufferIndex])) {
+      return lastBufferIndex;
+    }
+    // Offsets are strictly ascending because empty buffers are rejected. On a 
miss, binarySearch returns
+    // (-insertionPoint - 1), and the buffer that contains the offset is the 
one before the insertion point.
+    int index = Arrays.binarySearch(_bufferOffsets, offset);
+    int result = index >= 0 ? index : -index - 2;

Review Comment:
   This fixes a real quadratic: before, a backward lookup reset to index 0 and 
rescanned, which the DataTable merge path hit hard with thousands of pages read 
in column/random order. The `-index - 2` decode is correct since offset 0 is 
always present. Minor: the test exercises backward and random access well, but 
none of the buffer sizes exceed one entry boundary enough to make the old scan 
visibly quadratic — that is fine for a correctness test, just noting the perf 
win itself is not directly asserted.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to