Package com.sleepycat.je.tree

Examples of com.sleepycat.je.tree.LN


                /* The entry is not known to be obsolete -- process it now. */
                if (isLN) {

                    final LNLogEntry lnEntry = reader.getLNLogEntry();
                    lnEntry.postFetchInit(db);
                    final LN targetLN = lnEntry.getLN();
                    final byte[] key = lnEntry.getKey();

                    lookAheadCache.add
                        (Long.valueOf(DbLsn.getFileOffset(logLsn)),
                         new LNInfo(targetLN, dbId, key));
View Full Code Here


        /* Get the first LN from the queue. */
        Long offset = lookAheadCache.nextOffset();
        LNInfo info = lookAheadCache.remove(offset);

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

        long logLsn = DbLsn.makeLsn
            (fileNum.longValue(), offset.longValue());

View Full Code Here

                                long treeLsn,
                                BIN bin,
                                int index)
        throws DatabaseException {

        LN lnFromLog = info.getLN();
        byte[] key = info.getKey();

        DatabaseImpl db = bin.getDatabase();
        boolean isTemporary = db.isTemporary();

        /* 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.

        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 if we will perform lazy migration
             * -- 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.
             *
             * 4. If the LSN in the tree is a null LSN, the log entry is
             * obsolete. A slot can only have a null LSN if the record has
             * never been written to disk in a deferred write database, and
             * in that case the log entry must be for a past, deleted version
             * of that record.
             */
            if (lnFromLog.isDeleted() &&
                (treeLsn == logLsn) &&
                fileLogVersion <= 2) {

                /*
                 * SR 14583: After JE 2.0, deleted LNs are never found in the
                 * tree, since we can assume they're obsolete and correctly
                 * marked as such in the obsolete offset tracking. JE 1.7.1 and
                 * earlier did not use the pending deleted bit, so deleted LNs
                 * may still be reachable through their BIN parents.
                 */
                obsolete = true;
                nLNsDeadThisRun++;
                bin.setPendingDeleted(index);
            } else if (treeLsn == DbLsn.NULL_LSN) {

                /*
                 * Case 4: The LN in the tree is a never-written LN for a
                 * deferred-write db, so the LN in the file is obsolete.
                 */
                obsolete = true;
            } else if (treeLsn != logLsn && isTemporary) {

                /*
                 * Temporary databases are always non-transactional.  If the
                 * tree and log LSNs are different then we know that the logLsn
                 * is obsolete.  Even if the LN is locked, the tree cannot be
                 * restored to the logLsn because no abort is possible without
                 * a transaction.  We should consider a similar optimization in
                 * the future for non-transactional durable databases.
                 */
                nLNsDeadThisRun++;
                obsolete = true;
            } else if ((treeLsn != logLsn || !cleaner.lazyMigration) &&
                       !isTemporary) {

                /*
                 * Get a lock on the LN if the treeLsn and logLsn are different
                 * to determine definitively whether the logLsn is obsolete.
                 * We must also get a lock if we will migrate the LN now
                 * (lazyMigration is false and isTemporary is false).
                 *
                 * We can hold the latch on the BIN since we always attempt to
                 * acquire a non-blocking read lock.
                 */
                locker = BasicLocker.createBasicLocker(env, false /*noWait*/);
                /* Don't allow this short-lived lock to be preempted/stolen. */
                locker.setPreemptable(false);
                LockResult lockRet = locker.nonBlockingLock
                    (treeLsn, LockType.READ, false /*jumpAheadOfWaiters*/, 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 if (treeLsn != logLsn) {
                    /* The LN is obsolete and can be purged. */
                    nLNsDeadThisRun++;
                    obsolete = true;
                }
            }

            /*
             * At this point either obsolete==true, lockDenied==true, or
             * treeLsn==logLsn.
             */
            if (!obsolete && !lockDenied) {
                assert treeLsn == logLsn;

                /*
                 * If lazyMigration is true, set the migrate flag and dirty
                 * the parent IN.  The evictor or checkpointer will migrate the
                 * LN later.  If lazyMigration is false, migrate the LN now.
                 *
                 * We have a lock on the LN if we are going to migrate it now,
                 * but not if we will set the migrate flag.
                 *
                 * When setting the migrate flag, also populate 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].
                 *
                 * For temporary databases, do not rely on the LN migration
                 * mechanism because temporary databases are not checkpointed
                 * or recovered.  Instead, dirty the LN to ensure it is
                 * flushed before its parent is written.  Because we do not
                 * attempt to lock temporary database LNs (see above) we know
                 * that if it is non-obsolete, the tree and log LSNs are equal.
                 * We will always restore the LN to the BIN slot here, and
                 * always log the dirty LN when logging the BIN.
                 *
                 * Also for temporary databases, make both the target LN and
                 * the BIN or IN parent dirty. Otherwise, when the BIN or IN is
                 * evicted in the future, it will be written to disk without
                 * flushing its dirty, migrated LNs.  [#18227]
                 */
                if (bin.getTarget(index) == null) {
                    lnFromLog.postFetchInit(db, logLsn);
                    /* Ensure keys are transactionally correct. [#15704] */
                    bin.updateNode(index, lnFromLog, key /*lnSlotKey*/);
                }

                if (isTemporary) {
                    ((LN) bin.getTarget(index)).setDirty();
                    bin.setDirty(true);
                } else if (cleaner.lazyMigration) {
                    bin.setMigrate(index, true);
                    bin.setDirty(true);
                } else {
                    LN targetLn = (LN) bin.getTarget(index);
                    assert targetLn != null;
                    long newLNLsn = targetLn.log
                        (env, db, bin.getKey(index), logLsn,
                         true /*backgroundIO*/,
                         Cleaner.getMigrationRepContext(targetLn));
                    bin.updateEntry(index, newLNLsn);
                    /* Evict LN if we populated it with the log LN. */
 
View Full Code Here

            if (!childType.isLNType()) {
                return;
            }

            LN ln = (LN) node;
            try {
                KeyAndData e = new KeyAndData(lnKey, ln);
                while (!queue.offer(e, offerTimeout,
                                    TimeUnit.MILLISECONDS)) {
                    checkShutdown();
View Full Code Here

             * do not count the size if the LN is dirty, since the logged LN is
             * not available. [#15365]
             */
            int size = 0;
            if (lnKey != null && node instanceof LN) {
                LN ln = (LN) node;
                size = ln.getLastLoggedSize();
            }

            localTracker.countObsoleteNodeInexact
                (childLsn, childType, size, db);
        }
View Full Code Here

                env.getEvictor().doCriticalEviction();

                /* The entry is not known to be obsolete -- process it now. */
                if (reader.isLN()) {

                    LN targetLN = reader.getLN();
                    DatabaseId dbId = reader.getDatabaseId();
                    DatabaseImpl db = dbMapTree.getDb(dbId, lockTimeout);

                    processLN
                        (targetLN, db, reader.getKey(),
View Full Code Here

                /*
                 * fetchTarget should never return null if the MIGRATE flag is
                 * set, since the LN is not yet cleaned.
                 */
                LN ln = (LN) bin.fetchTarget(index);
                assert ln != null;

                byte[] key = getLNMainKey(bin, index);
                byte[] dupKey = getLNDupKey(bin, index, ln);

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. */
            env.getEvictor().doCriticalEviction();

            processPendingLN
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;
        DIN parentDIN = null;      // for DupCountLNs

        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.
             */
      Node node = null;
      if (!bin.isEntryKnownDeleted(index)) {
                node = bin.getTarget(index);
                if (node == null) {
                    /* If fetchTarget returns null, a deleted LN was cleaned.*/
                    node = bin.fetchTarget(index);
                    clearTarget = node instanceof LN &&
                        !db.getId().equals(DbTree.ID_DB_ID);
                }
            }

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

            /* Determine whether this is a DupCountLN or a regular LN. */
            boolean lnIsDupCountLN = node.containsDuplicates();
      if (lnIsDupCountLN) {
    parentDIN = (DIN) node;
    parentDIN.latch(false);
                ChildReference dclRef = parentDIN.getDupCountLNRef();
                lsn = dclRef.getLsn();
                ln = (LN) dclRef.fetchTarget(db, parentDIN);
            } else {
                ln = (LN) node;
            }

            /*
             * 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);
                LockGrantType lock = locker.nonBlockingReadLock
                    (ln.getNodeId(), db);
                if (lock == 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()) {
                assert !lnIsDupCountLN;
                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.  Although redundant with
             * isFileCleaningInProgress, check toBeCleanedFiles first because
             * it is unsynchronized.
             */
            Long fileNum = new Long(DbLsn.getFileNumber(lsn));
            if (!toBeCleanedFiles.contains(fileNum) &&
                !fileSelector.isFileCleaningInProgress(fileNum)) {
                completed = true;
                if (wasCleaned) {
                    nLNsDead++;
                }
                return;
            }

            /* Migrate the LN. */
            byte[] key = getLNMainKey(bin, index);
            long newLNLsn = ln.log(env, db.getId(), key, lsn, locker);
      if (lnIsDupCountLN) {
                parentDIN.updateDupCountLNRef(newLNLsn);
            } else {
                bin.updateEntry(index, newLNLsn);
            }
View Full Code Here

  /*
   * Check the nodeid to see if we've already seen it or not.
   */
  if (entry instanceof LNLogEntry) {
      LNLogEntry lnEntry = (LNLogEntry) entry;
      LN ln = lnEntry.getLN();
      long nodeId = ln.getNodeId();
      boolean isDelDupLN =
    entryType.equals(LogEntryType.
         LOG_DEL_DUPLN_TRANSACTIONAL) ||
    entryType.equals(LogEntryType.LOG_DEL_DUPLN);

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.