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

Binary search API #385

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Binary search API #385

wants to merge 2 commits into from

Conversation

dmlloyd
Copy link
Collaborator

@dmlloyd dmlloyd commented Dec 3, 2024

Will update the summary/description once things are more finalized.

Design (short version):

  • BinarySearch.intRange().find(0, 100, n -> n >= 35) - find the first integer in range [0, 100) which satisfies the predicate n >= 35 (in this case, yields 35 after about 7 steps)
  • BinarySearch.longRange().find(1000L, 1000000L, n -> n >= 2048L) - find the first long integer in range [1000L, 1000000L) which satisfies the predicate n >= 2048L

We also have BinarySearch.intRange().unsigned() which treats the range as unsigned integers (0..0xFFFF_FFFF), and BinarySearch.longRange().unsigned() which is equivalent for long.

There are also variations which allow you to provide your own midpoint function.

There are helpers to search ranges of things, for example, given:

public record Item(String name, String address) {}

We can search a List<Item> list for the given name using a helper like this:

int idx = BinarySearch.intRange().findFirst(list, "Fred", 0, list.size(), (l, i) -> l.get(i).name())

Then idx will either contain the exact match, or the point into which the exact match would go.

See https://bugs.openjdk.org/browse/JDK-8326330 for the original inspiration of this flexible implementation.

I'm not super happy with the API ergonomics (the factory methods). But it seemed better than having one BinarySearch class with 50 or more methods called find. And the factory methods are all monomorphic and don't actually allocate anything, so the perf impact is expected to be minimal as these can be trivially inlined. But I'm open to other ideas in terms of API ergonomics and naming of classes.

@dmlloyd dmlloyd force-pushed the binary-search branch 4 times, most recently from 7b0612a to 32772ba Compare January 15, 2025 16:26
@dmlloyd
Copy link
Collaborator Author

dmlloyd commented Jan 15, 2025

OK I'm pretty happy with the API now. Just going to add some more tests before marking this as ready to go.

@dmlloyd dmlloyd marked this pull request as ready for review January 15, 2025 16:56
@dmlloyd dmlloyd changed the title Binary search (WIP) Binary search API Jan 15, 2025
@dmlloyd
Copy link
Collaborator Author

dmlloyd commented Jan 15, 2025

OK everything is all set. The artifact name is smallrye-common-search and the module name is io.smallrye.common.search. We could potentially add support for other kinds of search algorithms in the future to this module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant