Extend ArrayUtils
Provide only two binary search functions: - Add binarySearchFirstGreaterOrEqual() - Add binarySearchFirstGreater() Note: other binary search variations can be built later on top of these functions. Bug: b/256564627 Test: npm run test:unit Change-Id: Icbd308923fe4b79dae29fb69176fa7276f5dd7cd
This commit is contained in:
@@ -61,7 +61,10 @@ class ArrayUtils {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static binarySearchLowerOrEqual<T>(values: T[] | TypedArray, target: T): number | undefined {
|
||||
static binarySearchFirstGreaterOrEqual<T>(
|
||||
values: T[] | TypedArray,
|
||||
target: T
|
||||
): number | undefined {
|
||||
if (values.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -75,11 +78,11 @@ class ArrayUtils {
|
||||
const mid = (low + high) >> 1;
|
||||
|
||||
if (values[mid] < target) {
|
||||
if (result === undefined || result < mid) {
|
||||
result = mid;
|
||||
}
|
||||
low = mid + 1;
|
||||
} else if (values[mid] > target) {
|
||||
if (result === undefined || result > mid) {
|
||||
result = mid;
|
||||
}
|
||||
high = mid - 1;
|
||||
} else {
|
||||
result = mid;
|
||||
@@ -90,6 +93,34 @@ class ArrayUtils {
|
||||
return result;
|
||||
}
|
||||
|
||||
static binarySearchFirstGreater<T>(values: T[] | TypedArray, target: T): number | undefined {
|
||||
if (values.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let low = 0;
|
||||
let high = values.length - 1;
|
||||
|
||||
let result: number | undefined = undefined;
|
||||
|
||||
while (low <= high) {
|
||||
const mid = (low + high) >> 1;
|
||||
|
||||
if (values[mid] < target) {
|
||||
low = mid + 1;
|
||||
} else if (values[mid] > target) {
|
||||
if (result === undefined || result > mid) {
|
||||
result = mid;
|
||||
}
|
||||
high = mid - 1;
|
||||
} else {
|
||||
low = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static toUintLittleEndian(buffer: Uint8Array, start: number, end: number): bigint {
|
||||
let result = 0n;
|
||||
for (let i = end - 1; i >= start; --i) {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {ArrayUtils} from './array_utils';
|
||||
|
||||
describe('ArrayUtils', () => {
|
||||
@@ -55,35 +56,65 @@ describe('ArrayUtils', () => {
|
||||
expect(ArrayUtils.searchSubarray([0, 1, 2], [2, 3])).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('binarySearchLowerOrEqual', () => {
|
||||
it('binarySearchFirstGreaterOrEqual', () => {
|
||||
// no match
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([], 5)).toBeUndefined();
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([6], 5)).toBeUndefined();
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([6, 7], 5)).toBeUndefined();
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([6, 7, 8], 5)).toBeUndefined();
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([], 9)).toBeUndefined();
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([8], 9)).toBeUndefined();
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([7, 8], 9)).toBeUndefined();
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([6, 7, 8], 9)).toBeUndefined();
|
||||
|
||||
// match (lower)
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([4], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([3, 4], 5)).toEqual(1);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([2, 3, 4], 5)).toEqual(2);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([2, 3, 4, 6], 5)).toEqual(2);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([2, 3, 4, 6, 7], 5)).toEqual(2);
|
||||
// match (greater)
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([6], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([6, 7], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([4, 6], 5)).toEqual(1);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([4, 6, 7, 8], 5)).toEqual(1);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([3, 4, 6, 7, 8], 5)).toEqual(2);
|
||||
|
||||
// match (equal)
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([5], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([5, 6], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([4, 5], 5)).toEqual(1);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([3, 4, 5], 5)).toEqual(2);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([3, 4, 5, 6], 5)).toEqual(2);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([3, 4, 5, 6, 7], 5)).toEqual(2);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([5], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([5, 6], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([4, 5], 5)).toEqual(1);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([3, 4, 5], 5)).toEqual(2);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([3, 4, 5, 6], 5)).toEqual(2);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([3, 4, 5, 6, 7], 5)).toEqual(2);
|
||||
|
||||
// match (equal with repeated values)
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([5, 5], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([5, 5, 5], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([5, 5, 5, 5], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([4, 5, 5, 6], 5)).toEqual(1);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([4, 4, 5, 5, 5, 6], 5)).toEqual(2);
|
||||
expect(ArrayUtils.binarySearchLowerOrEqual([4, 4, 4, 5, 5, 5, 5, 6], 5)).toEqual(3);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([5, 5], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([5, 5, 5], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([5, 5, 5, 5], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([4, 5, 5, 6], 5)).toEqual(1);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([4, 4, 5, 5, 5, 6], 5)).toEqual(2);
|
||||
expect(ArrayUtils.binarySearchFirstGreaterOrEqual([4, 4, 4, 5, 5, 5, 5, 6], 5)).toEqual(3);
|
||||
});
|
||||
|
||||
it('binarySearchFirstGreater', () => {
|
||||
// no match
|
||||
expect(ArrayUtils.binarySearchFirstGreater([], 9)).toBeUndefined();
|
||||
expect(ArrayUtils.binarySearchFirstGreater([8], 9)).toBeUndefined();
|
||||
expect(ArrayUtils.binarySearchFirstGreater([7, 8], 9)).toBeUndefined();
|
||||
expect(ArrayUtils.binarySearchFirstGreater([6, 7, 8], 9)).toBeUndefined();
|
||||
|
||||
// match
|
||||
expect(ArrayUtils.binarySearchFirstGreater([6], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([6, 7], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([4, 6], 5)).toEqual(1);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([4, 6, 7, 8], 5)).toEqual(1);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([3, 4, 6, 7, 8], 5)).toEqual(2);
|
||||
|
||||
// match (ignore equal)
|
||||
expect(ArrayUtils.binarySearchFirstGreater([5], 5)).toEqual(undefined);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([5, 6], 5)).toEqual(1);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([4, 5, 6], 5)).toEqual(2);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([3, 4, 5, 6], 5)).toEqual(3);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([3, 4, 5, 6, 7], 5)).toEqual(3);
|
||||
|
||||
// match (with repeated values)
|
||||
expect(ArrayUtils.binarySearchFirstGreater([6, 6], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([6, 6, 6], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([6, 6, 6, 6], 5)).toEqual(0);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([5, 6, 6, 7], 5)).toEqual(1);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([5, 5, 6, 6, 6, 7], 5)).toEqual(2);
|
||||
expect(ArrayUtils.binarySearchFirstGreater([5, 5, 5, 6, 6, 6, 6, 7], 5)).toEqual(3);
|
||||
});
|
||||
|
||||
it('toUintLittleEndian', () => {
|
||||
|
||||
Reference in New Issue
Block a user