You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2014/03/10 21:27:49 UTC
svn commit: r1576069 - in /directory/mavibot/branches/with-txns/mavibot/src:
main/java/org/apache/directory/mavibot/btree/
test/java/org/apache/directory/mavibot/btree/
Author: elecharny
Date: Mon Mar 10 20:27:49 2014
New Revision: 1576069
URL: http://svn.apache.org/r1576069
Log:
Fixed the delete operation when used with transaction on a persisted btre.
Modified:
directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java
directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java
directory/mavibot/branches/with-txns/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java?rev=1576069&r1=1576068&r2=1576069&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java Mon Mar 10 20:27:49 2014
@@ -362,13 +362,20 @@ import org.apache.directory.mavibot.btre
{
ReadTransaction<K, V> transaction = beginReadTransaction( revision );
- try
+ if ( transaction == null )
{
- return transaction.getRootPage().get( key );
+ return null;
}
- finally
+ else
{
- transaction.close();
+ try
+ {
+ return transaction.getRootPage().get( key );
+ }
+ finally
+ {
+ transaction.close();
+ }
}
}
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java?rev=1576069&r1=1576068&r2=1576069&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java Mon Mar 10 20:27:49 2014
@@ -273,58 +273,76 @@ public class PersistedBTree<K, V> extend
*/
/* no qualifier */ Tuple<K, V> delete( K key, V value, long revision ) throws IOException
{
- recordManager.beginTransaction();
-
- // Try to delete the entry starting from the root page. Here, the root
- // page may be either a Node or a Leaf
- DeleteResult<K, V> result = processDelete( key, value, revision );
-
- // Check that we have found the element to delete
- if ( result instanceof NotPresentResult )
+ // We have to start a new transaction, which will be committed or rollbacked
+ // locally. This will duplicate the current BtreeHeader during this phase.
+ if ( revision == -1L )
{
- // We haven't found the element in the B-tree, just get out
- recordManager.commit();
-
- return null;
+ revision = currentRevision.get() + 1;
}
- // The element was found, and removed
- AbstractDeleteResult<K, V> deleteResult = ( AbstractDeleteResult<K, V> ) result;
-
- Tuple<K, V> tuple = deleteResult.getRemovedElement();
-
- // Update the B-tree header, creating a new BtreeHeader page now
- long newBtreeHeaderOffset = recordManager.updateBtreeHeader( this, ( ( AbstractPage<K, V> ) getRootPage() ).getOffset() );
+ recordManager.beginTransaction();
- // Update the B-tree of B-trees with this new offset, if we are not already doing so
- switch ( btreeType )
+ try
{
- case PERSISTED :
- // We have a new B-tree header to inject into the B-tree of btrees
- recordManager.addInBtreeOfBtrees( getName(), revision, newBtreeHeaderOffset );
- break;
+ // Try to delete the entry starting from the root page. Here, the root
+ // page may be either a Node or a Leaf
+ DeleteResult<K, V> result = processDelete( key, value, revision );
- case BTREE_OF_BTREES :
- case COPIED_PAGES_BTREE :
- // The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
- getBtreeHeader().setBTreeHeaderOffset( newBtreeHeaderOffset );
+ // Check that we have found the element to delete
+ if ( result instanceof NotPresentResult )
+ {
+ // We haven't found the element in the B-tree, just get out
+ // without updating the recordManager
+ rollback();
- break;
+ return null;
+ }
- default:
- // Nothing to do for sub-btrees
- break;
- }
+ // The element was found, and removed
+ AbstractDeleteResult<K, V> deleteResult = ( AbstractDeleteResult<K, V> ) result;
- // We can safely free the copied pages
- recordManager.freePages( this, revision, result.getCopiedPages() );
+ Tuple<K, V> tuple = deleteResult.getRemovedElement();
+//
+// // Update the B-tree header, creating a new BtreeHeader page now
+// long newBtreeHeaderOffset = recordManager.updateBtreeHeader( this, ( ( AbstractPage<K, V> ) getRootPage() ).getOffset() );
+//
+// // Update the B-tree of B-trees with this new offset, if we are not already doing so
+// switch ( btreeType )
+// {
+// case PERSISTED :
+// // We have a new B-tree header to inject into the B-tree of btrees
+// recordManager.addInBtreeOfBtrees( getName(), revision, newBtreeHeaderOffset );
+// break;
+//
+// case BTREE_OF_BTREES :
+// case COPIED_PAGES_BTREE :
+// // The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
+// getBtreeHeader().setBTreeHeaderOffset( newBtreeHeaderOffset );
+//
+// break;
+//
+// default:
+// // Nothing to do for sub-btrees
+// break;
+// }
+//
+// // We can safely free the copied pages
+// recordManager.freePages( this, revision, result.getCopiedPages() );
- // If the B-tree is managed, we have to update the rootPage on disk
- // Update the RecordManager header
- recordManager.commit();
+ // If the B-tree is managed, we have to update the rootPage on disk
+ // Update the RecordManager header
+ commit();
- // Return the value we have found if it was modified
- return tuple;
+ // Return the value we have found if it was modified
+ return tuple;
+ }
+ catch ( IOException ioe )
+ {
+ // if we've got an error, we have to rollback
+ rollback();
+
+ throw ioe;
+ }
}
@@ -333,9 +351,12 @@ public class PersistedBTree<K, V> extend
*/
private DeleteResult<K, V> processDelete( K key, V value, long revision ) throws IOException
{
+ // Get the current B-tree header, and delete the value from it
+ BTreeHeader<K, V> btreeHeader = getBtreeHeader();
+
// Try to delete the entry starting from the root page. Here, the root
// page may be either a Node or a Leaf
- DeleteResult<K, V> result = getRootPage().delete( key, value, revision);
+ DeleteResult<K, V> result = btreeHeader.getRootPage().delete( key, value, revision);
if ( result instanceof NotPresentResult )
{
@@ -343,34 +364,92 @@ public class PersistedBTree<K, V> extend
return result;
}
+ // Create a new BTreeHeader
+ BTreeHeader<K, V> newBtreeHeader = btreeHeader.copy();
+
+ // Inject the old B-tree header into the pages to be freed
+ // if we are deleting an element from a management BTree
+ if ( ( btreeType == BTreeTypeEnum.BTREE_OF_BTREES ) || ( btreeType == BTreeTypeEnum.COPIED_PAGES_BTREE ) )
+ {
+ PageIO[] pageIos = recordManager.readPageIOs( btreeHeader.getBTreeHeaderOffset(), -1L );
+
+ for ( PageIO pageIo : pageIos )
+ {
+ recordManager.freedPages.add( pageIo );
+ }
+ }
+
// The element was found, and removed
AbstractDeleteResult<K, V> removeResult = ( AbstractDeleteResult<K, V> ) result;
- Page<K, V> modifiedPage = removeResult.getModifiedPage();
+ // This is a new root
+ Page<K, V> newRootPage = removeResult.getModifiedPage();
// Write the modified page on disk
// Note that we don't use the holder, the new root page will
// remain in memory.
- PageHolder<K, V> holder = writePage( modifiedPage, revision );
+ PageHolder<K, V> holder = writePage( newRootPage, revision );
// Store the offset on disk in the page in memory
- ( ( AbstractPage<K, V> ) modifiedPage ).setOffset( ( ( PersistedPageHolder<K, V> ) holder )
- .getOffset() );
+// ( ( AbstractPage<K, V> ) modifiedPage ).setOffset( ( ( PersistedPageHolder<K, V> ) holder )
+// .getOffset() );
+//
+// // Store the last offset on disk in the page in memory
+// ( ( AbstractPage<K, V> ) modifiedPage )
+// .setLastOffset( ( ( PersistedPageHolder<K, V> ) holder )
+// .getLastOffset() );
+
+ // Decrease the number of elements in the current tree
+ newBtreeHeader.decrementNbElems();
+ newBtreeHeader.setRootPage( newRootPage );
+ newBtreeHeader.setRevision( revision );
- // Store the last offset on disk in the page in memory
- ( ( AbstractPage<K, V> ) modifiedPage )
- .setLastOffset( ( ( PersistedPageHolder<K, V> ) holder )
- .getLastOffset() );
+ // Write down the data on disk
+ long newBtreeHeaderOffset = recordManager.writeBtreeHeader( this, newBtreeHeader );
- // This is a new root
- //rootPage = modifiedPage;
- // Decrease the number of elements in the current tree
- getBtreeHeader().decrementNbElems();
+ // Update the B-tree of B-trees with this new offset, if we are not already doing so
+ switch ( btreeType )
+ {
+ case PERSISTED :
+ // We have a new B-tree header to inject into the B-tree of btrees
+ recordManager.addInBtreeOfBtrees( getName(), revision, newBtreeHeaderOffset );
+
+ recordManager.addInCopiedPagesBtree( getName(), revision, result.getCopiedPages() );
+
+ // Store the new revision
+ storeRevision( newBtreeHeader );
- // We have to update the rootPage on disk
- // Update the B-tree header now
- recordManager.updateBtreeHeader( this, ( ( AbstractPage<K, V> ) getBtreeHeader().getRootPage() ).getOffset() );
+ break;
+
+ case BTREE_OF_BTREES :
+ // The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
+ recordManager.updateRecordManagerHeader( newBtreeHeaderOffset, -1L );
+
+ // We can free the copied pages
+ recordManager.freePages( this, revision, result.getCopiedPages() );
+
+ // Store the new revision
+ storeRevision( newBtreeHeader );
+
+ break;
+
+ case COPIED_PAGES_BTREE :
+ // The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
+ recordManager.updateRecordManagerHeader( -1L, newBtreeHeaderOffset );
+
+ // We can free the copied pages
+ recordManager.freePages( this, revision, result.getCopiedPages() );
+
+ // Store the new revision
+ storeRevision( newBtreeHeader );
+
+ break;
+
+ default:
+ // Nothing to do for sub-btrees
+ break;
+ }
// Return the value we have found if it was modified
return result;
Modified: directory/mavibot/branches/with-txns/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java?rev=1576069&r1=1576068&r2=1576069&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java Mon Mar 10 20:27:49 2014
@@ -615,20 +615,16 @@ public class RecordManagerTest
// Check that we can get a value from each revision
// revision 1
- assertEquals( "V3", btree.get( rev1, 3L ) );
+ checkBTreeRevisionBrowse( btree, rev1 );
// revision 2
- assertEquals( "V1", btree.get( rev2, 1L ) );
- assertEquals( "V3", btree.get( rev2, 3L ) );
+ checkBTreeRevisionBrowse( btree, rev2 );
// revision 3
- assertEquals( "V1", btree.get( rev3, 1L ) );
- assertEquals( "V3", btree.get( rev3, 3L ) );
- assertEquals( "V5", btree.get( rev3, 5L ) );
+ checkBTreeRevisionBrowse( btree, rev3 );
// revision 4
- assertEquals( "V1", btree.get( rev4, 1L ) );
- assertEquals( "V5", btree.get( rev4, 5L ) );
+ checkBTreeRevisionBrowse( btree, rev4, 1L, 5L );
try
{