Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(types) add type coverage & docs for binarySearchBounds.js #17058

Merged
merged 2 commits into from
Apr 25, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 49 additions & 0 deletions lib/util/binarySearchBounds.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,28 @@
/* cspell:disable-next-line */
// Refactor: Peter Somogyvari @petermetz

/** @typedef {">=" | "<=" | "<" | ">" | "-" } BinarySearchPredicate */
/** @typedef {"GE" | "GT" | "LT" | "LE" | "EQ" } SearchPredicateSuffix */

/**
* Helper function for compiling binary search functions.
*
* The generated code uses a while loop to repeatedly divide the search interval
* in half until the desired element is found, or the search interval is empty.
*
* The following is an example of a generated function for calling `compileSearch("myFunc", ">=", true, ["value"], false)`:
*
* ```js
* function myFunc(a,l,h,value){var i=l-1;while(l<=h){var m=(l+h)>>>1,x=a[m];if(>=){i=m;l=m+1}else{h=m-1}}return i};
TheLarkInn marked this conversation as resolved.
Show resolved Hide resolved
* ```
*
* @param {string} funcName The name of the function to be compiled.
* @param {string} predicate The predicate / comparison operator to be used in the binary search.
* @param {boolean} reversed Whether the search should be reversed.
* @param {string[]} extraArgs Extra arguments to be passed to the function.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If earlyOut must at least contain a value named y that is the search value.

* @param {boolean=} earlyOut Whether the search should return as soon as a match is found.
* @returns {string} The compiled binary search function.
*/
const compileSearch = (funcName, predicate, reversed, extraArgs, earlyOut) => {
const code = [
"function ",
Expand Down Expand Up @@ -43,6 +65,18 @@ const compileSearch = (funcName, predicate, reversed, extraArgs, earlyOut) => {
return code.join("");
};

/**
* This helper functions generate code for two binary search functions:
* A(): Performs a binary search on an array using the comparison operator specified.
* P(): Performs a binary search on an array using a _custom comparison function_
* `c(x,y)` **and** comparison operator specified by `predicate`.
*
* @param {BinarySearchPredicate} predicate The predicate / comparison operator to be used in the binary search.
* @param {boolean} reversed Whether the search should be reversed.
* @param {SearchPredicateSuffix} suffix The suffix to be used in the function name.
* @param {boolean=} earlyOut Whether the search should return as soon as a match is found.
* @returns {function} The compiled binary search function.
*/
const compileBoundsSearch = (predicate, reversed, suffix, earlyOut) => {
const arg1 = compileSearch(
"A",
Expand Down Expand Up @@ -77,6 +111,21 @@ return dispatchBinarySearch";
return result();
};

/**
* These functions are used to perform binary searches on arrays.
*
* @example
* ```js
* const { gt, le} = require("./binarySearchBounds");
* const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
*
* // Find the index of the first element greater than 5
* const index1 = gt(arr, 5); // index1 === 3
*
* // Find the index of the first element less than or equal to 5
* const index2 = le(arr, 5); // index2 === 4
* ```
*/
module.exports = {
ge: compileBoundsSearch(">=", false, "GE"),
gt: compileBoundsSearch(">", false, "GT"),
Expand Down