io.deephaven.engine.table.impl.util.ShiftData 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.util;
import gnu.trove.list.TLongList;
import gnu.trove.list.array.TLongArrayList;
import io.deephaven.engine.rowset.RowSet;
public class ShiftData {
private final TLongArrayList startIndex;
private final TLongArrayList endIndex;
private final TLongArrayList offsets;
private final int size;
private int runningSize = 0;
private long runningOffset = 0;
public RowSet getAddedPos() {
return addedPos;
}
private RowSet addedPos;
public ShiftData(RowSet rowSet, RowSet removed, RowSet added) {
TLongList[] removedKeys = rowSet.findMissing(removed);
addedPos = rowSet.invert(added);
endIndex = new TLongArrayList();
startIndex = new TLongArrayList();
offsets = new TLongArrayList();
int removedIndex = 0;
TLongList removedPositions = removedKeys[0];
TLongList removedCount = removedKeys[1];
for (RowSet.RangeIterator addedIt = addedPos.rangeIterator(); addedIt.hasNext();) {
addedIt.next();
int startOffset = (int) addedIt.currentRangeStart();
int endOffset = (int) addedIt.currentRangeEnd();
while (removedIndex < removedPositions.size() && removedPositions.get(removedIndex) < startOffset) {
removeRange(removedPositions.get(removedIndex), removedCount.get(removedIndex));
removedIndex++;
}
int deleteCount = 0;
while (removedIndex < removedPositions.size() && removedPositions.get(removedIndex) <= endOffset) {
deleteCount += removedCount.get(removedIndex);
removedIndex++;
}
addRange(startOffset, endOffset, deleteCount);
}
while (removedIndex < removedPositions.size()) {
removeRange(removedPositions.get(removedIndex), removedCount.get(removedIndex));
removedIndex++;
}
if (runningSize > 0) {
if (startIndex.get(runningSize - 1) <= (rowSet.size() - added.size() + removed.size() - 1)) {
endIndex.set(runningSize - 1, (int) (rowSet.size() - added.size() + removed.size() - 1));
} else {
runningSize--;
}
}
size = runningSize;
}
void addRange(long firstIndex, long lastIndex, long deletionCount) {
if (lastIndex - firstIndex + 1 == deletionCount) {
return;
}
if (runningSize > 0) {
endIndex.set(runningSize - 1, firstIndex - runningOffset - 1);
}
long newStartIndex = firstIndex + deletionCount - runningOffset;
runningOffset = lastIndex + runningOffset + 1 - (deletionCount + firstIndex);
if (runningSize > 0 && ((newStartIndex + runningOffset) == (startIndex.get(runningSize - 1)
+ offsets.get(runningSize - 1)))) {
startIndex.set(runningSize - 1, newStartIndex);
offsets.set(runningSize - 1, runningOffset);
} else {
startIndex.add(newStartIndex);
offsets.add(runningOffset);
endIndex.add(0);
runningSize++;
}
}
void removeRange(long firstIndex, long count) {
if (runningSize > 0) {
endIndex.set(runningSize - 1, firstIndex - runningOffset - 1);
}
long newStartIndex = firstIndex - runningOffset + count;
runningOffset = runningOffset - count;
if (runningSize > 0
&& (newStartIndex + runningOffset == startIndex.get(runningSize - 1) + offsets.get(runningSize - 1))) {
startIndex.set(runningSize - 1, newStartIndex);
offsets.set(runningSize - 1, runningOffset);
} else {
startIndex.add(newStartIndex);
offsets.add(runningOffset);
endIndex.add(0);
runningSize++;
}
}
public interface ShiftCallback {
void shift(long start, long end, long offset);
}
public interface RowSetShiftCallback {
void shift(RowSet rowSet, long offset);
}
public void applyDataShift(ShiftCallback shiftCallback) {
int startPos = 0;
int currentPos = 0;
while (currentPos < size) {
if (offsets.get(startPos) > 0) {
while (currentPos < size && offsets.get(currentPos) > 0) {
currentPos++;
}
for (int ii = currentPos - 1; ii >= startPos; ii--) {
shiftCallback.shift(startIndex.get(ii), endIndex.get(ii), offsets.get(ii));
}
} else if (offsets.get(startPos) < 0) {
while (currentPos < size && offsets.get(currentPos) < 0) {
currentPos++;
}
for (int ii = startPos; ii < currentPos; ii++) {
shiftCallback.shift(startIndex.get(ii), endIndex.get(ii), offsets.get(ii));
}
} else {
while (currentPos < size && offsets.get(currentPos) == 0) {
currentPos++;
}
}
startPos = currentPos;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy