Package com.sleepycat.je.tree

Examples of com.sleepycat.je.tree.LN


                                BIN bin,
                                int index,
                                DIN parentDIN)
        throws DatabaseException {

        LN ln = info.getLN();
        byte[] key = info.getKey();
        byte[] dupKey = info.getDupKey();

        DatabaseImpl db = bin.getDatabase();
        boolean isDupCountLN = parentDIN != null;

        /* Status variables are used to generate debug tracing info. */
        boolean obsolete = false// The LN is no longer in use.
        boolean migrated = false// The LN was in use and is migrated.
        boolean lockDenied = false;// The LN lock was denied.
        boolean completed = false; // This method completed.

        long nodeId = ln.getNodeId();
        BasicLocker locker = null;
        try {
            Tree tree = db.getTree();
            assert tree != null;

            /*
             * If the tree and log LSNs are equal, then we can be fairly
             * certain that the log entry is current; in that case, it is
             * wasteful to lock the LN here -- it is better to lock only once
             * during lazy migration.  But if the tree and log LSNs differ, it
             * is likely that another thread has updated or deleted the LN and
             * the log LSN is now obsolete; in this case we can avoid dirtying
             * the BIN by checking for obsoleteness here, which requires
             * locking.  The latter case can occur frequently if trackDetail is
             * false.
             *
             * 1. If the LSN in the tree and in the log are the same, we will
             * attempt to migrate it.
             *
             * 2. If the LSN in the tree is < the LSN in the log, the log entry
             * is obsolete, because this LN has been rolled back to a previous
             * version by a txn that aborted.
             *
             * 3. If the LSN in the tree is > the LSN in the log, the log entry
             * is obsolete, because the LN was advanced forward by some
             * now-committed txn.
             */
            if (treeLsn != logLsn) {

                /*
                 * Check to see whether the LN being migrated is locked
                 * elsewhere.  Do that by attempting to lock it.  We can hold
                 * the latch on the BIN (and DIN) since we always attempt to
                 * acquire a non-blocking read lock.  Holding the latch ensures
                 * that the INs won't change underneath us because of splits or
                 * eviction.
                 */
                locker = new BasicLocker(env);
                LockResult lockRet = locker.nonBlockingLock
                    (nodeId, LockType.READ, db);
                if (lockRet.getLockGrant() == LockGrantType.DENIED) {

                    /*
                     * LN is currently locked by another Locker, so we can't
                     * assume anything about the value of the LSN in the bin.
                     */
                    nLNsLockedThisRun++;
                    lockDenied = true;
                } else {
                    /* The LN is obsolete and can be purged. */
                    nLNsDeadThisRun++;
                    obsolete = true;
                }
            }

            if (!obsolete && !lockDenied) {

                /*
                 * Set the migrate flag and dirty the parent IN.  The evictor
                 * or checkpointer will migrate the LN later.
                 *
                 * Then set the target node so it does not have to be fetched
                 * when it is migrated, if the tree and log LSNs are equal and
                 * the target is not resident.  We must call postFetchInit to
                 * initialize MapLNs that have not been fully initialized yet
                 * [#13191].
                 */
                if (isDupCountLN) {
                    ChildReference dclRef = parentDIN.getDupCountLNRef();
                    dclRef.setMigrate(true);
                    parentDIN.setDirty(true);

                    if (treeLsn == logLsn && dclRef.getTarget() == null) {
                        ln.postFetchInit(db, logLsn);
                        parentDIN.updateDupCountLN(ln);
                    }
                } else {
                    bin.setMigrate(index, true);
                    bin.setDirty(true);

                    if (treeLsn == logLsn && bin.getTarget(index) == null) {
                        ln.postFetchInit(db, logLsn);
                        bin.updateEntry(index, ln);
                    }

                    /*
                     * If the generation is zero, we fetched this BIN just for
View Full Code Here


                             i < origBIN.getNEntries();
                             i++) {
                            if (!origBIN.isEntryKnownDeleted(i)) {
                                Node n = origBIN.fetchTarget(i);
                                if (n != null && !n.containsDuplicates()) {
                                    LN ln = (LN) n;
                                    /* See comment above about locking. */
                                    if (!ln.isDeleted()) {
                                        ret = true;
                                        break;
                                    }
                                }
                            } else {
                                /* Need to check the DupCountLN. */
                            }
                        }
                    }
                } else {
                    if (origCursor.getIndex() > 0) {

                        /*
                         * We were adjusted to something other than the first
                         * entry so some insertion happened.
                         */
                        for (int i = 0; i < origCursor.getIndex(); i++) {
                            if (!origBIN.isEntryKnownDeleted(i)) {
                                Node n = origBIN.fetchTarget(i);
                                if (n != null && !n.containsDuplicates()) {
                                    LN ln = (LN) n;
                                    /* See comment above about locking. */
                                    if (!ln.isDeleted()) {
                                        ret = true;
                                        break;
                                    }
                                } else {
                                    /* Need to check the DupCountLN. */
                                }
                            }
                        }
                    }
                }
            }
            origCursor.releaseBINs();
            return ret;
        }

        if (origDBIN != dupCursor.getDupBIN() &&
            origCursor.getIndex() == dupCursor.getIndex() &&
            getMode != GetMode.NEXT_NODUP &&
            getMode != GetMode.PREV_NODUP) {
            /* Same as above, only for the dupBIN. */
            origCursor.latchBINs();
            if (forward) {
                if (origDBIN.getNEntries() - 1 >
                    origCursor.getDupIndex()) {

                    /*
                     * We were adjusted to something other than the last entry
                     * so some insertion happened.
                     */
                    for (int i = origCursor.getDupIndex() + 1;
                         i < origDBIN.getNEntries();
                         i++) {
                        if (!origDBIN.isEntryKnownDeleted(i)) {
                            Node n = origDBIN.fetchTarget(i);
                            LN ln = (LN) n;
                            /* See comment above about locking. */
                            if (n != null && !ln.isDeleted()) {
                                ret = true;
                                break;
                            }
                        }
                    }
                }
            } else {
                if (origCursor.getDupIndex() > 0) {

                    /*
                     * We were adjusted to something other than the first entry
                     * so some insertion happened.
                     */
                    for (int i = 0; i < origCursor.getDupIndex(); i++) {
                        if (!origDBIN.isEntryKnownDeleted(i)) {
                            Node n = origDBIN.fetchTarget(i);
                            LN ln = (LN) n;
                            /* See comment above about locking. */
                            if (n != null && !ln.isDeleted()) {
                                ret = true;
                                break;
                            }
                        }
                    }
View Full Code Here

            releaseBINs();
            return OperationStatus.KEYEMPTY;
        }

        /* If fetchTarget returns null, a deleted LN was cleaned. */
        LN ln = (LN) targetBin.fetchTarget(targetIndex);
        if (ln == null) {
      releaseBINs();
            return OperationStatus.KEYEMPTY;
        }

        /* Get a write lock. */
  LockResult lockResult = lockLN(ln, LockType.WRITE);
  ln = lockResult.getLN();
           
        /* Check LN deleted status under the protection of a write lock. */
        if (ln == null) {
            releaseBINs();
            return OperationStatus.KEYEMPTY;
        }

        /* Lock the DupCountLN before logging any LNs. */
        LockResult dclLockResult = null;
        DIN dupRoot = null;
        try {
            isDup = (dupBin != null);
            if (isDup) {
                dupRoot = getLatchedDupRoot(true /*isDBINLatched*/);
                dclLockResult = lockDupCountLN(dupRoot, LockType.WRITE);

                /*
                 * Refresh the dupRoot variable because it may have changed
                 * during locking, but is sure to be resident and latched by
                 * lockDupCountLN.
                 */
                dupRoot = (DIN) bin.getTarget(index);
                /* Release BIN to increase concurrency. */
                releaseBIN();
            }

            /*
             * Between the release of the BIN latch and acquiring the write
             * lock any number of operations may have executed which would
             * result in a new abort LSN for this record. Therefore, wait until
             * now to get the abort LSN.
             */
            setTargetBin();
            long oldLsn = targetBin.getLsn(targetIndex);
            byte[] lnKey = targetBin.getKey(targetIndex);
            lockResult.setAbortLsn
                (oldLsn, targetBin.isEntryKnownDeleted(targetIndex));

            /* Log the LN. */
            long oldLNSize = ln.getMemorySizeIncludedByParent();
            long newLsn = ln.delete(database, lnKey, dupKey, oldLsn, locker);
            long newLNSize = ln.getMemorySizeIncludedByParent();

            /*
             * Now update the parent of the LN (be it BIN or DBIN) to correctly
             * reference the LN and adjust the memory sizing.  Be sure to do
             * this update of the LSN before updating the dup count LN. In case
View Full Code Here

      /*
       * Invoke the evictor to reduce memory consumption.
       */
      env.invokeEvictor();

      LN ln = reader.getLN();
      long logLsn = reader.getLastLsn();
      long abortLsn = reader.getAbortLsn();
      boolean abortKnownDeleted =
          reader.getAbortKnownDeleted();
      DatabaseId dbId = reader.getDatabaseId();
      DatabaseImpl db = dbMapTree.getDb(dbId);
                       
      /* Database may be null if it's been deleted. */
      if (db != null) {
          ln.postFetchInit(db, logLsn);
          try {
                                undo(detailedTraceLevel,
                                     db,
                                     location,
                                     ln,
View Full Code Here

        if (processThisLN) {

                        /* Invoke the evictor to reduce memory consumption. */
                        env.invokeEvictor();

                        LN ln = reader.getLN();
                        DatabaseId dbId = reader.getDatabaseId();
                        DatabaseImpl db = dbMapTree.getDb(dbId);
                        long logLsn = reader.getLastLsn();
                        long treeLsn = DbLsn.NULL_LSN;

                        /* Database may be null if it's been deleted. */
                        if (db != null) {
                            ln.postFetchInit(db, logLsn);

          if (preparedTxn != null) {
        preparedTxn.addLogInfo(logLsn);

        /*
         * We're reconstructing a prepared, but not
         * finished, transaction.  We know that there
         * was a write lock on this LN since it exists
         * in the log under this txnId.
         */
        preparedTxn.lock
                                    (ln.getNodeId(), LockType.WRITE,
                                     false /*noWait*/, db);
        preparedTxn.setPrepared(true);
          }

                            treeLsn = redo(db,
View Full Code Here

                /*
                 * Read the LN that's in this slot to check for deleted
                 * status.  No need to lock, since this is recovery.  If
                 * fetchTarget returns null, a deleted LN was cleaned.
                 */
                LN currentLN = (LN) parentBIN.fetchTarget(entryIndex);

                if (currentLN == null || currentLN.isDeleted()) {
                    canOverwrite = true;
                }

                /*
     * Evict the target again manually, to reduce memory
View Full Code Here

        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 = createLocker(envImpl);
View Full Code Here

                DatabaseId dbId = info.getDbId();
                DatabaseImpl db = dbMapTree.getDb(dbId, lockTimeout);

                byte[] key = info.getKey();
                byte[] dupKey = info.getDupKey();
                LN ln = info.getLN();

                /* Evict before processing each entry. */
                if (DO_CRITICAL_EVICTION) {
                    env.getEvictor().doCriticalEviction();
                }
View Full Code Here

        /*
         * If wasCleaned is false we don't count statistics unless we migrate
         * the LN.  This avoids double counting.
         */
        BasicLocker locker = null;
        LN ln = null;

        try {

            /*
             * Fetch the node, if necessary.  If it was not resident and it is
             * an evictable LN, we will clear it after we migrate it.
             */
      if (!bin.isEntryKnownDeleted(index)) {
                ln = (LN) bin.getTarget(index);
                if (ln == null) {
                    /* If fetchTarget returns null, a deleted LN was cleaned.*/
                    ln = (LN) bin.fetchTarget(index);
                    clearTarget = !db.getId().equals(DbTree.ID_DB_ID);
                }
            }

      /* Don't migrate knownDeleted or deleted cleaned LNs.  */
            if (ln == null) {
                if (wasCleaned) {
                    nLNsDead++;
                }
                obsolete = true;
                completed = true;
                return;
      }

            /*
             * Get a non-blocking read lock on the LN.  A pending node is
             * already locked, but that node ID may be different than the
             * current LN's node if a slot is reused.  We must lock the current
             * node to guard against aborts.
             */
            if (lockedPendingNodeId != ln.getNodeId()) {
                locker = new BasicLocker(env);
                LockResult lockRet = locker.nonBlockingLock
                    (ln.getNodeId(), LockType.READ, db);
                if (lockRet.getLockGrant() == LockGrantType.DENIED) {

                    /*
                     * LN is currently locked by another Locker, so we can't
                     * assume anything about the value of the LSN in the bin.
                     */
                    if (wasCleaned) {
                        nLNsLocked++;
                    }
                    lockDenied = true;
                    completed = true;
                    return;
                }
            }

      /* Don't migrate deleted LNs.  */
            if (ln.isDeleted()) {
                bin.setKnownDeletedLeaveTarget(index);
                if (wasCleaned) {
                    nLNsDead++;
                }
                obsolete = true;
                completed = true;
                return;
            }

            /*
             * Once we have a lock, check whether the current LSN needs to be
             * migrated.  There is no need to migrate it if the LSN no longer
             * qualifies for cleaning.  The LSN could have been changed by an
             * update or delete after we set the MIGRATE flag.
             *
             * Note that we do not perform this optimization if the MIGRATE
             * flag is not set, i.e, for clustering and proactive migration of
             * resident LNs.  For these cases, we checked the conditions for
             * migration immediately before calling this method.  Although the
             * condition could change after locking, the window is small and
             * a second check is not worthwhile.
             */
            if (bin.getMigrate(index)) {
                Long fileNum = new Long(DbLsn.getFileNumber(lsn));
                if (!fileSelector.isFileCleaningInProgress(fileNum)) {
                    obsolete = true;
                    completed = true;
                    if (wasCleaned) {
                        nLNsDead++;
                    }
                    return;
                }
            }

            /* Migrate the LN. */
            byte[] key = getLNMainKey(bin, index);
            long newLNLsn = ln.log(env, db.getId(), key, lsn, locker);
            bin.updateEntry(index, newLNLsn);
            nLNsMigrated++;
            migrated = true;
            completed = true;
            return;
View Full Code Here

        /*
         * If wasCleaned is false we don't count statistics unless we migrate
         * the LN.  This avoids double counting.
         */
        BasicLocker locker = null;
        LN ln = null;

        try {

            /*
             * Fetch the node, if necessary.  If it was not resident and it is
             * an evictable LN, we will clear it after we migrate it.
             */
      ln = (LN) dclRef.getTarget();
            if (ln == null) {
                ln = (LN) dclRef.fetchTarget(db, parentDIN);
                assert ln != null;
                clearTarget = !db.getId().equals(DbTree.ID_DB_ID);
            }

            /*
             * Get a non-blocking read lock on the LN, if this is not an
             * already locked pending node.
             */
            if (lockedPendingNodeId != ln.getNodeId()) {
                locker = new BasicLocker(env);
                LockResult lockRet = locker.nonBlockingLock
                    (ln.getNodeId(), LockType.READ, db);
                if (lockRet.getLockGrant() == LockGrantType.DENIED) {

                    /*
                     * LN is currently locked by another Locker, so we can't
                     * assume anything about the value of the LSN in the bin.
                     */
                    if (wasCleaned) {
                        nLNsLocked++;
                    }
                    lockDenied = true;
                    completed = true;
                    return;
                }
            }

            /*
             * Once we have a lock, check whether the current LSN needs to be
             * migrated.  There is no need to migrate it if the LSN no longer
             * qualifies for cleaning.
             */
            Long fileNum = new Long(DbLsn.getFileNumber(lsn));
            if (!fileSelector.isFileCleaningInProgress(fileNum)) {
                obsolete = true;
                completed = true;
                if (wasCleaned) {
                    nLNsDead++;
                }
                return;
            }

            /* Migrate the LN. */
            byte[] key = parentDIN.getDupKey();
            long newLNLsn = ln.log(env, db.getId(), key, lsn, locker);
            parentDIN.updateDupCountLNRef(newLNLsn);
            nLNsMigrated++;
            migrated = true;
            completed = true;
            return;
View Full Code Here

TOP

Related Classes of com.sleepycat.je.tree.LN

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.