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

BisectSearch util #25

Merged
merged 5 commits into from
Jul 6, 2022
Merged

BisectSearch util #25

merged 5 commits into from
Jul 6, 2022

Conversation

runeflobakk
Copy link
Member

@runeflobakk runeflobakk commented Jun 27, 2022

Adds a util for performing bisection search (or binary searches) on ordered sets of arbitrary objects. The objects can be generated as needed based on an ordered index (where it "would" appear in an ordered set of the objects), and as such does not need to be existing instances in memory in order to be searched.


A use case for this is to iteratively find a generated valid binary file of a
certain size, e.g. PDFs, images, etc, anything that can be translated
from an integer to an object retaining the same notion of "order" as the
integer it is based on.

Generating PDFs with random content using PDFBox:

PDDocument createPdf(int pages) {
    // generate PDDocument with the given amount of pages, filled with random content
}

...

import no.digipost.io.DataSize;
import no.digipost.util.bisect.BisectSearch;
import no.digipost.util.bisect.Suggestion;
import static no.digipost.util.bisect.Evaluator.size;

public static void main(String[] args) {
    PDDocument pdf512kb = BisectSearch
            .from(numberOfPages -> Suggestion.of(createPdf(numberOfPages)))
            .inRange(30, 500)
            .searchFor(size(DataSize.kB(512), PDDocument::save))
}

Each attempted (suggested) PDDocument will also be properly closed, being an AutoCloseable, except from the resulting PDDocument which is returned from the search. By default, the search will perform at most 20 attempts before returning its last attempt (unless found before).

Similarly, this utility could be used to translate points (a.k.a. the integer from the range) to X and Y pixel amount, given a fixed aspect ratio, and generate images with random content, and search for one with a certain size.

Similar to Function.identity() in the JDK.
Specced to throw RuntimeException, but will never throw such as it just
returns its given argument.
@runeflobakk runeflobakk force-pushed the bisect-search-util branch 2 times, most recently from 1f6b9a5 to f3ae577 Compare June 27, 2022 15:44
E.g. can be used to iteratively find a generated valid binary file of a
certain size, e.g. PDFs, images, etc, anything that can be translated
from an integer to an object retaining the same notion of "order" as the
integer it is based on.

https://en.wikipedia.org/wiki/Binary_search_algorithm
In addition to a byteCount integer (long)
Copy link

@velfundert velfundert left a comment

Choose a reason for hiding this comment

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

a man doing calculations

Unifies ThrowingFunction and Function.
Also adds some javadocs
@runeflobakk runeflobakk merged commit 460b8f2 into main Jul 6, 2022
@runeflobakk runeflobakk deleted the bisect-search-util branch July 6, 2022 12:32
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.

2 participants