You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2014/05/02 20:48:52 UTC

svn commit: r1592008 - in /directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree: MavibotInspector.java RecordManager.java

Author: kayyagari
Date: Fri May  2 18:48:52 2014
New Revision: 1592008

URL: http://svn.apache.org/r1592008
Log:
o added a utility to inspect the DB file
o modified the visibility of few methods in RecordManager to make them callable from the MavibotInspector class
o made all check/dump methods to print to standard output (a file stream support will be added later)

Added:
    directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/MavibotInspector.java
Modified:
    directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java

Added: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/MavibotInspector.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/MavibotInspector.java?rev=1592008&view=auto
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/MavibotInspector.java (added)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/MavibotInspector.java Fri May  2 18:48:52 2014
@@ -0,0 +1,317 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree;
+
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.util.Set;
+
+import org.apache.directory.mavibot.btree.serializer.StringSerializer;
+
+
+/**
+ * A class to examine a Mavibot database file.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class MavibotInspector
+{
+    private File dbFile;
+
+    private RecordManager rm;
+
+    private BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
+
+
+    public MavibotInspector( File dbFile )
+    {
+        this.dbFile = dbFile;
+    }
+
+
+    boolean checkFilePresence()
+    {
+        if ( dbFile == null )
+        {
+            System.out.println( "No mavibot database file was given" );
+            return false;
+        }
+
+        if ( !dbFile.exists() )
+        {
+            System.out.println( "Given mavibot database file " + dbFile + " doesn't exist" );
+            return false;
+        }
+
+        return true;
+    }
+
+
+    public void printFileSize() throws IOException
+    {
+        FileChannel fileChannel = new RandomAccessFile( dbFile, "r" ).getChannel();
+
+        long l = fileChannel.size();
+
+        fileChannel.close();
+
+        String msg;
+
+        if ( l < 1024 )
+        {
+            msg = l + " bytes";
+        }
+        else
+        {
+            msg = ( l / 1024 ) + " KB";
+        }
+
+        System.out.println( msg );
+    }
+
+
+    public void printNumberOfBTrees()
+    {
+        int nbBtrees = 0;
+        if ( rm != null )
+        {
+            nbBtrees = rm.getNbManagedTrees();
+        }
+
+        // The number of trees. It must be at least 2 and > 0
+        System.out.println( "Total Number of BTrees: " + nbBtrees );
+    }
+
+
+    public void printBTreeNames()
+    {
+        if ( rm == null )
+        {
+            System.out.println( "Couldn't find the number of managed btrees" );
+            return;
+        }
+
+        Set<String> trees = rm.getManagedTrees();
+        System.out.println( "\nManaged BTrees:" );
+        for ( String t : trees )
+        {
+            System.out.println( t );
+        }
+        System.out.println();
+    }
+
+
+    public void checkBTree()
+    {
+        if ( rm == null )
+        {
+            System.out.println( "Cannot check BTree(s)" );
+            return;
+        }
+
+        System.out.print( "BTree Name: " );
+        String name = readLine();
+
+        PersistedBTree pb = ( PersistedBTree ) rm.getManagedTree( name );
+
+        if ( pb == null )
+        {
+            System.out.println( "No BTree exists with the name '" + name + "'" );
+            return;
+        }
+
+        System.out.println( "\nBTree offset: " + pb.getBtreeOffset() );
+        System.out.println( "BTree _info_ offset: " + pb.getBtreeInfoOffset() );
+        System.out.println( "BTree root page offset: " + pb.getRootPageOffset() );
+        System.out.println( "Number of elements present: " + pb.getNbElems() );
+        System.out.println( "BTree Page size: " + pb.getPageSize() );
+        System.out.println( "BTree revision: " + pb.getRevision() );
+        System.out.println( "Key serializer: " + pb.getKeySerializerFQCN() );
+        System.out.println( "Value serializer: " + pb.getValueSerializerFQCN() );
+        System.out.println();
+
+    }
+
+
+    private boolean loadRm()
+    {
+        try
+        {
+            if( rm != null )
+            {
+                System.out.println("Closing record manager");
+                rm.close();
+            }
+            
+            rm = new RecordManager( dbFile.getAbsolutePath() );
+            System.out.println("Loaded record manager");
+        }
+        catch ( Exception e )
+        {
+            System.out.println( "Given database file seems to be corrupted. " + e.getMessage() );
+            return false;
+        }
+
+        return true;
+    }
+
+
+    public void start() throws Exception
+    {
+        if ( !checkFilePresence() )
+        {
+            return;
+        }
+
+        if ( !loadRm() )
+        {
+            return;
+        }
+
+        boolean stop = false;
+
+        while ( !stop )
+        {
+            System.out.println( "Choose an option:" );
+            System.out.println( "1. Print Number of BTrees" );
+            System.out.println( "2. Print BTree Names" );
+            System.out.println( "3. Inspect BTree" );
+            System.out.println( "4. Check Free Pages" );
+            System.out.println( "5. Get database file size" );
+            System.out.println( "6. Dump RecordManager" );
+            System.out.println( "7. Reload RecordManager" );
+            System.out.println( "q. Quit" );
+
+            char c = readOption();
+
+            switch ( c )
+            {
+                case '1':
+                    printNumberOfBTrees();
+                    break;
+
+                case '2':
+                    printBTreeNames();
+                    break;
+
+                case '3':
+                    checkBTree();
+                    break;
+
+                case '4':
+                    rm.checkFreePages();
+                    break;
+
+                case '5':
+                    printFileSize();
+                    break;
+
+                case '6':
+                    rm.check();
+                    break;
+
+                case '7':
+                    loadRm();
+                    break;
+
+                case 'q':
+                    stop = true;
+                    break;
+
+                default:
+                    System.out.println( "Invalid option" );
+                    //c = readOption( br );
+                    break;
+            }
+        }
+
+        try
+        {
+            rm.close();
+            br.close();
+        }
+        catch ( Exception e )
+        {
+            //ignore
+        }
+    }
+
+
+    private String readLine()
+    {
+        try
+        {
+            return br.readLine().trim();
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    private char readOption()
+    {
+        try
+        {
+            String s = br.readLine();
+
+            if ( s.length() == 0 )
+            {
+                return ' ';
+            }
+
+            return s.charAt( 0 );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    public static void main( String[] args ) throws Exception
+    {
+        File f = new File( "/tmp/mavibotispector.db" );
+
+        RecordManager rm = new RecordManager( f.getAbsolutePath() );
+        String name = "corpus";
+        if ( !rm.getManagedTrees().contains( name ) )
+        {
+            rm.addBTree( name, StringSerializer.INSTANCE, StringSerializer.INSTANCE, true );
+        }
+
+        BTree btree = rm.getManagedTree( name );
+        for ( int i = 0; i < 10; i++ )
+        {
+            btree.insert( "" + i, "" + i );
+        }
+
+        rm.close();
+
+        MavibotInspector mi = new MavibotInspector( f );
+        mi.start();
+    }
+}

Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java?rev=1592008&r1=1592007&r2=1592008&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java Fri May  2 18:48:52 2014
@@ -109,7 +109,7 @@ public class RecordManager extends Abstr
     private BTree<RevisionName, long[]> copiedPageBtree;
 
     /** A constant for an offset on a non existing page */
