io.deephaven.engine.table.impl.select.analyzers.StaticFlattenLayer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of deephaven-engine-table Show documentation
Show all versions of deephaven-engine-table Show documentation
Engine Table: Implementation and closely-coupled utilities
/**
* Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending
*/
package io.deephaven.engine.table.impl.select.analyzers;
import io.deephaven.base.log.LogOutput;
import io.deephaven.base.verify.Assert;
import io.deephaven.engine.liveness.LivenessNode;
import io.deephaven.engine.rowset.RowSet;
import io.deephaven.engine.rowset.RowSetFactory;
import io.deephaven.engine.rowset.RowSetShiftData;
import io.deephaven.engine.rowset.TrackingRowSet;
import io.deephaven.engine.table.ColumnDefinition;
import io.deephaven.engine.table.ColumnSource;
import io.deephaven.engine.table.ModifiedColumnSet;
import io.deephaven.engine.table.TableUpdate;
import io.deephaven.engine.table.impl.TableUpdateImpl;
import io.deephaven.engine.table.impl.sources.RedirectedColumnSource;
import io.deephaven.engine.table.impl.util.RowRedirection;
import io.deephaven.engine.table.impl.util.WrappedRowSetRowRedirection;
import io.deephaven.engine.table.impl.util.JobScheduler;
import org.jetbrains.annotations.Nullable;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
final public class StaticFlattenLayer extends SelectAndViewAnalyzer {
private final SelectAndViewAnalyzer inner;
private final TrackingRowSet parentRowSet;
private final Map> overriddenColumns;
StaticFlattenLayer(SelectAndViewAnalyzer inner, TrackingRowSet parentRowSet) {
super(inner.getLayerIndex() + 1);
this.inner = inner;
this.parentRowSet = parentRowSet;
final HashSet alreadyFlattenedColumns = new HashSet<>();
inner.getNewColumnSources().forEach((name, cs) -> {
alreadyFlattenedColumns.add(name);
});
final RowRedirection rowRedirection = new WrappedRowSetRowRedirection(parentRowSet);
overriddenColumns = new HashMap<>();
inner.getAllColumnSources().forEach((name, cs) -> {
if (alreadyFlattenedColumns.contains(name)) {
return;
}
overriddenColumns.put(name, RedirectedColumnSource.maybeRedirect(rowRedirection, cs));
});
}
@Override
void setBaseBits(BitSet bitset) {
inner.setBaseBits(bitset);
}
@Override
void populateModifiedColumnSetRecurse(ModifiedColumnSet mcsBuilder, Set remainingDepsToSatisfy) {
inner.populateModifiedColumnSetRecurse(mcsBuilder, remainingDepsToSatisfy);
}
@Override
Map> getColumnSourcesRecurse(GetMode mode) {
final Map> innerColumns = inner.getColumnSourcesRecurse(mode);
if (overriddenColumns.keySet().stream().noneMatch(innerColumns::containsKey)) {
return innerColumns;
}
final Map> columns = new LinkedHashMap<>();
innerColumns.forEach((name, cs) -> columns.put(name, overriddenColumns.getOrDefault(name, cs)));
return columns;
}
@Override
public void applyUpdate(TableUpdate upstream, RowSet toClear, UpdateHelper helper, JobScheduler jobScheduler,
@Nullable LivenessNode liveResultOwner, SelectLayerCompletionHandler onCompletion) {
// this must be the fake update used to initialize the result table
Assert.eqTrue(upstream.added().isFlat(), "upstream.added.isFlat()");
Assert.eq(upstream.added().size(), "upstream.added.size()", parentRowSet.size(), "parentRowSet.size()");
Assert.eqTrue(upstream.removed().isEmpty(), "upstream.removed.isEmpty()");
Assert.eqTrue(upstream.modified().isEmpty(), "upstream.modified.isEmpty()");
final BitSet baseLayerBitSet = new BitSet();
inner.setBaseBits(baseLayerBitSet);
final TableUpdate innerUpdate = new TableUpdateImpl(
parentRowSet.copy(), RowSetFactory.empty(), RowSetFactory.empty(),
RowSetShiftData.EMPTY, ModifiedColumnSet.EMPTY);
inner.applyUpdate(innerUpdate, toClear, helper, jobScheduler, liveResultOwner,
new SelectLayerCompletionHandler(baseLayerBitSet, onCompletion) {
@Override
public void onAllRequiredColumnsCompleted() {
onCompletion.onLayerCompleted(getLayerIndex());
}
});
}
@Override
Map> calcDependsOnRecurse(boolean forcePublishAllResources) {
return inner.calcDependsOnRecurse(forcePublishAllResources);
}
@Override
public SelectAndViewAnalyzer getInner() {
return inner;
}
@Override
int getLayerIndexFor(String column) {
if (overriddenColumns.containsKey(column)) {
return getLayerIndex();
}
return inner.getLayerIndexFor(column);
}
@Override
public void updateColumnDefinitionsFromTopLayer(Map> columnDefinitions) {
inner.updateColumnDefinitionsFromTopLayer(columnDefinitions);
}
@Override
public void startTrackingPrev() {
throw new UnsupportedOperationException("StaticFlattenLayer is used in only non-refreshing scenarios");
}
@Override
public LogOutput append(LogOutput logOutput) {
return logOutput.append("{StaticFlattenLayer").append(", layerIndex=").append(getLayerIndex()).append("}");
}
@Override
public boolean allowCrossColumnParallelization() {
return inner.allowCrossColumnParallelization();
}
@Override
public boolean flattenedResult() {
// this layer performs a flatten, so the result is flattened
return true;
}
@Override
public boolean alreadyFlattenedSources() {
// this layer performs a flatten, so the sources are now flattened
return true;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy