/** * This reader looks at all nodes for the max node id and database id. It only returns * non-provisional INs and IN delete entries. */ protected boolean processEntry(ByteBuffer entryBuffer) throws DatabaseException { boolean useEntry = false; boolean entryLoaded = false; /* If this is a targetted entry, read the entire log entry. */ if (targetLogEntry != null) { targetLogEntry.readEntry(entryBuffer, currentEntrySize, currentEntryTypeVersion, true); DatabaseId dbId = getDatabaseId(); boolean isMapDb = dbId.equals(DbTree.ID_DB_ID); useEntry = (!mapDbOnly || isMapDb); entryLoaded = true; } /* Do a partial load during tracking if necessary. */ if (trackIds) { /* * Do partial load of db and txn id tracking entries if necessary. * Note that these entries do not overlap with targetLogEntry. * * XXX We're doing a full load for now, since LNLogEntry does not * read the db and txn id in a partial load, only the node id. */ LNLogEntry lnEntry = null; if (dbIdTrackingEntry != null) { /* This entry has a db id */ lnEntry = dbIdTrackingEntry; lnEntry.readEntry( entryBuffer, currentEntrySize, currentEntryTypeVersion, true /* full load */); entryLoaded = true; MapLN mapLN = (MapLN) lnEntry.getMainItem(); int dbId = mapLN.getDatabase().getId().getId(); if (dbId > maxDbId) { maxDbId = dbId; } } if (txnIdTrackingEntry != null) { /* This entry has a txn id */ if (lnEntry == null) { lnEntry = txnIdTrackingEntry; lnEntry.readEntry( entryBuffer, currentEntrySize, currentEntryTypeVersion, true /* full load */); entryLoaded = true; } long txnId = lnEntry.getTxnId().longValue(); if (txnId > maxTxnId) { maxTxnId = txnId; } } /* * Perform utilization counting under trackIds to prevent * double-counting. */ if (fsTrackingEntry != null) { /* Must do full load to get key from file summary LN. */ if (!entryLoaded) { nodeTrackingEntry.readEntry( entryBuffer, currentEntrySize, currentEntryTypeVersion, true /* full load */); entryLoaded = true; } /* * When a FileSummaryLN is encountered, reset the tracked * summary for that file to replay what happens when a * FileSummaryLN log entry is written. */ byte[] keyBytes = fsTrackingEntry.getKey(); FileSummaryLN fsln = (FileSummaryLN) fsTrackingEntry.getMainItem(); long fileNum = fsln.getFileNumber(keyBytes); TrackedFileSummary trackedLN = tracker.getTrackedFile(fileNum); if (trackedLN != null) { trackedLN.reset(); } /* Save the LSN of the FileSummaryLN for use by undo/redo. */ fileSummaryLsns.put(new Long(fileNum), new Long(getLastLsn())); /* * SR 10395: Do not cache the file summary in the * UtilizationProfile here, since it may be for a deleted log * file. */ } /* * Do partial load of nodeTrackingEntry (and inTrackingEntry) if not * already loaded. We only need the node id. */ if (nodeTrackingEntry != null) { if (!entryLoaded) { nodeTrackingEntry.readEntry( entryBuffer, currentEntrySize, currentEntryTypeVersion, false /* partial load */); entryLoaded = true; } /* Keep track of the largest node id seen. */ long nodeId = nodeTrackingEntry.getNodeId(); maxNodeId = (nodeId > maxNodeId) ? nodeId : maxNodeId; } if (inTrackingEntry != null) { assert entryLoaded : "All nodes should have been loaded"; /* * Count the obsolete LSN of the previous version, if available * and if not already counted. Use inexact counting for two * reasons: 1) we don't always have the full LSN because earlier * log versions only had the file number, and 2) we can't * guarantee obsoleteness for provisional INs. */ long oldLsn = inTrackingEntry.getObsoleteLsn(); if (oldLsn != DbLsn.NULL_LSN) { long newLsn = getLastLsn(); if (!isObsoleteLsnAlreadyCounted(oldLsn, newLsn)) { tracker.countObsoleteNodeInexact(oldLsn, fromLogType); } } /* * Count a provisional IN as obsolete if it follows * partialCkptStart. It cannot have been already counted, * because provisional INs are not normally counted as obsolete; * they are only considered obsolete when they are part of a * partial checkpoint. * * Depending on the exact point at which the checkpoint was * aborted, this technique is not always accurate; therefore * inexact counting must be used. */ if (isProvisional && partialCkptStart != DbLsn.NULL_LSN) { oldLsn = getLastLsn(); if (DbLsn.compareTo(partialCkptStart, oldLsn) < 0) { tracker.countObsoleteNodeInexact(oldLsn, fromLogType); } } } } /* Return true if this entry should be processed */ return useEntry; }
// changed to public public boolean isTargetEntry(byte entryTypeNum, byte entryTypeVersion) throws DatabaseException { lastEntryWasDelete = false; lastEntryWasDupDelete = false; targetLogEntry = null; dbIdTrackingEntry = null; txnIdTrackingEntry = null; nodeTrackingEntry = null; inTrackingEntry = null; fsTrackingEntry = null; isProvisional = LogEntryType.isProvisional(entryTypeVersion); /* Get the log entry type instance we need to read the entry. */ fromLogType = LogEntryType.findType(entryTypeNum, entryTypeVersion); LogEntry possibleTarget = (LogEntry) targetEntryMap.get(fromLogType); /* * If the entry is provisional, we won't be reading it in its entirety; * otherwise, we try to establish targetLogEntry. */ if (!isProvisional) { targetLogEntry = possibleTarget; } /* Was the log entry an IN deletion? */ if (LogEntryType.LOG_IN_DELETE_INFO.equals(fromLogType)) { lastEntryWasDelete = true; } if (LogEntryType.LOG_IN_DUPDELETE_INFO.equals(fromLogType)) { lastEntryWasDupDelete = true; } if (trackIds) { /* * Check if it's a db or txn id tracking entry. Note that these * entries do not overlap with targetLogEntry. */ if (!isProvisional) { dbIdTrackingEntry = (LNLogEntry) dbIdTrackingMap.get(fromLogType); txnIdTrackingEntry = (LNLogEntry) txnIdTrackingMap.get(fromLogType); } /* * Determine nodeTrackingEntry, inTrackingEntry, fsTrackingEntry. * Note that these entries do overlap with targetLogEntry. */ if (fromLogType.isNodeType()) { if (possibleTarget != null) { nodeTrackingEntry = (NodeLogEntry) possibleTarget; } else if (dbIdTrackingEntry != null) { nodeTrackingEntry = dbIdTrackingEntry; } else if (txnIdTrackingEntry != null) { nodeTrackingEntry = txnIdTrackingEntry; } else { nodeTrackingEntry = (NodeLogEntry) otherNodeTrackingMap.get(fromLogType); if (nodeTrackingEntry == null) { nodeTrackingEntry = (NodeLogEntry) fromLogType.getNewLogEntry(); otherNodeTrackingMap.put(fromLogType, nodeTrackingEntry); } } if (nodeTrackingEntry instanceof INLogEntry) { inTrackingEntry = (INLogEntry) nodeTrackingEntry; } if (LogEntryType.LOG_FILESUMMARYLN.equals(fromLogType)) { fsTrackingEntry = (LNLogEntry) nodeTrackingEntry; } } /* Count all entries as new. */ tracker.countNewLogEntry( getLastLsn(), fromLogType, LogManager.HEADER_BYTES + currentEntrySize); /* * Return true if this entry should be passed on to processEntry. If * we're tracking ids, return if this is a targeted entry or if it's * any kind of tracked entry or node. */ return (targetLogEntry != null) || (dbIdTrackingEntry != null) || (txnIdTrackingEntry != null) || (nodeTrackingEntry != null); } else { /* * Return true if this entry should be passed on to processEntry. If * we're not tracking ids, only return true if it's a targeted * entry. */ return (targetLogEntry != null); } }