Search in sources :

Example 1 with JsRangeSet

use of io.deephaven.web.client.api.JsRangeSet in project deephaven-core by deephaven.

the class TableViewportSubscription method snapshot.

@JsMethod
public Promise<TableData> snapshot(JsRangeSet rows, Column[] columns) {
    // TODO #1039 slice rows and drop columns
    return copy.then(table -> {
        final ClientTableState state = table.state();
        String[] columnTypes = Arrays.stream(state.getTableDef().getColumns()).map(ColumnDefinition::getType).toArray(String[]::new);
        final BitSet columnBitset = table.lastVisibleState().makeBitset(columns);
        return Callbacks.<TableSnapshot, String>promise(this, callback -> {
            WorkerConnection connection = table.getConnection();
            BiDiStream<FlightData, FlightData> stream = connection.<FlightData, FlightData>streamFactory().create(headers -> connection.flightServiceClient().doExchange(headers), (first, headers) -> connection.browserFlightServiceClient().openDoExchange(first, headers), (next, headers, c) -> connection.browserFlightServiceClient().nextDoExchange(next, headers, c::apply), new FlightData());
            Builder doGetRequest = new Builder(1024);
            double columnsOffset = BarrageSubscriptionRequest.createColumnsVector(doGetRequest, makeUint8ArrayFromBitset(columnBitset));
            double viewportOffset = BarrageSubscriptionRequest.createViewportVector(doGetRequest, serializeRanges(Collections.singleton(rows.getRange())));
            double serializationOptionsOffset = BarrageSnapshotOptions.createBarrageSnapshotOptions(doGetRequest, ColumnConversionMode.Stringify, true, 0);
            double tableTicketOffset = BarrageSubscriptionRequest.createTicketVector(doGetRequest, state.getHandle().getTicket());
            BarrageSnapshotRequest.startBarrageSnapshotRequest(doGetRequest);
            BarrageSnapshotRequest.addTicket(doGetRequest, tableTicketOffset);
            BarrageSnapshotRequest.addColumns(doGetRequest, columnsOffset);
            BarrageSnapshotRequest.addSnapshotOptions(doGetRequest, serializationOptionsOffset);
            BarrageSnapshotRequest.addViewport(doGetRequest, viewportOffset);
            doGetRequest.finish(BarrageSnapshotRequest.endBarrageSnapshotRequest(doGetRequest));
            FlightData request = new FlightData();
            request.setAppMetadata(BarrageUtils.wrapMessage(doGetRequest, BarrageMessageType.BarrageSnapshotRequest));
            stream.send(request);
            stream.end();
            stream.onData(flightData -> {
                Message message = Message.getRootAsMessage(new ByteBuffer(flightData.getDataHeader_asU8()));
                if (message.headerType() == MessageHeader.Schema) {
                    // ignore for now, we'll handle this later
                    return;
                }
                assert message.headerType() == MessageHeader.RecordBatch;
                RecordBatch header = message.header(new RecordBatch());
                Uint8Array appMetadataBytes = flightData.getAppMetadata_asU8();
                BarrageUpdateMetadata update = null;
                if (appMetadataBytes.length != 0) {
                    BarrageMessageWrapper barrageMessageWrapper = BarrageMessageWrapper.getRootAsBarrageMessageWrapper(new io.deephaven.javascript.proto.dhinternal.flatbuffers.ByteBuffer(appMetadataBytes));
                    update = BarrageUpdateMetadata.getRootAsBarrageUpdateMetadata(new ByteBuffer(new Uint8Array(barrageMessageWrapper.msgPayloadArray())));
                }
                TableSnapshot snapshot = BarrageUtils.createSnapshot(header, BarrageUtils.typedArrayToLittleEndianByteBuffer(flightData.getDataBody_asU8()), update, true, columnTypes);
                callback.onSuccess(snapshot);
            });
            stream.onStatus(status -> {
                if (!status.isOk()) {
                    callback.onFailure(status.getDetails());
                }
            });
        }).then(defer()).then(snapshot -> {
            SubscriptionTableData pretendSubscription = new SubscriptionTableData(Js.uncheckedCast(columns), state.getRowFormatColumn() == null ? NO_ROW_FORMAT_COLUMN : state.getRowFormatColumn().getIndex(), null);
            TableData data = pretendSubscription.handleSnapshot(snapshot);
            return Promise.resolve(data);
        }).then(defer());
    });
}
Also used : BarrageSubscriptionOptions(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageSubscriptionOptions) ColumnConversionMode(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.ColumnConversionMode) IThenable(elemental2.promise.IThenable) Arrays(java.util.Arrays) BarrageSnapshotRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageSnapshotRequest) JsOptional(jsinterop.annotations.JsOptional) BarrageUtils.serializeRanges(io.deephaven.web.client.api.barrage.BarrageUtils.serializeRanges) BarrageUpdateMetadata(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageUpdateMetadata) Event(elemental2.dom.Event) JsRangeSet(io.deephaven.web.client.api.JsRangeSet) BarrageMessageType(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageMessageType) JsMethod(jsinterop.annotations.JsMethod) HasEventHandling(io.deephaven.web.client.api.HasEventHandling) Promise(elemental2.promise.Promise) BiDiStream(io.deephaven.web.client.api.barrage.stream.BiDiStream) ByteBuffer(io.deephaven.javascript.proto.dhinternal.flatbuffers.ByteBuffer) Callbacks(io.deephaven.web.client.api.Callbacks) TableData(io.deephaven.web.client.api.TableData) Js(jsinterop.base.Js) WorkerConnection(io.deephaven.web.client.api.WorkerConnection) JsTable(io.deephaven.web.client.api.JsTable) BarrageUtils.makeUint8ArrayFromBitset(io.deephaven.web.client.api.barrage.BarrageUtils.makeUint8ArrayFromBitset) Builder(io.deephaven.javascript.proto.dhinternal.flatbuffers.Builder) FlightData(io.deephaven.javascript.proto.dhinternal.arrow.flight.protocol.flight_pb.FlightData) BarrageSnapshotOptions(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageSnapshotOptions) Int8Array(elemental2.core.Int8Array) CustomEvent(elemental2.dom.CustomEvent) JsLog(io.deephaven.web.client.fu.JsLog) DomGlobal(elemental2.dom.DomGlobal) ClientTableState(io.deephaven.web.client.state.ClientTableState) CustomEventInit(elemental2.dom.CustomEventInit) NO_ROW_FORMAT_COLUMN(io.deephaven.web.client.api.subscription.ViewportData.NO_ROW_FORMAT_COLUMN) ColumnDefinition(io.deephaven.web.client.api.barrage.def.ColumnDefinition) RecordBatch(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.RecordBatch) Column(io.deephaven.web.client.api.Column) BarrageUtils(io.deephaven.web.client.api.barrage.BarrageUtils) Uint8Array(elemental2.core.Uint8Array) TableSnapshot(io.deephaven.web.shared.data.TableSnapshot) Message(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.Message) BarrageSubscriptionRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageSubscriptionRequest) BitSet(java.util.BitSet) MessageHeader(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.MessageHeader) Collections(java.util.Collections) BarrageMessageWrapper(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageMessageWrapper) BarrageMessageWrapper(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageMessageWrapper) Message(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.Message) RecordBatch(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.RecordBatch) Builder(io.deephaven.javascript.proto.dhinternal.flatbuffers.Builder) BitSet(java.util.BitSet) ByteBuffer(io.deephaven.javascript.proto.dhinternal.flatbuffers.ByteBuffer) BarrageUpdateMetadata(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageUpdateMetadata) BiDiStream(io.deephaven.web.client.api.barrage.stream.BiDiStream) FlightData(io.deephaven.javascript.proto.dhinternal.arrow.flight.protocol.flight_pb.FlightData) ClientTableState(io.deephaven.web.client.state.ClientTableState) TableSnapshot(io.deephaven.web.shared.data.TableSnapshot) Uint8Array(elemental2.core.Uint8Array) TableData(io.deephaven.web.client.api.TableData) WorkerConnection(io.deephaven.web.client.api.WorkerConnection) JsMethod(jsinterop.annotations.JsMethod)

