summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/data/lazy/NewLazyPair.java
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-04-11 21:54:44 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-04-11 21:54:44 -0400
commitc8a00b789671d59589bcb5520c1e9d208bcc27f6 (patch)
tree6b64e3c78f56d025c78ab08a9edc038af0b6e821 /BJC-Utils2/src/main/java/bjc/utils/data/lazy/NewLazyPair.java
parenta716a7a53f85a6901128896da508d31c172011b4 (diff)
Work on restructing data.
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/data/lazy/NewLazyPair.java')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/lazy/NewLazyPair.java202
1 files changed, 202 insertions, 0 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/NewLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/NewLazyPair.java
new file mode 100644
index 0000000..4bd3832
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/NewLazyPair.java
@@ -0,0 +1,202 @@
+package bjc.utils.data.lazy;
+
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
+
+import bjc.utils.data.GenHolder;
+import bjc.utils.data.IPair;
+import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcdata.IFunctionalList;
+
+/**
+ * New implementation of lazy pair not delegating to {@link LazyHolder}
+ *
+ * @author ben
+ * @param <L>
+ * The type on the left side of the pair
+ * @param <R>
+ * The type on the right side of the pair
+ *
+ */
+public class NewLazyPair<L, R> implements IPair<L, R>, ILazy {
+ private static class BoundLazyPair<OldL, OldR, NewL, NewR>
+ implements IPair<NewL, NewR> {
+ private Supplier<OldL> oldLeftSupplier;
+ private Supplier<OldR> oldRightSupplier;
+
+ private BiFunction<OldL, OldR, IPair<NewL, NewR>> newPairSupplier;
+
+ private IPair<NewL, NewR> newPair;
+
+ private boolean newPairMaterialized;
+
+ public BoundLazyPair(Supplier<OldL> leftSup,
+ Supplier<OldR> rightSup,
+ BiFunction<OldL, OldR, IPair<NewL, NewR>> binder) {
+ oldLeftSupplier = leftSup;
+ oldRightSupplier = rightSup;
+
+ newPairSupplier = binder;
+ }
+
+ @Override
+ public <L2, R2> IPair<L2, R2> bind(
+ BiFunction<NewL, NewR, IPair<L2, R2>> binder) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void doWith(BiConsumer<NewL, NewR> action) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public <E> E merge(BiFunction<NewL, NewR, E> merger) {
+ if (!newPairMaterialized) {
+ newPair = newPairSupplier.apply(oldLeftSupplier.get(),
+ oldRightSupplier.get());
+ }
+
+ return newPair.merge(merger);
+ }
+ }
+
+ private L leftValue;
+ private R rightValue;
+
+ private Supplier<R> rightValueSupplier;
+ private Supplier<L> leftValueSupplier;
+
+ private boolean rightMaterialized;
+ private boolean leftMaterialized;
+
+ private IFunctionalList<BiConsumer<L, R>> actions;
+
+ /**
+ * Create a new lazy pair
+ *
+ * @param leftVal
+ * The left value in the pair
+ * @param rightVal
+ * The right value in the pair
+ */
+ public NewLazyPair(L leftVal, R rightVal) {
+ leftValueSupplier = () -> leftVal;
+ rightValueSupplier = () -> rightVal;
+ }
+
+ /**
+ * Create a new lazy pair
+ *
+ * @param leftSupplier
+ * The supplier for the left value in the pair
+ * @param rightSupplier
+ * The supplier for the right value in the pair
+ */
+ public NewLazyPair(Supplier<L> leftSupplier,
+ Supplier<R> rightSupplier) {
+ leftValueSupplier = leftSupplier;
+ rightValueSupplier = rightSupplier;
+ }
+
+ @Override
+ public void applyPendingActions() {
+ if (!isMaterialized()) {
+ throw new UnsupportedOperationException(
+ "Can only apply actions to materialized values");
+ }
+
+ actions.forEach((action) -> {
+ action.accept(leftValue, rightValue);
+ });
+
+ actions = new FunctionalList<>();
+ }
+
+ private void applyPossiblyPendingActions(GenHolder<Boolean> hasActions,
+ IFunctionalList<BiConsumer<L, R>> pendingActions) {
+ if (hasActions.unwrap((val) -> val) == true) {
+ pendingActions.forEach((action) -> {
+ action.accept(leftValue, rightValue);
+ });
+
+ hasActions.transform((val) -> false);
+ }
+ }
+
+ @Override
+ public <L2, R2> IPair<L2, R2> bind(
+ BiFunction<L, R, IPair<L2, R2>> binder) {
+ GenHolder<Boolean> hasActions = new GenHolder<>(true);
+ IFunctionalList<BiConsumer<L, R>> pendingActions = new FunctionalList<>();
+
+ actions.forEach(pendingActions::add);
+
+ return new BoundLazyPair<>(() -> {
+ applyPossiblyPendingActions(hasActions, pendingActions);
+
+ return leftValue;
+ }, () -> {
+ applyPossiblyPendingActions(hasActions, pendingActions);
+
+ return rightValue;
+ }, binder);
+ }
+
+ @Override
+ public void doWith(BiConsumer<L, R> action) {
+ actions.add(action);
+ }
+
+ @Override
+ public boolean hasPendingActions() {
+ return !actions.isEmpty();
+ }
+
+ @Override
+ public boolean isMaterialized() {
+ if (leftValueSupplier == null) {
+ if (rightValueSupplier == null) {
+ return true;
+ }
+
+ return rightMaterialized;
+ }
+
+ if (rightValueSupplier == null) {
+ return leftMaterialized;
+ }
+
+ return leftMaterialized && rightMaterialized;
+ }
+
+ @Override
+ public void materialize() {
+ if (isMaterialized()) {
+ throw new UnsupportedOperationException(
+ "Cannot materialize lazy object twice");
+ }
+
+ if (leftValueSupplier != null) {
+ leftValue = leftValueSupplier.get();
+ }
+
+ if (rightValueSupplier != null) {
+ rightValue = rightValueSupplier.get();
+ }
+ }
+
+ @Override
+ public <E> E merge(BiFunction<L, R, E> merger) {
+ if (!isMaterialized()) {
+ materialize();
+ }
+
+ applyPendingActions();
+
+ return merger.apply(leftValue, rightValue);
+ }
+} \ No newline at end of file