You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by el...@apache.org on 2013/07/18 22:08:54 UTC
svn commit: r1504628 -
/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/RecordManager.java
Author: elecharny
Date: Thu Jul 18 20:08:54 2013
New Revision: 1504628
URL: http://svn.apache.org/r1504628
Log:
Some more checks for the RM
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/RecordManager.java
Modified: labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/RecordManager.java
URL: http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/RecordManager.java?rev=1504628&r1=1504627&r2=1504628&view=diff
==============================================================================
--- labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/RecordManager.java (original)
+++ labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/RecordManager.java Thu Jul 18 20:08:54 2013
@@ -342,7 +342,6 @@ public class RecordManager
long btreeOffset = HEADER_SIZE;
PageIO[] pageIos = readPageIOs( HEADER_SIZE, Long.MAX_VALUE );
- long position = pageIos.length * pageSize + HEADER_SIZE;
// Create the BTree
copiedPageBTree = BTreeFactory.createBTree();
@@ -2237,6 +2236,23 @@ public class RecordManager
}
+ private void setCheckedPage( long[] checkedPages, long offset, int pageSize )
+ {
+ long pageOffset = ( offset - HEADER_SIZE ) / pageSize;
+ int index = ( int ) ( pageOffset / 64L );
+ long mask = ( 1L << ( pageOffset % 64L ) );
+ long bits = checkedPages[index];
+
+ if ( ( bits & mask ) == 1 )
+ {
+ throw new RuntimeException( "The page at : " + offset + " has already been checked" );
+ }
+
+ checkedPages[index] |= mask;
+
+ }
+
+
/**
* Check the free pages
*
@@ -2284,16 +2300,7 @@ public class RecordManager
+ pageIo.getOffset() );
}
- int index = ( int ) ( ( currentOffset - HEADER_SIZE ) / ( pageSize * 64 ) );
- long mask = ( 1L << ( ( ( currentOffset - HEADER_SIZE ) / pageSize ) % 64L ) );
- long bits = checkedPages[index];
-
- if ( ( bits & mask ) == 1 )
- {
- throw new RuntimeException( "The page at : " + currentOffset + " has already been checked" );
- }
-
- checkedPages[index] |= mask;
+ setCheckedPage( checkedPages, currentOffset, pageSize );
long newOffset = pageIo.getNextPage();
currentOffset = newOffset;
@@ -2306,9 +2313,162 @@ public class RecordManager
}
- private void checkBTrees( long[] checkedPages, int pageSize )
+ private long checkBTree( long[] checkedPages, PageIO[] pageIos, int pageSize, boolean isLast )
+ throws EndOfFileExceededException, IOException
+ {
+ long dataPos = 0L;
+
+ // The BTree current revision
+ long revision = readLong( pageIos, dataPos );
+ dataPos += LONG_SIZE;
+
+ // The nb elems in the tree
+ long nbElems = readLong( pageIos, dataPos );
+ dataPos += LONG_SIZE;
+
+ // The BTree rootPage offset
+ long rootPageOffset = readLong( pageIos, dataPos );
+
+ if ( ( rootPageOffset < 0 ) || ( rootPageOffset > fileChannel.size() ) )
+ {
+ throw new RuntimeException( "The rootpage is incorrect : " + rootPageOffset );
+ }
+
+ dataPos += LONG_SIZE;
+
+ // The next BTree offset
+ long nextBTreeOffset = readLong( pageIos, dataPos );
+
+ if ( ( ( rootPageOffset < 0 ) && ( !isLast ) ) || ( nextBTreeOffset > fileChannel.size() ) )
+ {
+ throw new RuntimeException( "The rootpage is incorrect : " + rootPageOffset );
+ }
+
+ dataPos += LONG_SIZE;
+
+ // The BTree page size
+ int btreePageSize = readInt( pageIos, dataPos );
+
+ if ( ( btreePageSize < 2 ) || ( ( btreePageSize & ( ~btreePageSize + 1 ) ) != btreePageSize ) )
+ {
+ throw new RuntimeException( "The BTree page size is not a power of 2 : " + btreePageSize );
+ }
+
+ dataPos += INT_SIZE;
+
+ // The tree name
+ byte[] btreeNameBytes = readBytes( pageIos, dataPos );
+ dataPos += INT_SIZE;
+
+ dataPos += btreeNameBytes.length;
+ String btreeName = Strings.utf8ToString( btreeNameBytes );
+
+ // The keySerializer FQCN
+ byte[] keySerializerBytes = readBytes( pageIos, dataPos );
+
+ String keySerializerFqcn = null;
+ dataPos += INT_SIZE;
+
+ if ( keySerializerBytes != null )
+ {
+ dataPos += keySerializerBytes.length;
+ keySerializerFqcn = Strings.utf8ToString( keySerializerBytes );
+ }
+ else
+ {
+ keySerializerFqcn = "";
+ }
+
+ // The valueSerialier FQCN
+ byte[] valueSerializerBytes = readBytes( pageIos, dataPos );
+
+ String valueSerializerFqcn = null;
+ dataPos += INT_SIZE;
+
+ if ( valueSerializerBytes != null )
+ {
+ dataPos += valueSerializerBytes.length;
+ valueSerializerFqcn = Strings.utf8ToString( valueSerializerBytes );
+ }
+ else
+ {
+ valueSerializerFqcn = "";
+ }
+
+ // The BTree allowDuplicates flag
+ int allowDuplicates = readInt( pageIos, dataPos );
+ dataPos += INT_SIZE;
+
+ // Now, load the rootPage, which can be a Leaf or a Node, depending
+ // on the number of elements in the tree : if it's above the pageSize,
+ // it's a Node, otherwise it's a Leaf
+
+ // Read the rootPage pages on disk
+ //PageIO[] rootPageIos = readPageIOs( rootPageOffset, Long.MAX_VALUE );
+
+ return nextBTreeOffset;
+ }
+
+
+ /**
+ * Check each BTree we manage
+ * @throws IOException
+ * @throws EndOfFileExceededException
+ */
+ private void checkBTrees( long[] checkedPages, int pageSize, int nbBTrees ) throws EndOfFileExceededException,
+ IOException
{
+ // Iterate on each BTree until we have exhausted all of them. The number
+ // of btrees is just used to check that we have the correct number
+ // of stored BTrees, as they are all linked.
+ long position = HEADER_SIZE;
+ for ( int i = 0; i < nbBTrees; i++ )
+ {
+ // Load the pageIOs containing the BTree
+ PageIO[] pageIos = readPageIOs( position, Long.MAX_VALUE );
+
+ // Check that they are correctly linked and not already used
+ int pageNb = 0;
+
+ for ( PageIO currentPageIo : pageIos )
+ {
+ //
+ long nextPageOffset = currentPageIo.getNextPage();
+
+ if ( pageNb == pageIos.length - 1 )
+ {
+ if ( nextPageOffset != NO_PAGE )
+ {
+ throw new RuntimeException( "The pointer to the next page is not valid, expected NO_PAGE" );
+ }
+ }
+ else
+ {
+ if ( nextPageOffset == NO_PAGE )
+ {
+ throw new RuntimeException( "The pointer to the next page is not valid, NO_PAGE" );
+ }
+ }
+
+ if ( ( nextPageOffset != NO_PAGE ) && ( ( nextPageOffset - HEADER_SIZE ) % pageSize != 0 ) )
+ {
+ throw new RuntimeException( "The pointer to the next page is not valid" );
+ }
+
+ // Update the array of processed pages
+ setCheckedPage( checkedPages, currentPageIo.getOffset(), pageSize );
+ }
+
+ // Now check the BTree
+ long nextBTree = checkBTree( checkedPages, pageIos, pageSize, i == nbBTrees - 1 );
+
+ if ( ( nextBTree == NO_PAGE ) && ( i < nbBTrees - 1 ) )
+ {
+ throw new RuntimeException( "The pointer to the next BTree is incorrect" );
+ }
+ position = nextBTree;
+ }
}
@@ -2347,11 +2507,11 @@ public class RecordManager
long nbPages = ( fileSize - HEADER_SIZE ) / pageSize;
// The number of trees. It must be at least 2 and > 0
- int nbTrees = header.getInt();
+ int nbBTrees = header.getInt();
- if ( nbTrees < 0 )
+ if ( nbBTrees < 0 )
{
- throw new RuntimeException( "Wrong nb trees : " + nbTrees );
+ throw new RuntimeException( "Wrong nb trees : " + nbBTrees );
}
// The first free page offset. It must be either -1 or below file size
@@ -2388,11 +2548,14 @@ public class RecordManager
checkFreePages( checkedPages, pageSize, firstFreePage, lastFreePage );
// The BTrees
- checkBTrees( checkedPages, pageSize );
+ checkBTrees( checkedPages, pageSize, nbBTrees );
}
- catch ( IOException ioe )
+ catch ( Exception e )
{
- throw new RuntimeException( "Error : " + ioe.getMessage() );
+ // We catch the exception and rethrow it immediately to be able to
+ // put a breakpoint here
+ e.printStackTrace();
+ throw new RuntimeException( "Error : " + e.getMessage() );
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org