Example 2 with JsRangeSet

use of io.deephaven.web.client.api.JsRangeSet 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();
        }
    }
}
Also used : java.util(java.util) UpdateEventData(io.deephaven.web.client.api.subscription.SubscriptionTableData.UpdateEventData) JsSettings(io.deephaven.web.client.fu.JsSettings) JsRangeSet(io.deephaven.web.client.api.JsRangeSet) Range(io.deephaven.web.shared.data.Range) JsArray(elemental2.core.JsArray) Any(jsinterop.base.Any) TableData(io.deephaven.web.client.api.TableData) Column(io.deephaven.web.client.api.Column) Js(jsinterop.base.Js) JsTable(io.deephaven.web.client.api.JsTable) Entry(java.util.Map.Entry) JsType(jsinterop.annotations.JsType) JsFunction(io.deephaven.web.shared.fu.JsFunction) JsArray(elemental2.core.JsArray) JsRangeSet(io.deephaven.web.client.api.JsRangeSet) Range(io.deephaven.web.shared.data.Range) Any(jsinterop.base.Any) UpdateEventData(io.deephaven.web.client.api.subscription.SubscriptionTableData.UpdateEventData)

Aggregations

Column (io.deephaven.web.client.api.Column)2 JsRangeSet (io.deephaven.web.client.api.JsRangeSet)2 JsTable (io.deephaven.web.client.api.JsTable)2 TableData (io.deephaven.web.client.api.TableData)2 Js (jsinterop.base.Js)2 Int8Array (elemental2.core.Int8Array)1 JsArray (elemental2.core.JsArray)1 Uint8Array (elemental2.core.Uint8Array)1 CustomEvent (elemental2.dom.CustomEvent)1 CustomEventInit (elemental2.dom.CustomEventInit)1 DomGlobal (elemental2.dom.DomGlobal)1 Event (elemental2.dom.Event)1 IThenable (elemental2.promise.IThenable)1 Promise (elemental2.promise.Promise)1 Message (io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.Message)1 MessageHeader (io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.MessageHeader)1 RecordBatch (io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.RecordBatch)1 FlightData (io.deephaven.javascript.proto.dhinternal.arrow.flight.protocol.flight_pb.FlightData)1 Builder (io.deephaven.javascript.proto.dhinternal.flatbuffers.Builder)1 ByteBuffer (io.deephaven.javascript.proto.dhinternal.flatbuffers.ByteBuffer)1