use of io.deephaven.web.client.api.subscription.SubscriptionTableData.UpdateEventData in project deephaven-core by deephaven.
the class ChartData method update.
public void update(Object eventDetail) {
assert eventDetail instanceof UpdateEventData : "update() can only take table subscription event instances";
UpdateEventData tableData = (UpdateEventData) eventDetail;
Iterator<Range> addedIterator = tableData.getAdded().getRange().rangeIterator();
Iterator<Range> removedIterator = tableData.getRemoved().getRange().rangeIterator();
Iterator<Range> modifiedIterator = tableData.getModified().getRange().rangeIterator();
Range nextAdded = addedIterator.hasNext() ? addedIterator.next() : null;
Range nextRemoved = removedIterator.hasNext() ? removedIterator.next() : null;
Range nextModified = modifiedIterator.hasNext() ? modifiedIterator.next() : null;
int i = 0;
// not useful for adding/modifying data, but fast and easy to use when removing rows
JsArray<Any>[] allColumns;
if (nextRemoved != null) {
// noinspection unchecked
allColumns = cachedData.values().stream().flatMap(m -> m.values().stream()).toArray(JsArray[]::new);
} else {
allColumns = null;
}
while (nextAdded != null || nextRemoved != null || nextModified != null) {
if (i >= indexes.length) {
// Note that this is the first case we'll hit on initial snapshot
assert nextRemoved == null;
assert nextModified == null;
while (nextAdded != null) {
insertDataRange(tableData, nextAdded, i);
// increment i past these new items so our offset is correct if there is a next block
i += nextAdded.size();
// not bothering with i or lastIndexSeen since we will break after this while loop
nextAdded = addedIterator.hasNext() ? addedIterator.next() : null;
}
break;
}
long nextIndex = indexes[i];
// index, while the other two start at the current index
if (nextAdded != null && nextAdded.getFirst() < nextIndex) {
// the whole range should be there if any is
assert nextAdded.getLast() < nextIndex;
// update the index array and insert the actual data into our mapped columns
insertDataRange(tableData, nextAdded, i);
// increment i past these new items, so that our "next" is actually next
i += nextAdded.size();
nextAdded = addedIterator.hasNext() ? addedIterator.next() : null;
} else if (nextModified != null && nextModified.getFirst() == nextIndex) {
// somehow being asked to update an item which wasn't
assert nextModified.getLast() >= nextIndex;
// the updated block is contiguous, make sure there are at least that many items to tweak
assert indexes.length - i >= nextModified.size();
replaceDataRange(tableData, nextModified, i);
// advance i past this section, since no other change can happen to these rows
i += nextModified.size();
nextModified = modifiedIterator.hasNext() ? modifiedIterator.next() : null;
} else if (nextRemoved != null && nextRemoved.getFirst() == nextIndex) {
// somehow being asked to remove an item which wasn't present
assert nextRemoved.getLast() >= nextIndex;
// the block being removed is contiguous, so make sure there are at least that many and splice them out
assert indexes.length - i >= nextRemoved.size();
// splice out the indexes
asArray(indexes).splice(i, (int) nextRemoved.size());
// splice out the data itself
assert allColumns != null;
for (JsArray<Any> column : allColumns) {
column.splice(i, (int) nextRemoved.size());
}
// don't in/decrement i, we'll just keep going
nextRemoved = removedIterator.hasNext() ? removedIterator.next() : null;
} else {
// no match, keep reading
i++;
}
}
if (JsSettings.isDevMode()) {
assert ((UpdateEventData) eventDetail).getRows().length == indexes.length;
assert cachedData.values().stream().flatMap(m -> m.values().stream()).allMatch(arr -> arr.length == indexes.length);
assert cachedData.values().stream().flatMap(m -> m.values().stream()).allMatch(arr -> arr.reduce((Object val, Any p1, int p2, JsArray<Any> p3) -> ((Integer) val) + 1, 0) == indexes.length);
JsRangeSet fullIndex = tableData.getFullIndex();
PrimitiveIterator.OfLong iter = fullIndex.getRange().indexIterator();
for (int j = 0; j < indexes.length; j++) {
assert indexes[j] == iter.nextLong();
}
}
}
Aggregations