private int compatibleBinarySearch()

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);
    }