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 (WIP) #385

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft

Binary search (WIP) #385

wants to merge 3 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.

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