io.deephaven.engine.table.impl.ssa.IntChunkSsaStamp 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
*/
/*
* ---------------------------------------------------------------------------------------------------------------------
* AUTO-GENERATED CLASS - DO NOT EDIT MANUALLY - for any changes edit CharChunkSsaStamp and regenerate
* ---------------------------------------------------------------------------------------------------------------------
*/
package io.deephaven.engine.table.impl.ssa;
import io.deephaven.chunk.*;
import io.deephaven.engine.rowset.chunkattributes.RowKeys;
import io.deephaven.chunk.attributes.Values;
import io.deephaven.engine.rowset.RowSequence;
import io.deephaven.engine.table.impl.util.RowRedirection;
import io.deephaven.engine.rowset.RowSetBuilderRandom;
import io.deephaven.engine.table.impl.util.WritableRowRedirection;
/**
* Stamp kernel for when the left hand side is a sorted chunk and the right hand side is a ticking SegmentedSortedArray.
*/
public class IntChunkSsaStamp implements ChunkSsaStamp {
static IntChunkSsaStamp INSTANCE = new IntChunkSsaStamp();
private IntChunkSsaStamp() {} // use the instance
@Override
public void processEntry(Chunk leftStampValues, Chunk leftStampKeys, SegmentedSortedArray ssa, WritableLongChunk rightKeysForLeft, boolean disallowExactMatch) {
processEntry(leftStampValues.asIntChunk(), leftStampKeys, (IntSegmentedSortedArray)ssa, rightKeysForLeft, disallowExactMatch);
}
private static void processEntry(IntChunk leftStampValues, Chunk leftStampKeys, IntSegmentedSortedArray ssa, WritableLongChunk rightKeysForLeft, boolean disallowExactMatch) {
final int leftSize = leftStampKeys.size();
final long rightSize = ssa.size();
if (rightSize == 0) {
rightKeysForLeft.fillWithValue(0, leftSize, RowSequence.NULL_ROW_KEY);
rightKeysForLeft.setSize(leftSize);
return;
}
final IntSegmentedSortedArray.Iterator ssaIt = ssa.iterator(disallowExactMatch, true);
for (int li = 0; li < leftSize; ) {
final int leftValue = leftStampValues.get(li);
final int comparison = doComparison(leftValue, ssaIt.getValue());
if (disallowExactMatch ? comparison <= 0 : comparison < 0) {
rightKeysForLeft.set(li++, RowSequence.NULL_ROW_KEY);
continue;
}
else if (comparison == 0) {
rightKeysForLeft.set(li++, ssaIt.getKey());
continue;
}
ssaIt.advanceToLast(leftValue);
final long redirectionKey = ssaIt.getKey();
if (!ssaIt.hasNext()) {
rightKeysForLeft.fillWithValue(li, leftSize - li, redirectionKey);
return;
} else {
rightKeysForLeft.set(li++, redirectionKey);
final int nextRightValue = ssaIt.nextValue();
while (li < leftSize && (disallowExactMatch ? leq(leftStampValues.get(li), nextRightValue) : lt(leftStampValues.get(li), nextRightValue))) {
rightKeysForLeft.set(li++, redirectionKey);
}
}
}
}
@Override
public void processRemovals(Chunk leftStampValues, LongChunk leftStampKeys, Chunk extends Values> rightStampChunk, LongChunk rightKeys, WritableLongChunk priorRedirections, WritableRowRedirection rowRedirection, RowSetBuilderRandom modifiedBuilder, boolean disallowExactMatch) {
processRemovals(leftStampValues.asIntChunk(), leftStampKeys, rightStampChunk.asIntChunk(), rightKeys, priorRedirections, rowRedirection, modifiedBuilder, disallowExactMatch);
}
private static void processRemovals(IntChunk leftStampValues, LongChunk leftStampKeys, IntChunk extends Values> rightStampChunk, LongChunk rightKeys, WritableLongChunk nextRedirections, WritableRowRedirection rowRedirection, RowSetBuilderRandom modifiedBuilder, boolean disallowExactMatch) {
// When removing a row, record the stamp, redirection key, and prior redirection key. Binary search
// in the left for the removed key to find the smallest value geq the removed right. Update all rows
// with the removed redirection to the previous key.
int leftLowIdx = 0;
for (int ii = 0; ii < rightStampChunk.size(); ++ii) {
final int rightStampValue = rightStampChunk.get(ii);
final long rightStampKey = rightKeys.get(ii);
final long newRightStampKey = nextRedirections.get(ii);
leftLowIdx = findFirstResponsiveLeft(leftLowIdx, leftStampValues, disallowExactMatch, rightStampValue);
while (leftLowIdx < leftStampKeys.size()) {
final long leftKey = leftStampKeys.get(leftLowIdx);
final long leftRedirectionKey = rowRedirection.get(leftKey);
if (leftRedirectionKey == rightStampKey) {
modifiedBuilder.addKey(leftKey);
if (newRightStampKey == RowSequence.NULL_ROW_KEY) {
rowRedirection.removeVoid(leftKey);
} else {
rowRedirection.putVoid(leftKey, newRightStampKey);
}
leftLowIdx++;
} else {
break;
}
}
}
}
@Override
public void processInsertion(Chunk leftStampValues, LongChunk leftStampKeys, Chunk extends Values> rightStampChunk, LongChunk rightKeys, Chunk nextRightValue, WritableRowRedirection rowRedirection, RowSetBuilderRandom modifiedBuilder, boolean endsWithLastValue, boolean disallowExactMatch) {
processInsertion(leftStampValues.asIntChunk(), leftStampKeys, rightStampChunk.asIntChunk(), rightKeys, nextRightValue.asIntChunk(), rowRedirection, modifiedBuilder, endsWithLastValue, disallowExactMatch);
}
private static void processInsertion(IntChunk leftStampValues, LongChunk leftStampKeys, IntChunk extends Values> rightStampChunk, LongChunk rightKeys, IntChunk nextRightValue, WritableRowRedirection rowRedirection, RowSetBuilderRandom modifiedBuilder, boolean endsWithLastValue, boolean disallowExactMatch) {
// We've already filtered out duplicate right stamps by the time we get here, which means that the rightStampChunk
// contains only values that are the last in any given run; and thus are possible matches.
// We binary search in the left for the first value >=, everything up until the next extant right value (contained
// in the nextRightValue chunk) should be re-stamped with our value
int leftLowIdx = 0;
for (int ii = 0; ii < rightStampChunk.size(); ++ii) {
final int rightStampValue = rightStampChunk.get(ii);
leftLowIdx = findFirstResponsiveLeft(leftLowIdx, leftStampValues, disallowExactMatch, rightStampValue);
final long rightStampKey = rightKeys.get(ii);
if (ii == rightStampChunk.size() - 1 && endsWithLastValue) {
while (leftLowIdx < leftStampKeys.size()) {
final long leftKey = leftStampKeys.get(leftLowIdx);
rowRedirection.putVoid(leftKey, rightStampKey);
modifiedBuilder.addKey(leftKey);
leftLowIdx++;
}
} else {
final int nextRight = nextRightValue.get(ii);
while (leftLowIdx < leftStampKeys.size()) {
final int leftValue = leftStampValues.get(leftLowIdx);
if (disallowExactMatch ? leq(leftValue, nextRight) : lt(leftValue, nextRight)) {
final long leftKey = leftStampKeys.get(leftLowIdx);
rowRedirection.putVoid(leftKey, rightStampKey);
modifiedBuilder.addKey(leftKey);
leftLowIdx++;
} else {
break;
}
}
}
}
}
@Override
public int findModified(int first, Chunk leftStampValues, LongChunk leftStampKeys, RowRedirection rowRedirection, Chunk extends Values> rightStampChunk, LongChunk rightStampIndices, RowSetBuilderRandom modifiedBuilder, boolean disallowExactMatch) {
return findModified(first, leftStampValues.asIntChunk(), leftStampKeys, rowRedirection, rightStampChunk.asIntChunk(), rightStampIndices, modifiedBuilder, disallowExactMatch);
}
private static int findModified(int leftLowIdx, IntChunk leftStampValues, LongChunk leftStampKeys, RowRedirection rowRedirection, IntChunk extends Values> rightStampChunk, LongChunk rightStampIndices, RowSetBuilderRandom modifiedBuilder, boolean disallowExactMatch) {
for (int ii = 0; ii < rightStampChunk.size(); ++ii) {
final int rightStampValue = rightStampChunk.get(ii);
// now find the lowest left value leq (lt) than rightStampValue
leftLowIdx = findFirstResponsiveLeft(leftLowIdx, leftStampValues, disallowExactMatch, rightStampValue);
final long rightStampKey = rightStampIndices.get(ii);
int checkIdx = leftLowIdx;
while (checkIdx < leftStampValues.size() && rowRedirection.get(leftStampKeys.get(checkIdx)) == rightStampKey) {
modifiedBuilder.addKey(leftStampKeys.get(checkIdx));
checkIdx++;
}
}
return leftLowIdx;
}
@Override
public void applyShift(Chunk leftStampValues, LongChunk leftStampKeys, Chunk extends Values> rightStampChunk, LongChunk rightStampKeys, long shiftDelta, WritableRowRedirection rowRedirection, boolean disallowExactMatch) {
applyShift(leftStampValues.asIntChunk(), leftStampKeys, rightStampChunk.asIntChunk(), rightStampKeys, shiftDelta, rowRedirection, disallowExactMatch);
}
private void applyShift(IntChunk leftStampValues, LongChunk leftStampKeys, IntChunk extends Values> rightStampChunk, LongChunk rightStampKeys, long shiftDelta, WritableRowRedirection rowRedirection, boolean disallowExactMatch) {
int leftLowIdx = 0;
for (int ii = 0; ii < rightStampChunk.size(); ++ii) {
final int rightStampValue = rightStampChunk.get(ii);
// now find the lowest left value leq (lt) than rightStampValue
leftLowIdx = findFirstResponsiveLeft(leftLowIdx, leftStampValues, disallowExactMatch, rightStampValue);
final long rightStampKey = rightStampKeys.get(ii);
int checkIdx = leftLowIdx;
while (checkIdx < leftStampValues.size() && rowRedirection.get(leftStampKeys.get(checkIdx)) == rightStampKey) {
rowRedirection.putVoid(leftStampKeys.get(checkIdx), rightStampKey + shiftDelta);
checkIdx++;
}
}
}
private static int findFirstResponsiveLeft(int leftLowIdx, IntChunk leftStampValues, boolean disallowExactMatch, int rightStampValue) {
int leftHighIdx = leftStampValues.size();
while (leftLowIdx < leftHighIdx) {
final int leftMidIdx = (leftHighIdx + leftLowIdx) >>> 1;
final int leftMidValue = leftStampValues.get(leftMidIdx);
final int comparison = doComparison(leftMidValue, rightStampValue);
final boolean moveLow = disallowExactMatch ? comparison <= 0 : comparison < 0;
if (moveLow) {
leftLowIdx = leftMidIdx + 1;
} else {
leftHighIdx = leftMidIdx;
}
}
return leftLowIdx;
}
// region comparison functions
private static int doComparison(int lhs, int rhs) {
return Integer.compare(lhs, rhs);
}
// endregion comparison functions
private static boolean lt(int lhs, int rhs) {
return doComparison(lhs, rhs) < 0;
}
private static boolean leq(int lhs, int rhs) {
return doComparison(lhs, rhs) <= 0;
}
}