Skip to content

Commit

Permalink
feat: exhaustive copy on write visitors (substrait-io#199)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: RelCopyOnWriteVisitor now extends RelVisitor and has generic type parameter
  • Loading branch information
vbarua authored Nov 7, 2023
1 parent b938573 commit 39c56ab
Show file tree
Hide file tree
Showing 9 changed files with 693 additions and 240 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ public Type getType() {
return type();
}

public static ImmutableFieldReference.Builder builder() {
return ImmutableFieldReference.builder();
}

public <R, E extends Throwable> R accept(ExpressionVisitor<R, E> visitor) throws E {
return visitor.visit(this);
}
Expand Down
59 changes: 59 additions & 0 deletions core/src/main/java/io/substrait/relation/CopyOnWriteUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.substrait.relation;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

/** Provides common utilities for copy-on-write visitations */
public class CopyOnWriteUtils {

public static boolean allEmpty(Optional<?>... optionals) {
return Arrays.stream(optionals).noneMatch(Optional::isPresent);
}

/** The `or` method on Optional instances is a Java 9+ feature */
public static <T> Optional<T> or(Optional<T> left, Supplier<? extends Optional<T>> right) {
if (left.isPresent()) {
return left;
} else {
return right.get();
}
}

@FunctionalInterface
public interface TransformFunction<T, E extends Exception> {
Optional<T> apply(T t) throws E;
}

/**
* Applies the given transformation function to each item in the list. If any of the list items
* are transformed, returns a new list in which each item is either
*
* <ul>
* <li>a transformed new item replacing an old item
* <li>the original item in the position it was in
* </ul>
*
* @param items the list of items to transform
* @param transform the transformation function to apply to each item
* @return An empty optional if none of the items have changed. An optional containing a new list
* otherwise.
*/
public static <ITEM, E extends Exception> Optional<List<ITEM>> transformList(
List<ITEM> items, TransformFunction<ITEM, E> transform) throws E {
List<ITEM> newItems = new ArrayList<>();
boolean listUpdated = false;
for (ITEM item : items) {
Optional<ITEM> newItem = transform.apply(item);
if (newItem.isPresent()) {
newItems.add(newItem.get());
listUpdated = true;
} else {
newItems.add(item);
}
}
return listUpdated ? Optional.of(newItems) : Optional.empty();
}
}
Loading

0 comments on commit 39c56ab

Please sign in to comment.