Skip to content

Commit

Permalink
feat: Add withRecomputeOnModifiedRow to SelectColumn. (#6339)
Browse files Browse the repository at this point in the history
  • Loading branch information
cpwright authored Nov 7, 2024
1 parent 8832682 commit 06878ae
Show file tree
Hide file tree
Showing 8 changed files with 338 additions and 99 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
//
package io.deephaven.engine.table.impl.select;

import io.deephaven.api.ColumnName;
import io.deephaven.api.expression.Expression;
import io.deephaven.engine.rowset.TrackingRowSet;
import io.deephaven.engine.table.ColumnDefinition;
import io.deephaven.engine.table.ColumnSource;
import io.deephaven.engine.table.WritableColumnSource;
import io.deephaven.engine.table.impl.BaseTable;
import io.deephaven.engine.table.impl.MatchPair;
import io.deephaven.engine.table.impl.QueryCompilerRequestProcessor;
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.Map;

/**
* {@link SelectColumn} implementation that wraps another {@link SelectColumn} and makes it report that values should be
* recomputed when the row is modified via {@link #recomputeOnModifiedRow()}.
*/
class RecomputeOnModifiedRowSelectColumn extends WrappedSelectColumn {

RecomputeOnModifiedRowSelectColumn(@NotNull final SelectColumn inner) {
super(inner);
}

@Override
public SelectColumn copy() {
return new RecomputeOnModifiedRowSelectColumn(inner.copy());
}

@Override
public boolean recomputeOnModifiedRow() {
return true;
}

@Override
public SelectColumn withRecomputeOnModifiedRow() {
return copy();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ static SelectColumn ofStateless(@NotNull final Selectable selectable) {
return new StatelessSelectColumn(of(selectable));
}

/**
* Produce a SelectColumn that {@link #recomputeOnModifiedRow()} recomputes values on any modified row} from
* {@code selectable}.
*
* @param selectable The {@link Selectable} to adapt and mark as requiring row-level recomputation
* @return The resulting SelectColumn
*/
static SelectColumn ofRecomputeOnModifiedRow(Selectable selectable) {
return new RecomputeOnModifiedRowSelectColumn(of(selectable));
}

/**
* Convenient static final instance of a zero length Array of SelectColumns for use in toArray calls.
*/
Expand Down Expand Up @@ -232,6 +243,22 @@ default boolean hasVirtualRowVariables() {
*/
SelectColumn copy();

/**
* Should we ignore modified column sets, and always re-evaluate this column when the row changes?
*
* @return true if this column should be evaluated on every row modification
*/
default boolean recomputeOnModifiedRow() {
return false;
}

/**
* Create a copy of this SelectColumn that always re-evaluates itself when a row is modified.
*/
default SelectColumn withRecomputeOnModifiedRow() {
return new RecomputeOnModifiedRowSelectColumn(copy());
}

class ExpressionAdapter implements Expression.Visitor<SelectColumn> {
private final ColumnName lhs;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,93 +21,10 @@
* {@link SelectColumn} implementation that wraps another {@link SelectColumn} and makes it report to be
* {@link #isStateless() stateless}.
*/
class StatelessSelectColumn implements SelectColumn {

private final SelectColumn inner;
class StatelessSelectColumn extends WrappedSelectColumn {

StatelessSelectColumn(@NotNull final SelectColumn inner) {
this.inner = inner;
}

@Override
public List<String> initInputs(
@NotNull final TrackingRowSet rowSet,
@NotNull final Map<String, ? extends ColumnSource<?>> columnsOfInterest) {
return inner.initInputs(rowSet, columnsOfInterest);
}

@Override
public List<String> initDef(@NotNull final Map<String, ColumnDefinition<?>> columnDefinitionMap) {
return inner.initDef(columnDefinitionMap);
}

@Override
public List<String> initDef(
@NotNull final Map<String, ColumnDefinition<?>> columnDefinitionMap,
@NotNull final QueryCompilerRequestProcessor compilationRequestProcessor) {
return inner.initDef(columnDefinitionMap, compilationRequestProcessor);
}

@Override
public Class<?> getReturnedType() {
return inner.getReturnedType();
}

@Override
public Class<?> getReturnedComponentType() {
return inner.getReturnedComponentType();
}

@Override
public List<String> getColumns() {
return inner.getColumns();
}

@Override
public List<String> getColumnArrays() {
return inner.getColumnArrays();
}

@Override
@NotNull
public ColumnSource<?> getDataView() {
return inner.getDataView();
}

@Override
@NotNull
public ColumnSource<?> getLazyView() {
return inner.getLazyView();
}

@Override
public String getName() {
return inner.getName();
}

@Override
public MatchPair getMatchPair() {
return inner.getMatchPair();
}

@Override
public WritableColumnSource<?> newDestInstance(final long size) {
return inner.newDestInstance(size);
}

@Override
public WritableColumnSource<?> newFlatDestInstance(final long size) {
return inner.newFlatDestInstance(size);
}

@Override
public boolean isRetain() {
return inner.isRetain();
}

@Override
public void validateSafeForRefresh(@NotNull final BaseTable<?> sourceTable) {
inner.validateSafeForRefresh(sourceTable);
super(inner);
}

@Override
Expand All @@ -119,14 +36,4 @@ public boolean isStateless() {
public SelectColumn copy() {
return new StatelessSelectColumn(inner.copy());
}

@Override
public ColumnName newColumn() {
return inner.newColumn();
}

@Override
public Expression expression() {
return inner.expression();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
//
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
//
package io.deephaven.engine.table.impl.select;

import io.deephaven.api.ColumnName;
import io.deephaven.api.expression.Expression;
import io.deephaven.engine.rowset.TrackingRowSet;
import io.deephaven.engine.table.ColumnDefinition;
import io.deephaven.engine.table.ColumnSource;
import io.deephaven.engine.table.WritableColumnSource;
import io.deephaven.engine.table.impl.BaseTable;
import io.deephaven.engine.table.impl.MatchPair;
import io.deephaven.engine.table.impl.QueryCompilerRequestProcessor;
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.Map;

/**
* {@link SelectColumn} implementation that wraps another {@link SelectColumn}.
*/
abstract class WrappedSelectColumn implements SelectColumn {

/**
* The select column that is being wrapped.
*/
protected final SelectColumn inner;

WrappedSelectColumn(@NotNull final SelectColumn inner) {
this.inner = inner;
}

@Override
public List<String> initInputs(
@NotNull final TrackingRowSet rowSet,
@NotNull final Map<String, ? extends ColumnSource<?>> columnsOfInterest) {
return inner.initInputs(rowSet, columnsOfInterest);
}

@Override
public List<String> initDef(@NotNull final Map<String, ColumnDefinition<?>> columnDefinitionMap) {
return inner.initDef(columnDefinitionMap);
}

@Override
public List<String> initDef(
@NotNull final Map<String, ColumnDefinition<?>> columnDefinitionMap,
@NotNull final QueryCompilerRequestProcessor compilationRequestProcessor) {
return inner.initDef(columnDefinitionMap, compilationRequestProcessor);
}

@Override
public Class<?> getReturnedType() {
return inner.getReturnedType();
}

@Override
public Class<?> getReturnedComponentType() {
return inner.getReturnedComponentType();
}

@Override
public List<String> getColumns() {
return inner.getColumns();
}

@Override
public List<String> getColumnArrays() {
return inner.getColumnArrays();
}

@Override
@NotNull
public ColumnSource<?> getDataView() {
return inner.getDataView();
}

@Override
@NotNull
public ColumnSource<?> getLazyView() {
return inner.getLazyView();
}

@Override
public String getName() {
return inner.getName();
}

@Override
public MatchPair getMatchPair() {
return inner.getMatchPair();
}

@Override
public WritableColumnSource<?> newDestInstance(final long size) {
return inner.newDestInstance(size);
}

@Override
public WritableColumnSource<?> newFlatDestInstance(final long size) {
return inner.newFlatDestInstance(size);
}

@Override
public boolean isRetain() {
return inner.isRetain();
}

@Override
public void validateSafeForRefresh(@NotNull final BaseTable<?> sourceTable) {
inner.validateSafeForRefresh(sourceTable);
}

@Override
public boolean isStateless() {
return inner.isStateless();
}

@Override
public boolean recomputeOnModifiedRow() {
return inner.recomputeOnModifiedRow();
}

@Override
public ColumnName newColumn() {
return inner.newColumn();
}

@Override
public Expression expression() {
return inner.expression();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ public class ConstantColumnLayer extends SelectOrViewColumnLayer {
final String[] deps,
final ModifiedColumnSet mcsBuilder) {
super(context, sc, ws, null, deps, mcsBuilder);
if (sc.recomputeOnModifiedRow()) {
throw new IllegalArgumentException(
"SelectColumn may not have alwaysEvaluate set for a constant column: " + sc);
}
initialize(ws);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public abstract class DependencyLayerBase extends SelectAndViewAnalyzer.Layer {
selectColumnHoldsVector = Vector.class.isAssignableFrom(selectColumn.getReturnedType());
this.columnSource = columnSource;
context.populateParentDependenciesMCS(mcsBuilder, dependencies);
if (selectColumn.recomputeOnModifiedRow()) {
mcsBuilder.setAll(ModifiedColumnSet.ALL);
}
this.myModifiedColumnSet = mcsBuilder;
this.myLayerDependencySet = new BitSet();
context.populateLayerDependencySet(myLayerDependencySet, dependencies);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ final public class ViewColumnLayer extends SelectOrViewColumnLayer {
final String[] deps,
final ModifiedColumnSet mcsBuilder) {
super(context, sc, checkResultType(cs), null, deps, mcsBuilder);
if (sc.recomputeOnModifiedRow()) {
throw new IllegalArgumentException(
"SelectColumn may not have recomputeOnModifiedRow set for a view column: " + sc);
}
}

@Override
Expand Down
Loading

0 comments on commit 06878ae

Please sign in to comment.