/** * Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.linkedin.pinot.core.indexsegment.utils; public class SearchableByteBufferUtil { private final GenericRowColumnDataFileReader mmappedDataFile; public SearchableByteBufferUtil(GenericRowColumnDataFileReader mmappedDataFile) { this.mmappedDataFile = mmappedDataFile; } /** * * @param col * @param value * @return */ public int binarySearch(int col, short value) { final int rows = mmappedDataFile.getNumberOfRows(); if (rows == 0) { return -1; } int low = 0; int high = rows - 1; while (low <= high) { final int middle = (low + high) / 2; final short midValue = mmappedDataFile.getShort(middle, col); if (value > midValue) { low = middle + 1; } else if (value < midValue) { high = middle - 1; } else { return middle; } } return -(low + 1); } /** * * @param col * @param value * @param from * @param to * @return */ public int binarySearch(int col, double value, int from, int to) { // This is ill defined, because both 1.0 < Double.NaN and Double.NaN < 1.0 are false assert !Double.isNaN(value); final int rows = mmappedDataFile.getNumberOfRows(); if (rows == 0) { return -1; } int low = from; int high = to - 1; while (low <= high) { final int middle = (low + high) / 2; final double midValue = mmappedDataFile.getDouble(middle, col); if (value > midValue) { low = middle + 1; } else if (value < midValue) { high = middle - 1; } else { return middle; } } return -(low + 1); } /** * * @param col * @param value * @return */ public int binarySearch(int col, double value) { return binarySearch(col, value, 0, mmappedDataFile.getNumberOfRows()); } /** * * @param col * @param value * @param from * @param to * @return */ public int binarySearch(int col, int value, int from, int to) { final int rows = mmappedDataFile.getNumberOfRows(); if (rows == 0) { return -1; } int low = from; int high = to - 1; while (low <= high) { final int middle = (low + high) / 2; final int midValue = mmappedDataFile.getInt(middle, col); if (value > midValue) { low = middle + 1; } else if (value < midValue) { high = middle - 1; } else { return middle; } } return -(low + 1); } /** * * @param col * @param value * @return */ public int binarySearch(int col, int value) { return binarySearch(col, value, 0, mmappedDataFile.getNumberOfRows()); } /** * * @param col * @param value * @param from * @param to * @return */ public int binarySearch(int col, long value, int from, int to) { final int rows = mmappedDataFile.getNumberOfRows(); if (rows == 0) { return -1; } int low = from; int high = to - 1; while (low <= high) { final int middle = (low + high) / 2; final long midValue = mmappedDataFile.getLong(middle, col); if (value > midValue) { low = middle + 1; } else if (value < midValue) { high = middle - 1; } else { return middle; } } return -(low + 1); } /** * * @param col * @param value * @return */ public int binarySearch(int col, long value) { return binarySearch(col, value, 0, mmappedDataFile.getNumberOfRows()); } /** * * @param col * @param value * @param from * @param to * @return */ public int binarySearch(int col, float value, int from, int to) { // This is ill defined, because both 1.0 < Float.NaN and Float.NaN < 1.0 are false assert !Float.isNaN(value); final int rows = mmappedDataFile.getNumberOfRows(); if (rows == 0) { return -1; } int low = from; int high = to - 1; while (low <= high) { final int middle = (low + high) / 2; final float midValue = mmappedDataFile.getFloat(middle, col); if (value > midValue) { low = middle + 1; } else if (value < midValue) { high = middle - 1; } else { return middle; } } return -(low + 1); } /** * * @param col * @param value * @return */ public int binarySearch(int col, float value) { return binarySearch(col, value, 0, mmappedDataFile.getNumberOfRows()); } /** * * @param col * @param value * @param padLength : length of padding to left pad the string * @param padChar : char to pad left * @return */ public int binarySearch(int col, String value, int padLength, char padChar) { String paddedString = value; for (int i = 0; i < padLength; i++) { paddedString += padChar; } return binarySearch(col, paddedString); } /** * * @param col * @param value: string to search in the dictionary, caller to pad it. * @return */ public int binarySearch(int col, String value) { final int rows = mmappedDataFile.getNumberOfRows(); if (rows == 0 || mmappedDataFile.getColumnSizes()[col] < value.length()) { return -1; } int low = 0; int high = rows - 1; while (low <= high) { final int middle = (low + high) / 2; final String midValue = mmappedDataFile.getString(middle, col); if (midValue.compareTo(value) > 0) { high = middle - 1; } else if (midValue.compareTo(value) < 0) { low = middle + 1; } else { return middle; } } return -(low + 1); } }