Example #1
0
  /**
   * Invoked during commit processing to merge down the write set from each index isolated by this
   * transactions onto the corresponding unisolated index on the database. This method invoked iff a
   * transaction has successfully prepared and hence is known to have validated successfully. The
   * default implementation is a NOP.
   *
   * @param revisionTime
   * @see <a href="https://sourceforge.net/apps/trac/bigdata/ticket/675" >Flush indices in parallel
   *     during checkpoint to reduce IO latency</a>
   */
  protected void mergeOntoGlobalState(final long revisionTime) {

    this.revisionTime = revisionTime;

    // Create tasks to checkpoint the indices.
    final List<Callable<Void>> tasks = new LinkedList<Callable<Void>>();
    {
      final Iterator<Map.Entry<String, ILocalBTreeView>> itr = indices.entrySet().iterator();

      while (itr.hasNext()) {

        final Map.Entry<String, ILocalBTreeView> entry = itr.next();

        final String name = entry.getKey();

        final IsolatedFusedView isolated = (IsolatedFusedView) entry.getValue();

        tasks.add(new CheckpointIndexTask(name, isolated));
      }
    }

    /*
     * Submit checkpoint tasks.
     *
     * Note: Method blocks until all tasks are done.
     */
    final List<Future<Void>> futures;
    try {

      futures = resourceManager.getLiveJournal().getExecutorService().invokeAll(tasks);

    } catch (InterruptedException ex) {

      throw new RuntimeException(ex);
    }

    /*
     * Check Futures for errors.
     *
     * Note: Per above, all futures are known to be done.
     */
    for (Future<Void> f : futures) {

      try {
        f.get();
      } catch (InterruptedException e) {

        throw new RuntimeException(e);

      } catch (ExecutionException e) {

        throw new RuntimeException(e);
      }
    }
  }
Example #2
0
  /**
   * @todo This might need to be a full {@link Journal} using {@link BufferMode#Temporary} in order
   *     to have concurrency control for the isolated named indices. This would let us leverage the
   *     existing {@link WriteExecutorService} for handling concurrent operations within a
   *     transaction on the same named _isolated_ resource. There are a lot of issues here,
   *     including the level of concurrency expected for transactions. Also, note that the write set
   *     of the tx is not restart safe, we never force writes to disk, etc. Those are good fits for
   *     the {@link BufferMode#Temporary} {@link BufferMode}. However, it might be nice to do
   *     without having a {@link WriteExecutorService} per transaction, e.g., by placing the named
   *     indices for a transaction within a namespace for that tx.
   * @todo Rather than creating a distinct {@link TemporaryStore} for each tx and then closing and
   *     deleting the store when the tx completes, just use the temporary store factory. Once there
   *     are no more tx's using a given temporary store it will automatically be finalized and
   *     deleted. However, it is important that we namespace the indices so that different
   *     transactions do not see one another's data.
   *     <p>We can do this just as easily with {@link BufferMode#Temporary}, but {@link
   *     IIndexStore#getTempStore()} would have to be modified. However, that would give us more
   *     concurrency control in the tmp stores and we might need that for concurrent access to named
   *     indices (see above).
   */
  private IRawStore getTemporaryStore() {

    return resourceManager.getLiveJournal().getTempStore();

    //        assert lock.isHeldByCurrentThread();
    //
    //        if (tmpStore == null) {
    //
    //            final int offsetBits = resourceManager.getLiveJournal()
    //                    .getOffsetBits();
    //
    //            tmpStore = new TemporaryRawStore(offsetBits);
    //
    //        }
    //
    //        return tmpStore;

  }