-    private static final long NO_PAGE = -1L;
+    public static final long NO_PAGE = -1L;
 
     /** The number of element we can store in a page */
     private static final int PAGE_SIZE = 4;
@@ -123,7 +123,7 @@ public class RecordManager extends Abstr
     private static final int LONG_SIZE = 8;
 
     /** The default page size */
-    private static final int DEFAULT_PAGE_SIZE = 512;
+    public static final int DEFAULT_PAGE_SIZE = 512;
 
     /** The minimal page size. Can't be below 64, as we have to store many thing sin the RMHeader */
     private static final int MIN_PAGE_SIZE = 64;
@@ -2996,8 +2996,7 @@ public class RecordManager extends Abstr
      */
     public void dump()
     {
-        LOG.debug( "/---------------------------- Dump ----------------------------\\" );
-//        System.out.println( "/---------------------------- Dump ----------------------------\\" );
+        System.out.println( "/---------------------------- Dump ----------------------------\\" );
 
         try
         {
@@ -3034,34 +3033,18 @@ public class RecordManager extends Abstr
             // The previous CopiedPages B-tree
             long previousCopiedPagesBtreePage = recordManagerHeader.getLong();
 
-            if ( LOG.isDebugEnabled() )
-            {
-                LOG.debug( "  RecordManager" );
-                LOG.debug( "  -------------" );
-                LOG.debug( "    Header " );
-                LOG.debug( "    Size = 0x{}", Long.toHexString( fileSize ) );
-                LOG.debug( "    NbPages = {}", nbPages );
-                LOG.debug( "      page size : {}", pageSize );
-                LOG.debug( "      nbTree : {}", nbBtree );
-                LOG.debug( "      firstFreePage : {}", Long.toHexString( firstFreePage ) );
-                LOG.debug( "      current BOB : {}", Long.toHexString( currentBtreeOfBtreesPage ) );
-                LOG.debug( "      previous BOB : {}", Long.toHexString( previousBtreeOfBtreesPage ) );
-                LOG.debug( "      current CopiedPages : {}", Long.toHexString( currentCopiedPagesBtreePage ) );
-                LOG.debug( "      previous CopiedPages : {}", Long.toHexString( previousCopiedPagesBtreePage ) );
-            }
-
-//            System.out.println( "  RecordManager" );
-//            System.out.println( "  -------------" );
-//            System.out.println( "  Size = 0x" + Long.toHexString( fileSize ) );
-//            System.out.println( "  NbPages = " + nbPages );
-//            System.out.println( "    Header " );
-//            System.out.println( "      page size : " + pageSize );
-//            System.out.println( "      nbTree : " + nbBtree );
-//            System.out.println( "      firstFreePage : 0x" + Long.toHexString( firstFreePage ) );
-//            System.out.println( "      current BOB : 0x" + Long.toHexString( currentBtreeOfBtreesPage ) );
-//            System.out.println( "      previous BOB : 0x" + Long.toHexString( previousBtreeOfBtreesPage ) );
-//            System.out.println( "      current CopiedPages : 0x" + Long.toHexString( currentCopiedPagesBtreePage ) );
-//            System.out.println( "      previous CopiedPages : 0x" + Long.toHexString( previousCopiedPagesBtreePage ) );
+            System.out.println( "  RecordManager" );
+            System.out.println( "  -------------" );
+            System.out.println( "  Size = 0x" + Long.toHexString( fileSize ) );
+            System.out.println( "  NbPages = " + nbPages );
+            System.out.println( "    Header " );
+            System.out.println( "      page size : " + pageSize );
+            System.out.println( "      nbTree : " + nbBtree );
+            System.out.println( "      firstFreePage : 0x" + Long.toHexString( firstFreePage ) );
+            System.out.println( "      current BOB : 0x" + Long.toHexString( currentBtreeOfBtreesPage ) );
+            System.out.println( "      previous BOB : 0x" + Long.toHexString( previousBtreeOfBtreesPage ) );
+            System.out.println( "      current CopiedPages : 0x" + Long.toHexString( currentCopiedPagesBtreePage ) );
+            System.out.println( "      previous CopiedPages : 0x" + Long.toHexString( previousCopiedPagesBtreePage ) );
 
             long position = RECORD_MANAGER_HEADER_SIZE;
 
@@ -3089,8 +3072,7 @@ public class RecordManager extends Abstr
 
             // Dump all the user's B-tree
             randomFile.close();
-            LOG.debug( "\\---------------------------- Dump ----------------------------/" );
-//            System.out.println( "\\---------------------------- Dump ----------------------------/" );
+            System.out.println( "\\---------------------------- Dump ----------------------------/" );
         }
         catch ( IOException ioe )
         {
@@ -3104,16 +3086,14 @@ public class RecordManager extends Abstr
      */
     private void dumpFreePages( long freePageOffset ) throws EndOfFileExceededException, IOException
     {
-//        System.out.println( "\n  FreePages : " );
-        LOG.debug( "\n  FreePages : " );
+        System.out.println( "\n  FreePages : " );
         int pageNb = 1;
 
         while ( freePageOffset != NO_PAGE )
         {
             PageIO pageIo = fetchPage( freePageOffset );
 
-            LOG.debug( "    freePage[{}] : 0x{}", pageNb, Long.toHexString( pageIo.getOffset() ) );
-//            System.out.println( "    freePage[" + pageNb + "] : 0x" + Long.toHexString( pageIo.getOffset() ) );
+            System.out.println( "    freePage[" + pageNb + "] : 0x" + Long.toHexString( pageIo.getOffset() ) );
 
             freePageOffset = pageIo.getNextPage();
             pageNb++;
@@ -3551,17 +3531,19 @@ public class RecordManager extends Abstr
 
     private void setCheckedPage( long[] checkedPages, long offset, int pageSize )
     {
-        long pageOffset = ( offset - RECORD_MANAGER_HEADER_SIZE ) / pageSize;
-        int index = ( int ) ( pageOffset / 64L );
-        long mask = ( 1L << ( pageOffset % 64L ) );
-        long bits = checkedPages[index];
-
-        if ( ( bits & mask ) == 1 )
+        int pageNumber = ( int ) offset / pageSize;
+        int nbBitsPage = ( LONG_SIZE << 3 );
+        long pageMask = checkedPages[ pageNumber / nbBitsPage ];
+        long mask = 1L << pageNumber % nbBitsPage;
+        
+        if ( ( pageMask & mask ) != 0 )
         {
-            throw new RecordManagerException( "The page at : " + offset + " has already been checked" );
+            throw new InvalidBTreeException( "The page " + offset + " has already been referenced" );
         }
 
-        checkedPages[index] |= mask;
+        pageMask |= mask;
+        
+        checkedPages[ pageNumber / nbBitsPage ] |= pageMask;
     }
 
 
@@ -3587,7 +3569,8 @@ public class RecordManager extends Abstr
         {
             if ( currentOffset > fileSize )
             {
-                throw new FreePageException( "Wrong free page offset, above file size : " + currentOffset );
+                System.out.println( "Wrong free page offset, above file size : " + currentOffset );
+                return;
             }
 
             try
@@ -3596,8 +3579,9 @@ public class RecordManager extends Abstr
 
                 if ( currentOffset != pageIo.getOffset() )
                 {
-                    throw new InvalidBTreeException( "PageIO offset is incorrect : " + currentOffset + "-"
+                    System.out.println( "PageIO offset is incorrect : " + currentOffset + "-"
                         + pageIo.getOffset() );
+                    return;
                 }
 
                 setCheckedPage( checkedPages, currentOffset, pageSize );
@@ -3610,6 +3594,39 @@ public class RecordManager extends Abstr
                 throw new InvalidBTreeException( "Cannot fetch page at : " + currentOffset );
             }
         }
+        
+        StringBuilder sb = new StringBuilder();
+        int i = -1;
+       
+        for ( long checkedPage : checkedPages )
+        {
+            if ( i == -1 )
+            {
+                i = 0;
+            }
+            else
+            {
+                i++;
+                sb.append( " " );
+            }
+           
+            sb.append( "[" ).append( i ).append(  "] " );
+ 
+           
+            for ( int j = 0; j < 64; j++ )
+            {
+                if ( ( checkedPage & ( 1L << j ) )  == 0 )
+                {
+                    sb.append( "0" );
+                }
+                else
+                {
+                    sb.append( "1" );
+                }
+            }
+        }
+       
+        System.out.println( sb.toString() );
     }
 
 
@@ -3903,7 +3920,7 @@ public class RecordManager extends Abstr
     /**
      * Check the whole file
      */
-    private void check()
+    /* no qualifier */ void check()
     {
         try
         {
@@ -4007,12 +4024,13 @@ public class RecordManager extends Abstr
     /**
      * Check the free pages list
      */
-    private void checkFreePages()
+    /* no qualifier */ void checkFreePages()
     {
         try
         {
             if ( firstFreePage == NO_PAGE )
             {
+                System.out.println("No Free pages exist.");
                 return;
             }
 
@@ -4020,6 +4038,8 @@ public class RecordManager extends Abstr
             Set<Long> seenOffset = new HashSet<Long>();
             seenOffset.add( currentFreePage );
 
+            long count = 0;
+            
             while ( currentFreePage != NO_PAGE )
             {
                 PageIO pageIo = fetchPage( currentFreePage );
@@ -4030,12 +4050,15 @@ public class RecordManager extends Abstr
 
                 if ( seenOffset.contains( currentFreePage ) )
                 {
-                    System.out.println( "ERROR !!! The FreePage lists is broken" );
+                    System.out.println( "ERROR !!! The FreePage list is broken, the offset " + currentFreePage + " is linked twice" );
                     dumpFreePages( firstFreePage );
+                    return;
                 }
+                
+                count++;
             }
 
-            return;
+            System.out.println( "Free page list is valid. There are " + count + " free pages." );
         }
         catch ( Exception e )
         {