o run reclaimer in a transaction
authorKiran Ayyagari <kayyagari@apache.org>
Tue, 12 May 2015 06:20:00 +0000 (06:20 +0000)
committerKiran Ayyagari <kayyagari@apache.org>
Tue, 12 May 2015 06:20:00 +0000 (06:20 +0000)
o added a test which demonstrates a failed page reclaiming operation when not run inside a transaction
o removed useless imports
o added a flag to skip running reclaimer when a reclaiming operation is in progress

mavibot/src/main/java/org/apache/directory/mavibot/btree/SpaceReclaimer.java
mavibot/src/test/java/org/apache/directory/mavibot/btree/SpaceReclaimerTest.java

index e119ecc..43e845e 100644 (file)
 package org.apache.directory.mavibot.btree;
 
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -50,11 +40,12 @@ public class SpaceReclaimer
     /** the record manager */
     private RecordManager rm;
 
-    private static String COPIED_PAGE_MAP_DATA_FILE = "cpm.db";
-
     /** The LoggerFactory used by this class */
     protected static final Logger LOG = LoggerFactory.getLogger( SpaceReclaimer.class );
 
+    /** a flag to detect the running state */
+    private boolean running = false;
+    
     /**
      * Creates a new instance of SpaceReclaimer.
      *
@@ -74,6 +65,15 @@ public class SpaceReclaimer
         //System.out.println( "reclaiming pages" );
         try
         {
+            if ( running )
+            {
+                return;
+            }
+            
+            running = true;
+            
+            rm.beginTransaction();
+            
             Set<String> managed = rm.getManagedTrees();
 
             for ( String name : managed )
@@ -81,7 +81,7 @@ public class SpaceReclaimer
                 PersistedBTree tree = ( PersistedBTree ) rm.getManagedTree( name );
 
                 Set<Long> inUseRevisions = new TreeSet<Long>();
-
+                
                 // the tree might have been removed
                 if ( tree != null )
                 {
@@ -110,12 +110,18 @@ public class SpaceReclaimer
                     rm.free( offsets );
 
                     RevisionName key = new RevisionName( rv, name );
+                    
                     rm.copiedPageBtree.delete( key );
                 }
             }
+
+            running = false;
+            rm.commit();
         }
         catch ( Exception e )
         {
+               running = false;
+               rm.rollback();
                LOG.warn( "Errors while reclaiming", e );
                throw new RuntimeException( e );
         }
@@ -146,6 +152,8 @@ public class SpaceReclaimer
             }
         }
 
+        cursor.close();
+        
         return lst;
     }
 }
index 4d1b869..3db277a 100644 (file)
@@ -110,4 +110,41 @@ public class SpaceReclaimerTest
         \r
         assertEquals( count, total );\r
     }\r
+    \r
+\r
+    /**\r
+     * with the reclaimer threshold 10 and total entries of 1120\r
+     * there was a condition that resulted in OOM while reopening the RM\r
+     * \r
+     * This issue was fixed after SpaceReclaimer was updated to run in\r
+     * a transaction.\r
+     * \r
+     * This test is present to verify the fix\r
+     * \r
+     * @throws Exception\r
+     */\r
+    @Test\r
+    public void testReclaimerWithMagicNum() throws Exception\r
+    {\r
+       rm.setSpaceReclaimerThreshold( 10 );\r
+       \r
+        int total = 1120;\r
+        for ( int i=0; i < total; i++ )\r
+        {\r
+            uidTree.insert( i, String.valueOf( i ) );\r
+        }\r
+\r
+        closeAndReopenRM();\r
+        \r
+        int count = 0;\r
+        TupleCursor<Integer, String> cursor = uidTree.browse();\r
+        while ( cursor.hasNext() )\r
+        {\r
+            Tuple<Integer, String> t = cursor.next();\r
+            assertEquals( t.key, Integer.valueOf( count ) );\r
+            count++;\r
+        }\r
+        \r
+        assertEquals( count, total );\r
+    }\r
 }\r