All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.objectfabric.IndexedDBQueue Maven / Gradle / Ivy

The newest version!
/**
 * This file is part of ObjectFabric (http://objectfabric.org).
 *
 * ObjectFabric is licensed under the Apache License, Version 2.0, the terms
 * of which may be found at http://www.apache.org/licenses/LICENSE-2.0.html.
 * 
 * Copyright ObjectFabric Inc.
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

package org.objectfabric;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.typedarrays.client.Uint8ArrayNative;
import com.google.gwt.typedarrays.shared.ArrayBuffer;

final class IndexedDBQueue extends BlockQueue implements Runnable {

    private static final int MAX_ONGOING = 10;

    private final IndexedDB _location;

    private int _ongoing;

    IndexedDBQueue(IndexedDB location) {
        _location = location;

        onStarted();
    }

    @Override
    protected void enqueue() {
        Platform.get().execute(this);
    }

    @Override
    public void run() {
        if (onRunStarting()) {
            if (Debug.ENABLED)
                ThreadAssert.resume(this, false);

            runMessages(false);

            while (_ongoing < MAX_ONGOING) {
                Block block = nextBlock();

                if (block == null)
                    break;

                if (Debug.PERSISTENCE_LOG)
                    Log.write("IndexedDB write " + block.URI + " - " + Tick.toString(block.Tick));

                if (Stats.ENABLED)
                    Stats.Instance.BlockWriteCount.incrementAndGet();

                write(_location.transaction(false), block.URI, block.Tick, block.Buffs, block.Removals, true);
            }

            if (Debug.ENABLED)
                ThreadAssert.suspend(this);

            onRunEnded(false);
        }
    }

    final void write(JavaScriptObject transaction, URI uri, long tick, Buff[] buffs, long[] removals, boolean callback) {
        IndexedDBView view = (IndexedDBView) uri.getOrCreate(_location);
        ArrayBuffer buffer;

        if (buffs.length == 1) {
            GWTBuff buff = (GWTBuff) buffs[0];
            buffer = buff.slice();
        } else {
            int capacity = 0;

            for (int i = 0; i < buffs.length; i++)
                capacity += buffs[i].remaining();

            Uint8ArrayNative array = Uint8ArrayNative.create(capacity);
            int position = 0;

            for (int i = 0; i < buffs.length; i++) {
                GWTBuff buff = (GWTBuff) buffs[i];
                array.set(buff.typed().subarray(buff.position(), buff.limit()), position);
                position += buff.remaining();
            }

            buffer = array.buffer();
        }

        JavaScriptObject request = write(transaction, IndexedDB.BLOCKS, view.getKey(tick), buffer);

        if (callback)
            callback(request, view, uri, new long[] { tick }, buffs, removals);

        if (removals != null)
            for (int i = 0; i < removals.length; i++)
                if (!Tick.isNull(removals[i]))
                    delete(_location.db(), IndexedDB.BLOCKS, view.getKey(removals[i]));

        _ongoing++;
    }

    private native JavaScriptObject write(JavaScriptObject transaction, String store, String key, ArrayBuffer value) /*-{
    return transaction.objectStore(store).put(value, key);
    }-*/;

    private native void callback(JavaScriptObject request, IndexedDBView view, URI uri, long[] tick, Buff[] buffs, long[] removals) /*-{
    var this_ = this;

    request.onsuccess = function(e) {
      [email protected]::onsuccess(Lorg/objectfabric/IndexedDBView;Lorg/objectfabric/URI;[J[Lorg/objectfabric/Buff;[J)(view, uri, tick , buffs, removals);
    };
    }-*/;

    private final void onsuccess(IndexedDBView view, URI uri, long[] tick, Buff[] buffs, long[] removals) {
        _ongoing--;

        for (int i = 0; i < buffs.length; i++)
            buffs[i].recycle();

        uri.onAck(view, tick[0]);
        view.add(tick[0], removals);

        // In case blocks left in queue
        requestRun();
    }

    private native void delete(JavaScriptObject db, String store, String key) /*-{
    var transaction = db.transaction(store, "readwrite");
    transaction.objectStore(store)["delete"](key);
    }-*/;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy