
org.elasticsearch.common.util.BinarySearcher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elasticsearch Show documentation
Show all versions of elasticsearch Show documentation
Elasticsearch - Open Source, Distributed, RESTful Search Engine
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.common.util;
/**
* Performs binary search on an arbitrary data structure.
*
* To do a search, create a subclass and implement custom {@link #compare(int)} and {@link #distance(int)} methods.
*
* {@link BinarySearcher} knows nothing about the value being searched for or the underlying data structure.
* These things should be determined by the subclass in its overridden methods.
*
* Refer to {@link BigArrays.DoubleBinarySearcher} for an example.
*
* NOTE: this class is not thread safe
*/
public abstract class BinarySearcher {
/**
* @return a negative integer, zero, or a positive integer if the array's value at index
is less than,
* equal to, or greater than the value being searched for.
*/
protected abstract int compare(int index);
/**
* @return the magnitude of the distance between the element at index
and the value being searched for.
* It will usually be Math.abs(array[index] - searchValue)
.
*/
protected abstract double distance(int index);
/**
* @return the index who's underlying value is closest to the value being searched for.
*/
private int getClosestIndex(int index1, int index2) {
if (distance(index1) < distance(index2)) {
return index1;
} else {
return index2;
}
}
/**
* Uses a binary search to determine the index of the element within the index range {from, ... , to} that is
* closest to the search value.
*
* Unlike most binary search implementations, the value being searched for is not an argument to search method.
* Rather, this value should be stored by the subclass along with the underlying array.
*
* @return the index of the closest element.
*
* Requires: The underlying array should be sorted.
**/
public int search(int from, int to) {
while (from < to) {
int mid = (from + to) >>> 1;
int compareResult = compare(mid);
if (compareResult == 0) {
// arr[mid] == value
return mid;
} else if (compareResult < 0) {
// arr[mid] < val
if (mid < to) {
// Check if val is between (mid, mid + 1) before setting left = mid + 1
// (mid < to) ensures that mid + 1 is not out of bounds
int compareValAfterMid = compare(mid + 1);
if (compareValAfterMid > 0) {
return getClosestIndex(mid, mid + 1);
}
} else if (mid == to) {
// val > arr[mid] and there are no more elements above mid, so mid is the closest
return mid;
}
from = mid + 1;
} else {
// arr[mid] > val
if (mid > from) {
// Check if val is between (mid - 1, mid)
// (mid > from) ensures that mid - 1 is not out of bounds
int compareValBeforeMid = compare(mid - 1);
if (compareValBeforeMid < 0) {
// val is between indices (mid - 1), mid
return getClosestIndex(mid, mid - 1);
}
} else if (mid == 0) {
// val < arr[mid] and there are no more candidates below mid, so mid is the closest
return mid;
}
to = mid - 1;
}
}
return from;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy