-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor common parts from the Rounding class into a separate 'round'…
… package Signed-off-by: Ketan Verma <ketan9495@gmail.com>
- Loading branch information
Showing
10 changed files
with
271 additions
and
147 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
libs/common/src/main/java/org/opensearch/common/round/BidirectionalLinearSearcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.common.round; | ||
|
||
import org.opensearch.common.annotation.InternalApi; | ||
|
||
/** | ||
* It uses linear search on a sorted array of pre-computed round-down points. | ||
* For small inputs (≤ 64 elements), this can be much faster than binary search as it avoids the penalty of | ||
* branch mispredictions and pipeline stalls, and accesses memory sequentially. | ||
* | ||
* <p> | ||
* It uses "meet in the middle" linear search to avoid the worst case scenario when the desired element is present | ||
* at either side of the array. This is helpful for time-series data where velocity increases over time, so more | ||
* documents are likely to find a greater timestamp which is likely to be present on the right end of the array. | ||
* | ||
* @opensearch.internal | ||
*/ | ||
@InternalApi | ||
class BidirectionalLinearSearcher implements Roundable { | ||
private final long[] ascending; | ||
private final long[] descending; | ||
|
||
public BidirectionalLinearSearcher(long[] values, int size) { | ||
assert size > 0 : "at least one value must be present"; | ||
|
||
int len = (size + 1) >>> 1; // rounded-up to handle odd number of values | ||
ascending = new long[len]; | ||
descending = new long[len]; | ||
|
||
for (int i = 0; i < len; i++) { | ||
ascending[i] = values[i]; | ||
descending[i] = values[size - i - 1]; | ||
} | ||
} | ||
|
||
@Override | ||
public long floor(long key) { | ||
int i = 0; | ||
for (; i < ascending.length; i++) { | ||
if (descending[i] <= key) { | ||
return descending[i]; | ||
} | ||
if (ascending[i] > key) { | ||
assert i > 0 : "key must be greater than or equal to " + ascending[0]; | ||
return ascending[i - 1]; | ||
} | ||
} | ||
return ascending[i - 1]; | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
libs/common/src/main/java/org/opensearch/common/round/BinarySearcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.common.round; | ||
|
||
import org.opensearch.common.annotation.InternalApi; | ||
|
||
import java.util.Arrays; | ||
|
||
/** | ||
* It uses binary search on a sorted array of pre-computed round-down points. | ||
* | ||
* @opensearch.internal | ||
*/ | ||
@InternalApi | ||
class BinarySearcher implements Roundable { | ||
private final long[] values; | ||
private final int size; | ||
|
||
public BinarySearcher(long[] values, int size) { | ||
assert size > 0 : "at least one value must be present"; | ||
|
||
this.values = values; | ||
this.size = size; | ||
} | ||
|
||
@Override | ||
public long floor(long key) { | ||
int idx = Arrays.binarySearch(values, 0, size, key); | ||
assert idx != -1 : "key must be greater than or equal to " + values[0]; | ||
if (idx < 0) { | ||
idx = -2 - idx; | ||
} | ||
return values[idx]; | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
libs/common/src/main/java/org/opensearch/common/round/Roundable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.common.round; | ||
|
||
import org.opensearch.common.annotation.InternalApi; | ||
|
||
/** | ||
* Interface to round-off values. | ||
* | ||
* @opensearch.internal | ||
*/ | ||
@InternalApi | ||
@FunctionalInterface | ||
public interface Roundable { | ||
/** | ||
* Returns the greatest lower bound of the given key. | ||
* In other words, it returns the largest value such that {@code value <= key}. | ||
* @param key to floor | ||
* @return the floored value | ||
*/ | ||
long floor(long key); | ||
} |
34 changes: 34 additions & 0 deletions
34
libs/common/src/main/java/org/opensearch/common/round/RoundableFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.common.round; | ||
|
||
/** | ||
* Factory class to create and return the fastest implementation of {@link Roundable}. | ||
*/ | ||
public class RoundableFactory { | ||
/** | ||
* The maximum limit up to which linear search is used, otherwise binary search is used. | ||
* This is because linear search is much faster on small arrays. | ||
* Benchmark results: <a href="https://github.com/opensearch-project/OpenSearch/pull/9727">PR #9727</a> | ||
*/ | ||
private static final int LINEAR_SEARCH_MAX_SIZE = 64; | ||
|
||
private RoundableFactory() {} | ||
|
||
/** | ||
* Creates and returns the fastest implementation of {@link Roundable}. | ||
*/ | ||
public static Roundable create(long[] values, int size) { | ||
if (size <= LINEAR_SEARCH_MAX_SIZE) { | ||
return new BidirectionalLinearSearcher(values, size); | ||
} else { | ||
return new BinarySearcher(values, size); | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
libs/common/src/main/java/org/opensearch/common/round/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
/** | ||
* Contains classes to round-off values. | ||
*/ | ||
package org.opensearch.common.round; |
Oops, something went wrong.