Skip to content

Memoizer: document public members #121

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

Open
wants to merge 1 commit into
base: octree-testing
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions src/main/java/dev/thedocruby/resounding/Memoizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,28 @@
import java.util.function.BiFunction;
import java.util.function.Function;

/**
* {@code Memoizer} is used to memoize mapping calculation from one input to
* another.
* <p>
* A mapping calculation maps a key-input pair into a key-output pair
* and may require dependency from other keys (see {@code Memoizer}).
* <p>
* Calculation errors are collected but not thrown are collected as output from
* calling {@code solve}. Following are possible errors:
* <ul>
* <li>circular or cyclic dependencies</li>
* <li>dependency's input nor output value exist</li>
* <li>calculation returned null</li>
* </ul>
* Runtime exceptions are not calculation errors and are propagated normally.
*
* @param <IN> the input value type
* @param <KEY> the mapping key type
* @param <OUT> the output value type
* @see #Memoizer(Map, TriFunction) Memoizer
* @see #solve(Map, boolean, boolean) solve
*/
public class Memoizer<IN,KEY,OUT> {

private Map<KEY,@NotNull IN> in;
Expand All @@ -21,13 +43,42 @@ public class Memoizer<IN,KEY,OUT> {
private final TriFunction<Function<KEY,@Nullable OUT>,@NotNull IN,@NotNull KEY,@Nullable OUT> calculator;
private final ObjectLinkedOpenHashSet<KEY> path = new ObjectLinkedOpenHashSet<>();

/**
* Creates a new Memoizer with a backing map and value calculator.
* <p>
* The calculation strategy is provided two arguments and is similar to that
* in {@code Memoizer(Map, TriFunction)} with the only difference being the
* exclusion of the mapping key.
*
* @param output the backing key-to-output map
* @param calculator the calculator
* @see #Memoizer(Map, TriFunction)
*/
public Memoizer(
Map<KEY,OUT> output,
BiFunction<Function<KEY,@Nullable OUT>,@NotNull IN,@Nullable OUT> calculator
) {
this(output, (getter, raw, key) -> calculator.apply(getter, raw));
}

/**
* Creates a new Memoizer with a backing map and value calculator.
* <p>
* The calculation strategy is provided three arguments:
* <ul>
* <li>an accessor function mapping a given key to an output. This forms
* dependencies between keys and should not be cyclic and should either
* their input or output values be present.</li>
* <li>the input value mapped to the given key</li>
* <li>the mapping key for both the input and output value</li>
* </ul>
* The calculation strategy may return null and is treated as a calculation
* error and is recorded accordingly (see {@code solve}).
*
* @param output the backing key-to-output map
* @param calculator the calculator
* @see #solve(Map, boolean, boolean) solve
*/
public Memoizer(
Map<KEY,OUT> output,
TriFunction<Function<KEY,@Nullable OUT>,@NotNull IN,@NotNull KEY,@Nullable OUT> calculator
Expand All @@ -36,10 +87,29 @@ public Memoizer(
this.calculator = calculator;
}

/**
* Given a key-to-input mapping memoize output values for the given keys.
* This is equivalent to {@code solve(in, false, false)}.
*
* @param in the key-to-input map used for calculating new output values
* @return a mutable list of errors emitted by this Memoizer
* @see #solve(Map, boolean, boolean)
*/
public List<String> solve(Map<KEY,@NotNull IN> in) {
return solve(in, false, true);
}

/**
* Given a key-to-input mapping memoize output values for the given keys.
* <p>
* Runtime exception from the calculator is not caught nor is recorded and
* is instead forwarded back to the caller.
*
* @param in the key-to-input map used for calculating new output values
* @param deconstruct should entries in the key-to-input map be consumed
* @param ignoreNull should a null key mapped to a null output be ignored
* @return a mutable list of errors emitted by this Memoizer
*/
public List<String> solve(Map<KEY,@NotNull IN> in, boolean deconstruct, boolean ignoreNull) {
this.in = in;
path.clear();
Expand Down