Package com.sleepycat.je.txn

Examples of com.sleepycat.je.txn.Locker


     */
    cursor.updateBin(bin, duplicateEntryIndex);
    if (n != null) {
        bin.releaseLatch();
    }
    Locker locker = cursor.getLocker();
                LockResult currentLock = null;
    while (n != null) {

        /*
         * Write lock instead of read lock to avoid upgrade issues.
         * There's a good chance that we'll need it for write
         * anyway.
         */
        currentLock = locker.lock
                        (currentLN.getNodeId(), LockType.WRITE, database);
        bin = cursor.latchBIN();
        duplicateEntryIndex = cursor.getIndex();
        n = bin.fetchTarget(duplicateEntryIndex);
        if (n == null) {
      currentLN = null;
      break;
        }
        if (n == currentLN ||
      dupCount != -1) {
      break;
        } else {

      /*
       * We should consider releasing the lock on currentLN
       * here.  However, it may be been locked from a prior
       * operation in this transaction.
       */
      if (n instanceof LN) {
          currentLN = (LN) n;
          dupCount = -1;
      } else {
          DIN duplicateRoot = (DIN) n;
          currentLN = (DupCountLN)
        duplicateRoot.getDupCountLNRef().
        fetchTarget(database, duplicateRoot);
          dupCount = ((DupCountLN) currentLN).getDupCount();
      }

      bin.releaseLatch();
        }
    }

    /*
     * If the ref is knownDeleted (DupCountLN's can't be deleted or
     * knownDeleted), or the LN that it points to is not a
     * DupCountLN and the data in it is deleted, then we substitute
     * the argument LN for it.
     *
     * dupCount == -1 means there is no dup tree here.
                 *
                 * If fetchTarget returns null, a deleted LN was cleaned.
     */
    boolean isDeleted = false;
                if (bin.isEntryKnownDeleted(duplicateEntryIndex)) {
                    isDeleted = true;
                } else if (dupCount == -1) {
                    LN existingLN = (LN) bin.fetchTarget(duplicateEntryIndex);
                    if (existingLN == null || existingLN.isDeleted()) {
                        isDeleted = true;
                    }
                }

                if (isDeleted) {

                    /*
                     * Set the abort LSN to that of the lock held on the
                     * current LN, if the current LN was previously locked by
                     * this txn.  This is needed when we change the node ID of
                     * this slot.
                     *
                     * If reusing a slot with an deleted LN deleted in a prior
                     * transaction (the LockGrantType is NEW or UPGRADE),
                     * always set abortKnownDeleted=true.  It may be that the
                     * existing slot is PENDING_DELETED, but we restore to
                     * KNOWN_DELETED in the event of an abort.
                     */
                    long abortLsn = bin.getLsn(duplicateEntryIndex);
                    boolean abortKnownDeleted = true;
                    if (currentLN != null &&
                        currentLock.getLockGrant() == LockGrantType.EXISTING) {
                        long nodeId = currentLN.getNodeId();
      abortLsn = locker.getAbortLsn(nodeId);
                        abortKnownDeleted =
          locker.getAbortKnownDeleted(nodeId);
                    }
        lnLock.setAbortLsn(abortLsn, abortKnownDeleted);

                    /*
                     * Current entry is a deleted entry. Replace it with LN.
View Full Code Here


                     * See the comment at the similar piece of code in insert()
                     * above.
         */
        cursor.updateDBin(duplicateBin, duplicateEntryIndex);
        duplicateBin.releaseLatch();
        Locker locker = cursor.getLocker();
                    LockResult currentLock = null;
        bin.releaseLatchIfOwner();

        while (currentLN != null) {
      currentLock = locker.lock
                            (currentLN.getNodeId(), LockType.WRITE, database);
      while (true) {
          duplicateBin = cursor.getDupBIN();
          duplicateBin.latch();
          if (duplicateBin != cursor.getDupBIN()) {
        duplicateBin.releaseLatch();
        continue;
          } else {
        break;
          }
      }
      duplicateEntryIndex = cursor.getDupIndex();
      n = duplicateBin.fetchTarget(duplicateEntryIndex);
      if (n == null) {
          currentLN = null;
          break;
      }
      if (n == currentLN) {
          break;
      } else {
          duplicateBin.releaseLatch();
          currentLN = (LN) n;
      }
        }

                    /* If currentLN is null, a deleted LN was cleaned.*/
        boolean isKnownDeleted =
      duplicateBin.isEntryKnownDeleted(duplicateEntryIndex);
                    if (isKnownDeleted ||
                        currentLN == null ||
                        currentLN.isDeleted()) {

                        /*
       * Existing entry is deleted.  Replace it.  If called
                         * on behalf of a cursor, update it to point to the
                         * entry that has been successfully inserted.
       */
      cursor.updateDBin(duplicateBin, duplicateEntryIndex);

                        /*
                         * Set the abort LSN to that of the lock held on the
                         * current LN, if the current LN was previously locked
                         * by this txn.  This is needed when we change the node
                         * ID of this slot.
                         *
                         * If reusing a slot with an deleted LN deleted in a
                         * prior transaction (the LockGrantType is NEW or
                         * UPGRADE), always set abortKnownDeleted=true.  It may
                         * be that the existing slot is PENDING_DELETED, but we
                         * restore to KNOWN_DELETED in the event of an abort.
                         */
                        long abortLsn = duplicateBin.getLsn
                            (duplicateEntryIndex);
                        boolean abortKnownDeleted = true;
                        if (currentLN != null &&
                            currentLock.getLockGrant() ==
                            LockGrantType.EXISTING) {
                            long nodeId = currentLN.getNodeId();
          abortLsn = locker.getAbortLsn(nodeId);
                            abortKnownDeleted =
                                locker.getAbortKnownDeleted(nodeId);
      }
      lnLock.setAbortLsn(abortLsn, abortKnownDeleted);

                        /*
                         * Current entry is a deleted entry. Replace it with
View Full Code Here

         * See [SR #10203] for a description of the bug that existed before
         * this change.
         */

        /* Create the first version of DupCountLN and log it. (Entry 1). */
        Locker locker = cursor.getLocker();
        int startingCount = locker.createdNode(existingLN.getNodeId()) ? 0 : 1;
        DupCountLN dupCountLN = new DupCountLN(startingCount);
        long firstDupCountLNLsn =
            dupCountLN.logProvisional(env, database.getId(),
              key, DbLsn.NULL_LSN);

        /* Make the duplicate root and DBIN. */
        duplicateRoot = new DIN(database,
                                existingKey,                   // idkey
                                maxDupTreeEntriesPerNode,
                                key,                           // dup key
                                new ChildReference
                                (dupCountLN, key, firstDupCountLNLsn),
                                2);                            // level
        duplicateRoot.latch();
        duplicateRoot.setIsRoot(true);

        duplicateBin = new DBIN(database,
                                existingKey,                   // idkey
                                maxDupTreeEntriesPerNode,
                                key,                           // dup key
                                1);                            // level
        duplicateBin.latch();

        /*
         * Attach the existing LN child to the duplicate BIN. Since this is a
         * newly created BIN, insertEntry will be successful.
         */
        ChildReference newExistingLNRef = new ChildReference
            (existingLN, existingKey, bin.getLsn(index), bin.getState(index));

        boolean insertOk = duplicateBin.insertEntry(newExistingLNRef);
        assert insertOk;

        try {

            /* Entry 2: DBIN. */
            long dbinLsn = duplicateBin.logProvisional
                (logManager, duplicateRoot);
            inMemoryINs.add(duplicateBin);
       
            /* Attach the duplicate BIN to the duplicate IN root. */
            duplicateRoot.setEntry(0, duplicateBin, duplicateBin.getKey(0),
                                   dbinLsn, duplicateBin.getState(0));

            /* Entry 3:  DIN */
            long dinLsn = duplicateRoot.log(logManager);
            inMemoryINs.add(duplicateRoot);

            /*
             * Now that the DIN is logged, we've created a duplicate tree that
             * holds the single, preexisting LN. We can safely create the non
             * provisional LNs that pertain to this insert -- the new LN and
             * the new DupCountLN.
             *
             * We request a lock while holding latches which is usually
             * forbidden, but safe in this case since we know it will be
             * immediately granted (we just created dupCountLN above).
             */
            LockResult lockResult = locker.lock
                (dupCountLN.getNodeId(), LockType.WRITE, database);
            lockResult.setAbortLsn(firstDupCountLNLsn, false);

            dupCountLN.setDupCount(2);
            long dupCountLsn = dupCountLN.log(env, database.getId(), key,
View Full Code Here

        this.db = db;
        this.key = copyEntry(key);
        logger = db.getEnvironment().getEnvironmentImpl().getLogger();

        /* Perform an auto-commit transaction to create the sequence. */
        Locker locker = null;
        Cursor cursor = null;
        OperationStatus status = OperationStatus.NOTFOUND;
        try {
            locker = LockerFactory.getWritableLocker
                (db.getEnvironment(), txn, db.isTransactional(),
                 false, autoCommitConfig);

            cursor = new Cursor(db, locker, null);

            if (useConfig.getAllowCreate()) {

                /* Get the persistent fields from the config. */
                rangeMin = useConfig.getRangeMin();
                rangeMax = useConfig.getRangeMax();
                increment = !useConfig.getDecrement();
                wrapAllowed = useConfig.getWrap();
                storedValue = useConfig.getInitialValue();

                /*
                 * To avoid dependence on SerializableIsolation, try
                 * putNoOverwrite first.  If it fails, then try to get an
                 * existing record.
                 */
                status = cursor.putNoOverwrite(key, makeData());

                if (status == OperationStatus.KEYEXIST) {
                    if (useConfig.getExclusiveCreate()) {
                        throw new DatabaseException
                            ("ExclusiveCreate=true and the sequence record " +
                             "already exists.");
                    }
                    if (!readData(cursor, null)) {
                        throw new DatabaseException
                            ("Sequence record removed during openSequence.");
                    }
                    status = OperationStatus.SUCCESS;
                }
            } else {

                /* Get an existing record. */
                if (!readData(cursor, null)) {
                    throw new DatabaseException
                        ("AllowCreate=false and the sequence record " +
                         "does not exist.");
                }
                status = OperationStatus.SUCCESS;
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
            if (locker != null) {
                locker.operationEnd(status);
            }
        }

        /*
         * cacheLast is initialized such that the cache will be considered
View Full Code Here

             * adjust.
             */
            int adjust = (delta > cacheSize) ? delta : cacheSize;

            /* Perform an auto-commit transaction to update the sequence. */
            Locker locker = null;
            Cursor cursor = null;
            OperationStatus status = OperationStatus.NOTFOUND;
            try {
                locker = LockerFactory.getWritableLocker
                    (db.getEnvironment(), txn, db.isTransactional(),
                     false, autoCommitConfig);

                cursor = new Cursor(db, locker, null);

                /* Get the existing record. */
                readDataRequired(cursor, LockMode.RMW);

                /* If we would have wrapped when not allowed, overflow. */
                if (overflow) {
                    throw new DatabaseException
                        ("Sequence overflow " + storedValue);
                }

                /*
                 * Handle wrapping.  The range size can be larger than a long
                 * can hold, so to avoid arithmetic overflow we use BigInteger
                 * arithmetic.  Since we are going to write, the BigInteger
                 * overhead is acceptable.
                 */
                BigInteger availBig;
                if (increment) {
                    /* Available amount: rangeMax - storedValue */
                    availBig = BigInteger.valueOf(rangeMax).
                        subtract(BigInteger.valueOf(storedValue));
                } else {
                    /* Available amount: storedValue - rangeMin */
                    availBig = BigInteger.valueOf(storedValue).
                        subtract(BigInteger.valueOf(rangeMin));
                }

                if (availBig.compareTo(BigInteger.valueOf(adjust)) < 0) {
                    /* If availBig < adjust then availBig fits in an int. */
                    int availInt = (int) availBig.longValue();
                    if (availInt < delta) {
                        if (wrapAllowed) {
                            /* Wrap to the opposite range end point. */
                            storedValue = increment ? rangeMin : rangeMax;
                            wrapped = true;
                        } else {
                            /* Signal an overflow next time. */
                            overflow = true;
                            adjust = 0;
                        }
                    } else {

                        /*
                         * If the delta fits in the cache available, don't wrap
                         * just to allocate the full cacheSize; instead,
                         * allocate as much as is available.
                         */
                        adjust = availInt;
                    }
                }

                /* Negate the adjustment for decrementing. */
                if (!increment) {
                    adjust = -adjust;
                }

                /* Set the stored value one past the cached amount. */
                storedValue += adjust;

                /* Write the new stored value. */
                cursor.put(key, makeData());
                status = OperationStatus.SUCCESS;
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
                if (locker != null) {
                    locker.operationEnd(status);
                }
            }

            /* The cache now contains the range: [cacheValue, storedValue) */
            cacheValue = storedValue - adjust;
View Full Code Here

                envImpl,
                dbConfig);
        CursorImpl idCursor = null;
        CursorImpl nameCursor = null;
        boolean operationOk = false;
        Locker autoTxn = null;
        try {
            /* Insert it into name -> id db. */
            nameCursor = new CursorImpl(nameDatabase, locker);
            nameCursor.setAllowEviction(allowEviction);
            LN nameLN = new NameLN(newId);
            nameCursor.putLN(databaseName.getBytes("UTF-8"),
           nameLN, false);

            /*
             * If this is a non-handle use, no need to record any handle locks.
             */
            if (databaseHandle != null) {
                locker.addToHandleMaps(new Long(nameLN.getNodeId()),
                                       databaseHandle);
            }

            /* Insert it into id -> name db, in auto commit mode. */
            autoTxn = new AutoTxn(envImpl, new TransactionConfig());
            idCursor = new CursorImpl(idDatabase, autoTxn);
            idCursor.setAllowEviction(allowEviction);
            idCursor.putLN(newId.getBytes(), new MapLN(newDb), false);
            operationOk = true;
  } catch (UnsupportedEncodingException UEE) {
      throw new DatabaseException(UEE);
        } finally {
            if (idCursor != null) {
                idCursor.close();
            }
            if (nameCursor != null) {
                nameCursor.close();
            }

            if (autoTxn != null) {
                autoTxn.operationEnd(operationOk);
            }
        }

        return newDb;
    }
View Full Code Here

       
        if (db.getId().equals(ID_DB_ID) ||
            db.getId().equals(NAME_DB_ID)) {
            envImpl.logMapTreeRoot();
        } else {
            Locker locker = new AutoTxn(envImpl, new TransactionConfig());
            CursorImpl cursor = new CursorImpl(idDatabase, locker);
            boolean operationOk = false;
            try {
                DatabaseEntry keyDbt =
        new DatabaseEntry(db.getId().getBytes());
    MapLN mapLN = null;

    /*
     * Retry indefinitely in the face of lock timeouts since the
     * lock on the MapLN is only supposed to be held for short
     * periods.
     */
    while (true) {
        try {
      boolean searchOk = (cursor.searchAndPosition
              (keyDbt, new DatabaseEntry(),
               SearchMode.SET, LockType.WRITE) &
              CursorImpl.FOUND) != 0;
      if (!searchOk) {
                            throw new DatabaseException(
                                "can't find database " + db.getId());
                        }
      mapLN = (MapLN)
          cursor.getCurrentLNAlreadyLatched(LockType.WRITE);
                        assert mapLN != null; /* Should be locked. */
        } catch (DeadlockException DE) {
      cursor.close();
      locker.operationEnd(false);
      locker = new AutoTxn(envImpl, new TransactionConfig());
      cursor = new CursorImpl(idDatabase, locker);
      continue;
        } finally {
      cursor.releaseBINs();
        }
        break;
    }

    RewriteMapLN writeMapLN = new RewriteMapLN(cursor);
    mapLN.getDatabase().getTree().withRootLatched(writeMapLN);

                operationOk = true;
            } finally {
                if (cursor != null) {
                    cursor.close();
                }

                locker.operationEnd(operationOk);
            }
        }
    }
View Full Code Here

                              long lockTimeout,
                              boolean allowEviction,
                              String dbNameIfAvailable)
        throws DatabaseException {

  Locker locker = new BasicLocker(envImpl);
  if (lockTimeout != -1) {
      locker.setLockTimeout(lockTimeout);
  }

        if (dbId.equals(idDatabase.getId())) {
            /* We're looking for the id database itself. */
            return idDatabase;
        } else if (dbId.equals(nameDatabase.getId())) {
            /* We're looking for the name database itself. */
            return nameDatabase;
        } else {
            /* Scan the tree for this db. */
            CursorImpl idCursor = null;
            DatabaseImpl foundDbImpl = null;

      /*
       * Retry in the face of lock timeouts.  Deadlocks may be due to
       * conflicts with modifyDbRoot.
       */
      while (true) {
                idCursor = new CursorImpl(idDatabase, locker);
                idCursor.setAllowEviction(allowEviction);
    try {
        DatabaseEntry keyDbt = new DatabaseEntry(dbId.getBytes());
        boolean found =
      (idCursor.searchAndPosition
       (keyDbt, new DatabaseEntry(), SearchMode.SET,
        LockType.READ) &
       CursorImpl.FOUND) != 0;
        if (found) {
      MapLN mapLN = (MapLN)
          idCursor.getCurrentLNAlreadyLatched(LockType.READ);
                        assert mapLN != null; /* Should be locked. */
                        foundDbImpl =  mapLN.getDatabase();
                    }
                    break;
    } catch (DeadlockException DE) {
        idCursor.close();
        locker.operationEnd(false);
        locker = new BasicLocker(envImpl);
        if (lockTimeout != -1) {
      locker.setLockTimeout(lockTimeout);
        }
        idCursor = new CursorImpl(idDatabase, locker);
                    idCursor.setAllowEviction(allowEviction);
        continue;
    } finally {
        idCursor.releaseBIN();
        idCursor.close();
        locker.operationEnd(true);
    }
      }

            /*
             * Set the debugging name in the databaseImpl, but only after
View Full Code Here

             * from each db verify invalidate the cursor.  Use dirty read
             * (LockMode.NONE) because locks on the MapLN should never be held
             * for long, as that will cause deadlocks with splits and
             * checkpointing.
       */
      Locker locker = null;
      CursorImpl cursor = null;
            LockType lockType = LockType.NONE;
      try {
    locker = new BasicLocker(envImpl);
    cursor = new CursorImpl(idDatabase, locker);
    if (cursor.positionFirstOrLast(true, null)) {
                    MapLN mapLN = (MapLN) cursor.
                        getCurrentLNAlreadyLatched(lockType);

                    DatabaseEntry keyDbt = new DatabaseEntry();
                    DatabaseEntry dataDbt = new DatabaseEntry();
                    while (true) {
                        if (mapLN != null && !mapLN.isDeleted()) {
                            DatabaseImpl dbImpl = mapLN.getDatabase();
                            boolean ok = dbImpl.verify(config,
                                                       dbImpl.getEmptyStats());
                            if (!ok) {
                                ret = false;
                            }
                        }
                        /* Go on to the next entry. */
                        OperationStatus status =
                            cursor.getNext(keyDbt, dataDbt, lockType,
                                           true,   // go forward
                                           false); // do need to latch
                        if (status != OperationStatus.SUCCESS) {
                            break;
                        }
                        mapLN = (MapLN) cursor.getCurrentLN(lockType);
                    }
                }
      } catch (DatabaseException e) {
                e.printStackTrace(out);
    ret = false;
      } finally {
    if (cursor != null) {
        cursor.releaseBINs();
        cursor.close();
    }
    if (locker != null) {
        locker.operationEnd();
    }
      }
  }

  return ret;
View Full Code Here

            return ID_DB_NAME;
        } else if (id.equals(NAME_DB_ID)) {
            return NAME_DB_NAME;
        }

        Locker locker = null;
        CursorImpl cursor = null;
        try {
            locker = new BasicLocker(envImpl);
            cursor = new CursorImpl(nameDatabase, locker);
            /* Use dirty reads (LockType.NONE). */
            DatabaseEntry keyDbt = new DatabaseEntry();
            DatabaseEntry dataDbt = new DatabaseEntry();
            String name = null;
            if (cursor.positionFirstOrLast(true, null)) {
                /* Fill in the key DatabaseEntry */
                OperationStatus status = cursor.getCurrentAlreadyLatched
                    (keyDbt, dataDbt, LockType.NONE, true);
                do {
                    if (status == OperationStatus.SUCCESS) {
                        NameLN nameLN = (NameLN) cursor.getCurrentLN
                            (LockType.NONE);
                        if (nameLN != null && nameLN.getId().equals(id)) {
                            name = new String(keyDbt.getData(), "UTF-8");
                            break;
                        }
                    }

                    /* Go on to the next entry. */
                    status = cursor.getNext(keyDbt, dataDbt, LockType.NONE,
                                            true,   // go forward
                                            false); // do need to latch
                } while (status == OperationStatus.SUCCESS);
            }
            return name;
  } catch (UnsupportedEncodingException UEE) {
      throw new DatabaseException(UEE);
        } finally {
            if (cursor != null) {
                cursor.releaseBINs();
                cursor.close();
            }
            if (locker != null) {
                locker.operationEnd();
            }
        }
    }
View Full Code Here

TOP

Related Classes of com.sleepycat.je.txn.Locker

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.