Package com.sleepycat.je.tree

Examples of com.sleepycat.je.tree.IN


     * Returns the root IN, latched shared.  Allows subclasses to override
     * getResidentRootIN and/or getRootIN to modify behavior.
     * getResidentRootIN is called first,
     */
    protected IN getOrFetchRootIN(DatabaseImpl dbImpl, long rootLsn) {
        final IN root = getResidentRootIN(dbImpl);
        if (root != null) {
            return root;
        }
        if (rootLsn == DbLsn.NULL_LSN) {
            return null;
View Full Code Here


     * The default behavior fetches the rootIN from the log and latches it
     * shared. Classes extending this may fetch (and latch) the root from the
     * tree.
     */
    protected IN getRootIN(DatabaseImpl dbImpl, long rootLsn) {
        final IN root = (IN)
            envImpl.getLogManager().getEntryHandleFileNotFound(rootLsn);
        if (root == null) {
            return null;
        }
        root.latchShared(CacheMode.DEFAULT);
        root.setDatabase(dbImpl);
        return root;
    }
View Full Code Here

        throws FileNotFoundException, DatabaseException {

        INEntry inEntry = lsnINMap.remove(lsn);
        assert (inEntry != null) : DbLsn.getNoFormatString(lsn);
        incInternalMemoryUsage(- inEntry.getMemorySize());
        IN in = inEntry.in;
        boolean isLatchedAlready = in.isLatchOwnerForWrite();
        if (!isLatchedAlready) {
            in.latch();
        }

        try {
            int index = inEntry.index;

            /* Preload latches the root, so why do these double checks? */
            if (in.isEntryKnownDeleted(index)) {
                return null;
            }
            if (inEntry.getDelta() == null) {
                if (in.getLsn(index) != lsn) {
                    return null;
                }
            } else {
                if (in.getLsn(index) != inEntry.getDeltaLsn()) {
                    return null;
                }
            }

            /* Fetch log entry. */
            LogEntry entry = envImpl.getLogManager().getLogEntry(lsn);

            /*
             * For a BINDeltaLogEntry, queue fetching of the full BIN and
             * combine the full BIN with the delta when it is processed later.
             * See call to reconstituteBIN below.
             */
            if (entry instanceof BINDeltaLogEntry) {
                BINDelta delta = (BINDelta) entry.getMainItem();
                long fullLsn = delta.getLastFullLsn();
                pendingLSNs.add(fullLsn);
                addToLsnINMap(fullLsn, in, index, delta, lsn);
                return null;
            }

            /* For an LNLogEntry, call postFetchInit and get the lnKey. */
            DatabaseImpl dbImpl = in.getDatabase();
            byte[] lnKey = null;
            if (entry instanceof LNLogEntry) {
                LNLogEntry lnEntry = (LNLogEntry) entry;
                lnEntry.postFetchInit(dbImpl);
                lnKey = lnEntry.getKey();
                lnKeyEntry.setData(lnKey);
            }

            /* Get the Node from the LogEntry. */
            Node ret = (Node) entry.getResolvedItem(dbImpl);

            /*
             * For an IN Node, set the database so it will be passed down to
             * nested fetches.
             */
            long lastLoggedLsn = lsn;
            if (ret instanceof IN) {
                IN retIn = (IN) ret;
                retIn.setDatabase(dbImpl);
            }

            /*
             * If there is a delta, then this is a BIN to which the delta must
             * be applied.  The delta LSN is the last logged LSN.
View Full Code Here

             *
             * If no possible parent is found, the compressor may have deleted
             * this item before we got to processing it.
             */
            if (result.parent != null) {
                IN parent = result.parent;
                int parentLevel = parent.getLevel();
                boolean mustLogParent = false;

                /*
                 * If bottomLevelTarget is true, the parent IN contains bottom
                 * level BINs.  The masking is used to normalize the level for
                 * ordinary DBs and the mapping tree DB.
                 */
                boolean bottomLevelTarget =
                    ((parentLevel & IN.LEVEL_MASK) == 2);

                /*
                 * INs at the max flush level are always non-provisional and
                 * INs at the bottom level (when this is not also the max flush
                 * level) are always provisional.  In between INs are
                 * provisional BEFORE_CKPT_END (see Provisional).
                 */
                Provisional provisional;
                if (currentLevel >= maxFlushLevel) {
                    provisional = Provisional.NO;
                } else if (bottomLevelTarget) {
                    provisional = Provisional.YES;
                } else {
                    provisional = Provisional.BEFORE_CKPT_END;
                }

                /*
                 * Log a sub-tree when the target is at the bottom level and
                 * this is not a recursive call to flushIN during sub-tree
                 * logging.
                 */
                boolean logSubtree = bottomLevelTarget && allowLogSubtree;

                /*
                 * Log sub-tree siblings with the latch held when highPriority
                 * is configured and this is not a DW DB.  For a DW DB, dirty
                 * LNs are logged for each BIN.  If we were to log a DW
                 * sub-tree with the parent latch held, the amount of logging
                 * may cause the latch to be held for too long a period.
                 */
                boolean logSiblingsWithParentLatchHeld =
                    logSubtree &&
                    highPriority &&
                    !db.isDurableDeferredWrite();

                /*
                 * If we log siblings with the parent latch held, we log the
                 * target along with other siblings so we can perform a single
                 * multi-log call for all siblings.
                 */
                boolean logTargetWithOtherSiblings = false;

                /*
                 * Map of node ID to parent index for each sibling to log.  We
                 * must process the siblings in node ID order during multi-log,
                 * so that latching order is deterministic and only in one
                 * direction.
                 */
                SortedMap<Long, Integer> siblingsToLog = null;

                try {
                    if (result.exactParentFound) {

                        /*
                         * If the child has already been evicted, don't
                         * refetch it.
                         */
                        IN renewedTarget = (IN) parent.getTarget(result.index);

                        if (renewedTarget == null) {
                            /* nAlreadyEvictedThisRun++;  -- for future */
                            mustLogParent |= true;
                        } else {
                            if (logSiblingsWithParentLatchHeld) {
                                logTargetWithOtherSiblings = true;
                            } else {
                                mustLogParent |= logSiblings
                                    (envImpl, dirtyMap, parent,
                                     Collections.singleton(result.index),
                                     allowDeltas, highPriority, provisional,
                                     fstats);
                            }
                        }
                    } else {
                        /* result.exactParentFound was false. */

                        /* Do not flush children of the inexact parent. */
                        logSubtree = false;

                        if (result.childNotResident) {

                            /*
                             * But it was because the child wasn't resident.
                             * To be on the safe side, we'll put the parent
                             * into the dirty set to be logged when that level
                             * is processed.
                             *
                             * Only do this if the parent we found is at a
                             * higher level than the child.  This ensures that
                             * the non-exact search does not find a sibling
                             * rather than a parent. [#11555]
                             */
                            if (parentLevel > currentLevel) {
                                mustLogParent |= true;
                            }
                            /* nAlreadyEvictedThisRun++; -- for future. */
                        }
                    }

                    if (logSubtree) {

                        /*
                         * Create a map of node ID to parent index for each
                         * sibling we intend to log.  Note that the dirty map
                         * does not contain targetRef (the sibling we're
                         * processing) because it was removed before calling
                         * this method, but it is added to the map below.
                         *
                         * A TreeMap (sorted map) is used so that siblings are
                         * latched in node ID order.  A deterministic order is
                         * needed to avoid deadlocks, if siblings are latched
                         * in multiple threads in the future.
                         */
                        siblingsToLog = new TreeMap<Long, Integer>();
                        for (int index = 0;
                             index < parent.getNEntries();
                             index += 1) {
                            IN child = (IN) parent.getTarget(index);
                            if (child != null) {
                                Long childId = child.getNodeId();
                                if ((logTargetWithOtherSiblings &&
                                     targetRef.nodeId ==
                                     childId.longValue()) ||
                                    dirtyMap.containsNode
                                        (child.getLevel(), childId)) {
                                    siblingsToLog.put(childId, index);
                                }
                            }
                        }

                        if (logSiblingsWithParentLatchHeld) {
                            if (MULTI_LOG) {
                                mustLogParent |= logSiblings
                                    (envImpl, dirtyMap, parent,
                                     siblingsToLog.values(), allowDeltas,
                                     highPriority, provisional, fstats);
                            } else {
                                for (int index : siblingsToLog.values()) {
                                    IN child = (IN) parent.getTarget(index);
                                    CheckpointReference childRef =
                                        (targetRef.nodeId ==
                                         child.getNodeId()) ? targetRef :
                                        dirtyMap.removeNode(child.getLevel(),
                                                            child.getNodeId());
                                    assert childRef != null;
                                    mustLogParent |= logSiblings
                                        (envImpl, dirtyMap, parent,
                                         Collections.singleton(index),
                                         allowDeltas, highPriority,
View Full Code Here

        boolean mustLogParent = false;
        List<INLogItem> itemList = new ArrayList<INLogItem>();

        try {
            for (int index : indicesToLog) {
                IN child = (IN) parent.getTarget(index);

                /* Remove it from dirty map if it is present. */
                dirtyMap.removeNode(child.getLevel(), child.getNodeId());

                /*
                 * Latch and add item with valid parentIndex, so we will
                 * release the latch in the finally statement.
                 */
                child.latch(CacheMode.UNCHANGED);
                INLogItem item = new INLogItem();
                item.parentIndex = index;
                itemList.add(item);

                if (child.getDirty()) {

                    if (child.getDatabase().isDurableDeferredWrite()) {

                        /*
                         * Find dirty descendants to avoid logging nodes with
                         * never-logged children. See [#13936] and
                         * IN.logDirtyChildren for description of the case.
                         *
                         * Note that we must log both dirty and never-logged
                         * descendants to be sure to have a consistent view of
                         * the split. If we didn't, we could end up with the
                         * post-split version of a new sibling and the
                         * pre-split version of an split sibling in the log,
                         * which could result in a recovery where descendants
                         * are incorrectly duplicated, because they are in both
                         * the pre-split split sibling, and the post-split
                         * version of the new sibling.
                         */
                        child.logDirtyChildren();
                    }

                    /* Set default params. */
                    item.provisional = provisional;
                    item.repContext = ReplicationContext.NO_REPLICATE;
                    item.parent = parent;

                    /*
                     * Allow child to perform "before log" processing.  Note
                     * that child decides whether to log a delta. Only BINs
                     * that fall into the required percentages and have not
                     * been cleaned will be logged with a delta.
                     */
                    child.beforeLog(logManager, item, context);
                } else {
                    /* Do not process if not dirty.  Unlatch now. */
                    itemList.remove(itemList.size() - 1);
                    child.releaseLatch();

                    /* Log parent if child has already been flushed. */
                    mustLogParent = true;
                }
            }

            /*
             * Log all siblings at once.  Limitations of Java generics prevent
             * conversion from List<INLogItem> to List<LogItem> even by
             * casting, so we convert to an array instead.
             */
            LogItem[] itemArray = new LogItem[itemList.size()];
            logManager.multiLog(itemList.toArray(itemArray), context);

            for (INLogItem item : itemList) {
                IN child = (IN) parent.getTarget(item.parentIndex);

                /* Allow child to perform "after log" processing. */
                child.afterLog(logManager, item, context);

                /* Update the parent slot's LSN. */
                assert (item.newLsn != DbLsn.NULL_LSN);
                parent.updateEntry(item.parentIndex, item.newLsn);

                /* Increment stats. */
                if (item.isDelta) {
                    fstats.nDeltaINFlushThisRun++;
                    fstats.nDeltaINFlush++;
                } else {
                    fstats.nFullINFlushThisRun++;
                    fstats.nFullINFlush++;
                    if (child.isBIN()) {
                        fstats.nFullBINFlush++;
                        fstats.nFullBINFlushThisRun++;
                    }
                }

                /* Parent slot has changed, must log parent. */
                mustLogParent = true;
            }
            return mustLogParent;
        } finally {
            for (INLogItem item : itemList) {
                IN child = (IN) parent.getTarget(item.parentIndex);
                child.releaseLatch();
            }
        }
    }
View Full Code Here

            throws DatabaseException {

            if (root == null) {
                return null;
            }
            IN rootIN = (IN) root.fetchTarget(db, null);
            rootIN.latch(CacheMode.UNCHANGED);
            try {
                if (rootIN.getNodeId() == targetNodeId) {

                    /*
                     * Find dirty descendants to avoid logging nodes with
                     * never-logged children. See [#13936]
                     */
                    if (rootIN.getDatabase().isDurableDeferredWrite()) {
                        rootIN.logDirtyChildren();
                    }

                    /*
                     * stillRoot handles the situation where the root was split
                     * after it was placed in the checkpointer's dirty set.
                     */
                    stillRoot = true;
                    if (rootIN.getDirty()) {
                        long newLsn = rootIN.log(logManager);
                        root.setLsn(newLsn);
                        flushed = true;
                    }
                }
            } finally {
                rootIN.releaseLatch();
            }
            return null;
        }
View Full Code Here

     */
    private void convertDin(final DIN din, final byte[] binKey) {
        din.latch();
        try {
            for (int i = 0; i < din.getNEntries(); i += 1) {
                final IN child = (IN) din.fetchTargetWithExclusiveLatch(i);
                if (child instanceof DBIN) {
                    final DBIN dbin = (DBIN) child;
                    dbin.latch();
                    try {
                        for (int j = 0; j < dbin.getNEntries(); j += 1) {
View Full Code Here

             * didn't properly propagate the logging of the rootIN up to the
             * root ChildReference.  We still do this for compatibility with
             * old log versions but may be able to remove it in the future.
             */
            if (DbLsn.compareTo(root.getLsn(), logLsn) <= 0) {
                IN rootIN = (IN) root.fetchTarget(db, null);
                rootIN.latch(Cleaner.UPDATE_GENERATION);
                return rootIN;
            } else {
                return null;
            }
        }
View Full Code Here

         * faulting-in-a-node path, because we don't want to put the IN on the
         * in memory list, and we don't want to search the db map tree, so we
         * have a IN.postRecoveryInit.
         */
        final long logLsn = reader.getLastLsn();
        final IN in = reader.getIN(db);
        in.postRecoveryInit(db, logLsn);
        in.latch();

        /*
         * Track the levels, in case we need an extra splits vs ckpt
         * reconcilliation.
         */
        if (recorder != null) {
            recorder.record(db.getId(), in.getLevel());
        }
        replaceOrInsert(db, in, logLsn, requireExactMatch);
    }
View Full Code Here

                        cleaner.processPending();
                    }

                } else if (isIN) {

                    final IN targetIN = reader.getIN(db);
                    targetIN.setDatabase(db);

                    processIN(targetIN, db, logLsn);

                } else if (isBINDelta) {
View Full Code Here

TOP

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

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.