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
  /**
   * par2 is a list of languages. For each language $L and domain $D, attempts to load the resource
   * $D:lang/$L.lang
   */
  public synchronized void loadLocaleDataFiles(IResourceManager p_135022_1_, List p_135022_2_) {
    this.field_135032_a.clear();
    Iterator var3 = p_135022_2_.iterator();

    while (var3.hasNext()) {
      String var4 = (String) var3.next();
      String var5 = String.format("lang/%s.lang", new Object[] {var4});
      Iterator var6 = p_135022_1_.getResourceDomains().iterator();

      while (var6.hasNext()) {
        String var7 = (String) var6.next();

        try {
          this.loadLocaleData(p_135022_1_.getAllResources(new ResourceLocation(var7, var5)));
        } catch (IOException var9) {;
        }
      }
    }

    this.checkUnicode();
  }
Example #3
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;

  }
Example #4
0
  /**
   * Invoked when a writable transaction prepares in order to validate its write sets (one per
   * isolated index). The default implementation is NOP.
   *
   * @return true iff the write sets were validated.
   */
  protected boolean validateWriteSets() {

    /*
     * for all isolated btrees, if(!validate()) return false;
     */

    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();

      /*
       * Note: this is the live version of the named index. We need to
       * validate against the live version of the index, not some
       * historical state.
       */

      final AbstractBTree[] sources = resourceManager.getIndexSources(name, UNISOLATED);

      if (sources == null) {

        log.warn("Index does not exist: " + name);

        return false;
      }

      if (!isolated.validate(sources)) {

        // Validation failed.

        if (log.isInfoEnabled()) log.info("validation failed: " + name);

        return false;
      }
    }

    return true;
  }
Example #5
0
  /**
   * Return a named index. The index will be isolated at the same level as this transaction. Changes
   * on the index will be made restart-safe iff the transaction successfully commits.
   *
   * @param name The name of the index.
   * @return The named index or <code>null</code> if no index is registered under that name.
   * @exception IllegalStateException if the transaction is not active.
   */
  public ILocalBTreeView getIndex(final String name) {

    if (name == null) throw new IllegalArgumentException();

    if (readOnly) {

      /*
       * Note: Access to the indices currently goes through the
       * IResourceManager interface for a read-only transaction.
       */

      throw new UnsupportedOperationException();
    }

    /*
     * @todo lock could be per index for higher concurrency rather than for
     * all indices which you might access through this tx.
     */
    lock.lock();

    try {

      if (!isActive()) {

        throw new IllegalStateException(NOT_ACTIVE);
      }

      /*
       * Test the cache - this is used so that we can recover the same
       * instance on each call within the same transaction.
       */

      if (indices.containsKey(name)) {

        // Already defined.

        return indices.get(name);
      }

      final ILocalBTreeView index;

      /*
       * See if the index was registered as of the ground state used by
       * this transaction to isolated indices.
       *
       * Note: IResourceManager#getIndex(String name,long timestamp) calls
       * us when the timestamp identifies an active transaction so we MUST
       * NOT call that method ourselves! Hence there is some replication
       * of logic between that method and this one.
       */

      final AbstractBTree[] sources =
          resourceManager.getIndexSources(name, readsOnCommitTime); // startTime);

      if (sources == null) {

        /*
         * The named index was not registered as of the transaction
         * ground state.
         */

        if (log.isInfoEnabled()) log.info("No such index: " + name + ", startTime=" + startTime);

        return null;
      }

      if (!sources[0].getIndexMetadata().isIsolatable()) {

        throw new RuntimeException("Not isolatable: " + name);
      }

      /*
       * Isolate the named btree.
       */

      //            if (readOnly) {
      //
      //                assert sources[0].isReadOnly();
      //
      //                if (sources.length == 1) {
      //
      //                    index = sources[0];
      //
      //                } else {
      //
      //                    index = new FusedView(sources);
      //
      //                }
      //
      //            } else {

      /*
       * Setup the view. The write set is always the first element in
       * the view.
       */

      // the view definition.
      final AbstractBTree[] b = new AbstractBTree[sources.length + 1];

      /*
       * Create the write set on a temporary store.
       *
       * Note: The BTree is NOT registered under a name so it can not
       * be discovered on the temporary store.  This is fine since we
       * hold onto a hard reference to the BTree in [indices].
       */
      b[0] = BTree.create(getTemporaryStore(), sources[0].getIndexMetadata().clone());

      System.arraycopy(sources, 0, b, 1, sources.length);

      // create view with isolated write set.
      index = new IsolatedFusedView(-startTime, b);

      // report event.
      ResourceManager.isolateIndex(startTime, name);

      //            }

      indices.put(name, index);

      return index;

    } finally {

      lock.unlock();
    }
  }