Exemple #1
0
  /**
   * Create a transaction reading from the most recent committed state not later than the specified
   * startTime.
   *
   * <p>Note: For an {@link IBigdataFederation}, a transaction does not start execution on all
   * {@link IDataService}s at the same moment. Instead, the transaction startTime is assigned by the
   * {@link ITransactionService} and then provided each time an {@link ITx} must be created for
   * isolatation of resources accessible on a {@link IDataService}.
   *
   * @param transactionManager The local (client-side) transaction manager.
   * @param resourceManager Provides access to named indices that are isolated by the transaction.
   * @param startTime The transaction identifier
   * @param readsOnCommitTime The timestamp of the commit point against which this transaction is
   *     reading.
   * @see <a href="https://sourceforge.net/apps/trac/bigdata/ticket/266">Refactor native long tx id
   *     to thin object</a>
   * @see <a href="http://sourceforge.net/apps/trac/bigdata/ticket/546" > Add cache for access to
   *     historical index views on the Journal by name and commitTime. </a>
   */
  public Tx( //
      final AbstractLocalTransactionManager localTransactionManager, //
      final IResourceManager resourceManager, //
      final long startTime,
      final long readsOnCommitTime //
      ) {

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

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

    this.readOnly = !TimestampUtility.isReadWriteTx(startTime);

    //        if (!TimestampUtility.isReadWriteTx(startTime)) {
    //
    //            /*
    //             * Note: We only maintain local state for read-write transactions.
    //             */
    //
    //            throw new IllegalArgumentException();
    //
    //        }

    //        this.localTransactionManager = localTransactionManager;

    this.indices = readOnly ? null : new ConcurrentHashMap<String, ILocalBTreeView>();

    this.resourceManager = resourceManager;

    this.startTime = startTime;

    /*
     * Note: On a new journal, the lastCommitTime is ZERO before the first
     * commit point. In order to avoid having the ground state view be the
     * UNISOLATED index view, we use a timestamp which is known to be before
     * any valid timestamp (and which will be shared by any transaction
     * started against an empty journal).
     *
     * Note: It might be better to put this logic into
     * Journal#getLastCommitTime(). However, there are other callers for
     * that method. By making the change here, we can guarantee that its
     * scope is limited to only the code change made for the following
     * ticket.
     *
     * @see <a href="http://sourceforge.net/apps/trac/bigdata/ticket/546" >
     * Add cache for access to historical index views on the Journal by name
     * and commitTime. </a>
     */
    this.readsOnCommitTime = readsOnCommitTime == ITx.UNISOLATED ? 1 : readsOnCommitTime;

    this.runState = RunState.Active;

    // pre-compute the hash code for the transaction.
    this.hashCode = Long.valueOf(startTime).hashCode();

    localTransactionManager.activateTx(this);

    // report event.
    ResourceManager.openTx(startTime);
  }
Exemple #2
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();
    }
  }