in environment/src/main/java/jetbrains/exodus/tree/btree/BasePageImmutable.java [306:374]
private int compatibleBinarySearch(final ByteIterable key, int low) {
final int cachePageSize = log.getCachePageSize();
final int bytesPerAddress = keyAddressLen;
final long dataAddress = this.getDataAddress();
int high = size - 1;
long leftAddress = -1L;
byte[] leftPage = null;
long rightAddress = -1L;
byte[] rightPage = null;
while (low <= high) {
final int mid = (low + high) >>> 1;
final long midAddress =
log.adjustLoggableAddress(dataAddress, (((long) mid) * bytesPerAddress));
final int offset;
final int adjustedPageSize;
if (formatWithHashCodeIsUsed) {
adjustedPageSize = cachePageSize - BufferedDataWriter.HASH_CODE_SIZE;
} else {
adjustedPageSize = cachePageSize;
}
@SuppressWarnings("ObjectAllocationInLoop")
final BinarySearchIterator it = new BinarySearchIterator(adjustedPageSize);
it.offset = offset = ((int) midAddress) & (cachePageSize - 1); // cache page size is always a power of 2
final long pageAddress = midAddress - offset;
if (pageAddress == leftAddress) {
it.page = leftPage;
} else if (pageAddress == rightAddress) {
it.page = rightPage;
} else {
it.page = leftPage = log.getCachedPage(pageAddress);
leftAddress = pageAddress;
}
final long leafAddress;
if (adjustedPageSize - offset < bytesPerAddress) {
final long nextPageAddress = pageAddress + cachePageSize;
if (rightAddress == nextPageAddress) {
it.nextPage = rightPage;
} else {
it.nextPage = rightPage = log.getCachedPage(nextPageAddress);
rightAddress = nextPageAddress;
}
//noinspection ObjectAllocationInLoop
leafAddress = it.asCompound().nextLong(bytesPerAddress);
} else {
leafAddress = it.nextLong(bytesPerAddress);
}
final int cmp = tree.compareLeafToKey(leafAddress, key);
if (cmp < 0) {
low = mid + 1;
} else if (cmp > 0) {
high = mid - 1;
} else {
// key found
return mid;
}
}
// key not found
return -(low + 1);
}