/** * Evict a single LN if allowed. The amount of memory freed is returned and must be subtracted * from the memory budget by the caller. */ private long evictInternal(int index, Cleaner cleaner) throws DatabaseException { Node n = getTarget(index); if (n instanceof LN) { LN ln = (LN) n; /* * Don't evict MapLNs for open databases (LN.isEvictable) [#13415]. * And don't strip LNs that the cleaner will be migrating * (Cleaner.isEvictable). */ if (ln.isEvictable() && cleaner.isEvictable(this, index)) { boolean force = getDatabase().isDeferredWriteMode() && getLsn(index) == DbLsn.NULL_LSN; /* Log target if necessary. */ logDirtyLN(index, (LN) n, force); /* Clear target. */ setTarget(index, null); ln.releaseMemoryBudget(); return n.getMemorySizeIncludedByParent(); } } return 0; }
/** @see IN.logDirtyChildren(); */ @Override public void logDirtyChildren() throws DatabaseException { /* Look for targets that are dirty. */ EnvironmentImpl envImpl = getDatabase().getDbEnvironment(); for (int i = 0; i < getNEntries(); i++) { Node node = getTarget(i); if (node != null) { if (node instanceof LN) { logDirtyLN(i, (LN) node, false); } else { DIN din = (DIN) node; din.latch(CacheMode.UNCHANGED); try { if (din.getDirty()) { din.logDirtyChildren(); /* Logging the DIN will log the DupCountLN. */ long childLsn = din.log( envImpl.getLogManager(), false, // allow deltas true, // is provisional false, // proactive migration true, // backgroundIO this); // provisional parent updateEntry(i, childLsn); } } finally { din.releaseLatch(); } } } } }
private void logDirtyLNs(LogManager logManager) throws DatabaseException { boolean isDeferredWrite = getDatabase().isDeferredWriteMode(); for (int i = 0; i < getNEntries(); i++) { Node node = getTarget(i); if ((node != null) && (node instanceof LN)) { logDirtyLN(i, (LN) node, (getLsn(i) == DbLsn.NULL_LSN && isDeferredWrite)); } } }