Exemplo n.º 1
0
  public void set(E value) {

    if (dataObject == null) {
      throw new IllegalStateException();
    }
    if (!coll.hasValues()) {
      throw new UnsupportedOperationException();
    }
    DataCursor cursor = null;
    boolean doAutoCommit = coll.beginAutoCommit();
    try {
      cursor = new DataCursor(coll.view, writeAllowed);
      if (moveCursor(dataIndex, cursor)) {
        cursor.putCurrent(value);
        setSlot(dataIndex, cursor);
        coll.closeCursor(cursor);
        coll.commitAutoCommit(doAutoCommit);
      } else {
        throw new IllegalStateException();
      }
    } catch (Exception e) {
      coll.closeCursor(cursor);
      throw coll.handleException(e, doAutoCommit);
    }
  }
Exemplo n.º 2
0
  public void add(E value) {

    /*
     * The checkIterAddAllowed method ensures that one of the following two
     * conditions holds and throws UnsupportedOperationException otherwise:
     * 1- This is a list iterator for a recno-renumber database.
     * 2- This is a collection iterator for a duplicates database.
     */
    coll.checkIterAddAllowed();
    OperationStatus status = OperationStatus.SUCCESS;
    DataCursor cursor = null;
    boolean doAutoCommit = coll.beginAutoCommit();
    try {
      if (coll.view.keysRenumbered || !coll.areDuplicatesOrdered()) {

        /*
         * This is a recno-renumber database or a btree/hash database
         * with unordered duplicates.
         */
        boolean hasPrev = hasPrevious();
        if (!hasPrev && !hasNext()) {

          /* The collection is empty. */
          if (coll.view.keysRenumbered) {

            /* Append to an empty recno-renumber database. */
            status = coll.view.append(value, null, null);

          } else if (coll.view.dupsAllowed && coll.view.range.isSingleKey()) {

            /*
             * When inserting a duplicate into a single-key range,
             * the main key is fixed, so we can always insert into
             * an empty collection.
             */
            cursor = new DataCursor(coll.view, writeAllowed);
            cursor.useRangeKey();
            status = cursor.putNoDupData(null, value, null, true);
            coll.closeCursor(cursor);
            cursor = null;
          } else {
            throw new IllegalStateException("Collection is empty, cannot add() duplicate");
          }

          /*
           * Move past the record just inserted (the cursor should be
           * closed above to prevent multiple open cursors in certain
           * DB core modes).
           */
          if (status == OperationStatus.SUCCESS) {
            next();
            dataIndex = nextIndex - 1;
          }
        } else {

          /*
           * The collection is non-empty.  If hasPrev is true then
           * the element at (nextIndex - 1) is available; otherwise
           * the element at nextIndex is available.
           */
          cursor = new DataCursor(coll.view, writeAllowed);
          int insertIndex = hasPrev ? (nextIndex - 1) : nextIndex;

          if (!moveCursor(insertIndex, cursor)) {
            throw new IllegalStateException();
          }

          /*
           * For a recno-renumber database or a database with
           * unsorted duplicates, insert before the iterator 'next'
           * position, or after the 'prev' position.  Then adjust
           * the slots to account for the inserted record.
           */
          status = hasPrev ? cursor.putAfter(value) : cursor.putBefore(value);
          if (status == OperationStatus.SUCCESS) {
            insertSlot(nextIndex, cursor);
          }
        }
      } else {
        /* This is a btree/hash database with ordered duplicates. */
        cursor = new DataCursor(coll.view, writeAllowed);

        if (coll.view.range.isSingleKey()) {

          /*
           * When inserting a duplicate into a single-key range,
           * the main key is fixed.
           */
          cursor.useRangeKey();
        } else {

          /*
           * When inserting into a multi-key range, the main key
           * is the last dataIndex accessed by next(), previous()
           * or add().
           */
          if (dataIndex < 0 || !moveCursor(dataIndex, cursor)) {
            throw new IllegalStateException();
          }
        }

        /*
         * For a hash/btree with duplicates, insert the duplicate,
         * put the new record in slot zero, and set the next index
         * to slot one (past the new record).
         */
        status = cursor.putNoDupData(null, value, null, true);
        if (status == OperationStatus.SUCCESS) {
          clearSlots();
          setSlot(0, cursor);
          dataIndex = 0;
          nextIndex = 1;
        }
      }

      if (status == OperationStatus.KEYEXIST) {
        throw new IllegalArgumentException("Duplicate value");
      } else if (status != OperationStatus.SUCCESS) {
        throw new IllegalArgumentException("Could not insert: " + status);
      }

      /* Prevent subsequent set() or remove() call. */
      dataObject = null;

      coll.closeCursor(cursor);
      coll.commitAutoCommit(doAutoCommit);
    } catch (Exception e) {
      /* Catch RuntimeExceptions too. */
      coll.closeCursor(cursor);
      throw coll.handleException(e, doAutoCommit);
    }
  }
Exemplo n.º 3
0
  public void remove() {

    if (dataObject == null) {
      throw new IllegalStateException();
    }
    DataCursor cursor = null;
    boolean doAutoCommit = coll.beginAutoCommit();
    try {
      cursor = new DataCursor(coll.view, writeAllowed);
      if (moveCursor(dataIndex, cursor)) {
        cursor.delete();
        deleteSlot(dataIndex);
        dataObject = null;

        /*
         * Repopulate the block after removing all records, using the
         * cursor position of the deleted record as a starting point.
         * First try moving forward, since the user was moving forward.
         * (It is possible to delete all records in the block only by
         * moving forward, i.e, when nextIndex is greater than
         * dataIndex.)
         */
        if (nextIndex == 0 && keys[0] == null) {
          OperationStatus status;
          for (int i = 0; i < keys.length; i += 1) {
            status = coll.iterateDuplicates() ? cursor.getNext(false) : cursor.getNextNoDup(false);
            if (status == OperationStatus.SUCCESS) {
              setSlot(i, cursor);
            } else {
              break;
            }
          }

          /*
           * If no records are found past the cursor position, try
           * moving backward.  If no records are found before the
           * cursor position, leave nextIndex set to keys.length,
           * which is the same as the initial iterator state and is
           * appropriate for an empty key range.
           */
          if (keys[0] == null) {
            nextIndex = keys.length;
            for (int i = nextIndex - 1; i >= 0; i -= 1) {
              status =
                  coll.iterateDuplicates() ? cursor.getPrev(false) : cursor.getPrevNoDup(false);
              if (status == OperationStatus.SUCCESS) {
                setSlot(i, cursor);
              } else {
                break;
              }
            }
          }
        }
        coll.closeCursor(cursor);
        coll.commitAutoCommit(doAutoCommit);
      } else {
        throw new IllegalStateException();
      }
    } catch (Exception e) {
      coll.closeCursor(cursor);
      throw coll.handleException(e, doAutoCommit);
    }
  }