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

feat: Add withRecomputeOnModifiedRow to SelectColumn. #6339

Merged
merged 4 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
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
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
Loading