package com.sleepycat.je.cleaner; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import com.sleepycat.je.Database; import com.sleepycat.je.DatabaseException; import com.sleepycat.je.DbInternal; import com.sleepycat.je.dbi.DatabaseImpl; import com.sleepycat.je.dbi.SortedLSNTreeWalker; import com.sleepycat.je.dbi.SortedLSNTreeWalker.TreeNodeProcessor; import com.sleepycat.je.log.LogEntryType; import com.sleepycat.je.utilint.DbLsn; import de.ovgu.cide.jakutil.*; /** * Verify cleaner data structures */ public class VerifyUtils { private static final boolean DEBUG=false; /** * Compare the lsns referenced by a given Database to the lsns held * in the utilization profile. Assumes that the database and * environment is quiescent, and that there is no current cleaner * activity. */ public static void checkLsns( Database db) throws DatabaseException { DatabaseImpl dbImpl=DbInternal.dbGetDatabaseImpl(db); GatherLSNs gatherLsns=new GatherLSNs(); long rootLsn=dbImpl.getTree().getRootLsn(); SortedLSNTreeWalker walker=new SortedLSNTreeWalker(dbImpl,false,false,rootLsn,gatherLsns); walker.walk(); Set lsnsInTree=gatherLsns.getLsns(); lsnsInTree.add(new Long(rootLsn)); Iterator iter=lsnsInTree.iterator(); Set fileNums=new HashSet(); while (iter.hasNext()) { long lsn=((Long)iter.next()).longValue(); fileNums.add(new Long(DbLsn.getFileNumber(lsn))); } iter=fileNums.iterator(); Set obsoleteLsns=new HashSet(); UtilizationProfile profile=dbImpl.getDbEnvironment().getUtilizationProfile(); while (iter.hasNext()) { Long fileNum=(Long)iter.next(); PackedOffsets obsoleteOffsets=new PackedOffsets(); TrackedFileSummary tfs=profile.getObsoleteDetail(fileNum,obsoleteOffsets,false); PackedOffsets.Iterator obsoleteIter=obsoleteOffsets.iterator(); while (obsoleteIter.hasNext()) { long offset=obsoleteIter.next(); Long oneLsn=new Long(DbLsn.makeLsn(fileNum.longValue(),offset)); obsoleteLsns.add(oneLsn); if (DEBUG) { System.out.println("Adding 0x" + Long.toHexString(oneLsn.longValue())); } } } boolean error=false; iter=lsnsInTree.iterator(); while (iter.hasNext()) { Long lsn=(Long)iter.next(); if (obsoleteLsns.contains(lsn)) { System.err.println("Obsolete lsns contains valid lsn " + DbLsn.getNoFormatString(lsn.longValue())); error=true; } } iter=obsoleteLsns.iterator(); while (iter.hasNext()) { Long lsn=(Long)iter.next(); if (lsnsInTree.contains(lsn)) { System.err.println("Tree contains obsolete lsn " + DbLsn.getNoFormatString(lsn.longValue())); error=true; } } if (error) { throw new DatabaseException("Lsn mismatch"); } } private static class GatherLSNs implements TreeNodeProcessor { private Set lsns=new HashSet(); public void processLSN( long childLSN, LogEntryType childType){ lsns.add(new Long(childLSN)); } public Set getLsns(){ return lsns; } } }