in mavibot/src/main/java/org/apache/directory/mavibot/btree/PageReclaimer.java [64:184]
/* no qualifier */ void reclaim()
{
//System.out.println( "reclaiming pages" );
try
{
if ( running )
{
return;
}
running = true;
Set<String> managed = rm.getManagedTrees();
for ( String name : managed )
{
PersistedBTree tree = ( PersistedBTree ) rm.getManagedTree( name );
long latestRev = tree.getRevision();
Set<Long> inUseRevisions = new TreeSet<Long>();
// the tree might have been removed
if ( tree != null )
{
Iterator<ReadTransaction> txnItr = tree.getReadTransactions().iterator();
while ( txnItr.hasNext() )
{
inUseRevisions.add( txnItr.next().getRevision() );
}
}
List<RevisionOffset> copiedRevisions = getRevisions( name );
// the revision last removed from copiedPage BTree
long lastRemovedRev = -1;
List<Long> freeList = new ArrayList<Long>();
for ( RevisionOffset ro : copiedRevisions )
{
long rv = ro.getRevision();
if ( inUseRevisions.contains( rv ) )
{
//System.out.println( "Revision " + rv + " of BTree " + name + " is in use, not reclaiming pages" );
break;
}
long[] offsets = ro.getOffsets();
//System.out.println( "Reclaiming " + Arrays.toString( offsets ) + "( " + offsets.length + " ) pages of the revision " + rv + " of BTree " + name );
for( long l : offsets )
{
freeList.add( l );
}
RevisionName key = new RevisionName( rv, name );
//System.out.println( "delete cpb key " + key );
rm.copiedPageBtree.delete( key );
lastRemovedRev = rv;
}
// no new txn is needed for the operations on BoB
// and also no need to traverse BoB if the tree is a sub-btree
if ( ( lastRemovedRev != -1 ) && !tree.isAllowDuplicates() )
{
// we SHOULD NOT delete the latest revision from BoB
NameRevision nr = new NameRevision( name, latestRev );
TupleCursor<NameRevision, Long> cursor = rm.btreeOfBtrees.browseFrom( nr );
List<Long> btreeHeaderOffsets = new ArrayList<Long>();
while ( cursor.hasPrev() )
{
Tuple<NameRevision, Long> t = cursor.prev();
//System.out.println( "deleting BoB rev " + t.getKey() + " latest rev " + latestRev );
rm.btreeOfBtrees.delete( t.getKey() );
btreeHeaderOffsets.add( t.value );
}
cursor.close();
for( Long l : btreeHeaderOffsets )
{
// the offset may have already been present while
// clearing CPB so skip it here, otherwise it will result in OOM
// due to the attempt to free and already freed page
if(freeList.contains( l ))
{
//System.out.println( "bob duplicate offset " + l );
continue;
}
freeList.add( l );
}
}
for( Long offset : freeList )
{
PageIO[] pageIos = rm.readPageIOs( offset, -1L );
for ( PageIO pageIo : pageIos )
{
rm.free( pageIo );
}
}
}
running = false;
}
catch ( Exception e )
{
running = false;
rm.rollback();
LOG.warn( "Errors while reclaiming", e );
throw new RuntimeException( e );
}
}