Return-Path: X-Original-To: apmail-directory-commits-archive@www.apache.org Delivered-To: apmail-directory-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4E2611097F for ; Fri, 20 Dec 2013 09:59:14 +0000 (UTC) Received: (qmail 84376 invoked by uid 500); 20 Dec 2013 09:59:14 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 84316 invoked by uid 500); 20 Dec 2013 09:59:13 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 84281 invoked by uid 99); 20 Dec 2013 09:59:11 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Dec 2013 09:59:11 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Dec 2013 09:59:05 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 5D3A3238890B; Fri, 20 Dec 2013 09:58:43 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1552574 - in /directory/mavibot/trunk/mavibot/src: main/java/org/apache/directory/mavibot/btree/ test/java/org/apache/directory/mavibot/btree/ Date: Fri, 20 Dec 2013 09:58:43 -0000 To: commits@directory.apache.org From: elecharny@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131220095843.5D3A3238890B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: elecharny Date: Fri Dec 20 09:58:42 2013 New Revision: 1552574 URL: http://svn.apache.org/r1552574 Log: o First drop of transaction support. It really does nothing but encapsulates the transaction mechanisms to get it working when t will be ready. Added: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeTransactionTest.java Modified: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/WriteTransaction.java Modified: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java?rev=1552574&r1=1552573&r2=1552574&view=diff ============================================================================== --- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java (original) +++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java Fri Dec 20 09:58:42 2013 @@ -24,6 +24,7 @@ import java.io.Closeable; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; +import java.util.Map; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.ReentrantLock; @@ -347,7 +348,7 @@ public class PersistedBTree extend // Write the modified page on disk // Note that we don't use the holder, the new root page will // remain in memory. - PageHolder holder = recordManager.writePage( this, modifiedPage, revision ); + PageHolder holder = writePage( modifiedPage, revision ); // Store the offset on disk in the page in memory ( ( AbstractPage ) modifiedPage ).setOffset( ( ( PersistedPageHolder ) holder ) @@ -430,7 +431,7 @@ public class PersistedBTree extend // Write the modified page on disk // Note that we don't use the holder, the new root page will // remain in memory. - PageHolder holder = recordManager.writePage( this, modifiedPage, revision ); + writePage( modifiedPage, revision ); // The root has just been modified, we haven't split it // Get it and make it the current root page @@ -451,17 +452,16 @@ public class PersistedBTree extend // If the BTree is managed, we have to write the two pages that were created // and to keep a track of the two offsets for the upper node - PageHolder holderLeft = recordManager.writePage( this, leftPage, revision ); + PageHolder holderLeft = writePage( leftPage, revision ); - PageHolder holderRight = recordManager.writePage( this, rightPage, revision ); + PageHolder holderRight = writePage( rightPage, revision ); // Create the new rootPage newRootPage = new PersistedNode( this, revision, pivot, holderLeft, holderRight ); // If the BTree is managed, we now have to write the page on disk // and to add this page to the list of modified pages - PageHolder holder = recordManager - .writePage( this, newRootPage, revision ); + PageHolder holder = writePage( newRootPage, revision ); rootPage = newRootPage; } @@ -475,16 +475,19 @@ public class PersistedBTree extend // If the BTree is managed, we have to update the rootPage on disk // Update the RecordManager header - recordManager.updateRecordManagerHeader(); + if ( ( writeTransaction == null ) || !writeTransaction.isStarted() ) + { + recordManager.updateRecordManagerHeader(); - // Update the BTree header now - recordManager.updateBtreeHeader( this, ( ( AbstractPage ) rootPage ).getOffset() ); + // Update the BTree header now + recordManager.updateBtreeHeader( this, ( ( AbstractPage ) rootPage ).getOffset() ); - // Moved the free pages into the list of free pages - recordManager.addFreePages( this, result.getCopiedPages() ); + // Moved the free pages into the list of free pages + recordManager.addFreePages( this, result.getCopiedPages() ); - // Store the created rootPage into the revision BTree, this will be stored in RecordManager only if revisions are set to keep - recordManager.storeRootPage( this, rootPage ); + // Store the created rootPage into the revision BTree, this will be stored in RecordManager only if revisions are set to keep + recordManager.storeRootPage( this, rootPage ); + } // Return the value we have found if it was modified return result; @@ -533,6 +536,29 @@ public class PersistedBTree extend /** + * Write a page either in the pending pages if the transaction is started, + * or directly on disk. + */ + private PageHolder writePage( Page modifiedPage, long revision ) throws IOException + { + if ( ( writeTransaction != null ) && writeTransaction.isStarted() ) + { + Map, BTree> pendingPages = recordManager.getPendingPages(); + pendingPages.put( modifiedPage, this ); + + PageHolder pageHolder = new PageHolder( this, modifiedPage ); + + return pageHolder; + } + else + { + PageHolder pageHolder = recordManager.writePage( this, modifiedPage, revision ); + + return pageHolder; + } + } + + /** * Get the rootPzge associated to a give revision. * * @param revision The revision we are looking for Modified: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java?rev=1552574&r1=1552573&r2=1552574&view=diff ============================================================================== --- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java (original) +++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java Fri Dec 20 09:58:42 2013 @@ -104,7 +104,7 @@ import java.util.List; super( btree, revision, 1 ); // Create the children array, and store the left and right children - children = ( PersistedPageHolder[] ) Array.newInstance( PersistedPageHolder.class, + children = ( PageHolder[] ) Array.newInstance( PageHolder.class, btree.getPageSize() + 1 ); children[0] = leftPage; Modified: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java?rev=1552574&r1=1552573&r2=1552574&view=diff ============================================================================== --- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java (original) +++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java Fri Dec 20 09:58:42 2013 @@ -170,6 +170,8 @@ public class RecordManager /** A flag used by internal btrees */ public static final boolean NORMAL_BTREE = false; + /** A map of pending pages */ + private Map, BTree> pendingPages = new LinkedHashMap, BTree>(); /** * Create a Record manager which will either create the underlying file @@ -3032,6 +3034,15 @@ public class RecordManager /** + * @return the pendingPages + */ + /* no qualifier*/ Map, BTree> getPendingPages() + { + return pendingPages; + } + + + /** * @see Object#toString() */ public String toString() Modified: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/WriteTransaction.java URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/WriteTransaction.java?rev=1552574&r1=1552573&r2=1552574&view=diff ============================================================================== --- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/WriteTransaction.java (original) +++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/WriteTransaction.java Fri Dec 20 09:58:42 2013 @@ -19,6 +19,8 @@ */ package org.apache.directory.mavibot.btree; +import java.io.IOException; +import java.util.Map; import java.util.concurrent.locks.ReentrantLock; import org.apache.directory.mavibot.btree.exception.BadTransactionStateException; @@ -62,6 +64,38 @@ import org.apache.directory.mavibot.btre throw new BadTransactionStateException( "Cannot commit a write transaction when it's not started" ); } + Map pendingPages = recordManager.getPendingPages(); + + for ( Object object : pendingPages.keySet() ) + { + BTree btree = (BTree)pendingPages.get( object ); + + try + { + recordManager.writePage( btree, (Page)object, ((Page)object).getRevision() ); + } + catch ( IOException e ) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /* + recordManager.updateRecordManagerHeader(); + + // Update the BTree header now + recordManager.updateBtreeHeader( btree, ( ( AbstractPage ) rootPage ).getOffset() ); + + // Moved the free pages into the list of free pages + recordManager.addFreePages( this, result.getCopiedPages() ); + + // Store the created rootPage into the revision BTree, this will be stored in RecordManager only if revisions are set to keep + recordManager.storeRootPage( this, rootPage ); + */ + + pendingPages.clear(); + writeLock.unlock(); } @@ -75,4 +109,14 @@ import org.apache.directory.mavibot.btre writeLock.unlock(); } + + + /** + * Tells if the transaction has started + * @return true if the transaction has started + */ + /* no qualifier */ boolean isStarted() + { + return writeLock.isLocked(); + } } Added: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeTransactionTest.java URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeTransactionTest.java?rev=1552574&view=auto ============================================================================== --- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeTransactionTest.java (added) +++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeTransactionTest.java Fri Dec 20 09:58:42 2013 @@ -0,0 +1,142 @@ +/* + * 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.File; +import java.io.IOException; +import java.util.UUID; + +import org.apache.directory.mavibot.btree.serializer.LongSerializer; +import org.apache.directory.mavibot.btree.serializer.StringSerializer; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +/** + * Test the PersistedBTree with transaction + * + * @author Apache Directory Project + */ +public class PersistedBTreeTransactionTest +{ + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + private File dataDirWithTxn = null; + private File dataDirNoTxn = null; + private BTree btreeWithTransactions = null; + private BTree btreeNoTransactions = null; + private RecordManager recordManagerTxn = null; + private RecordManager recordManagerNoTxn = null; + + + @Before + public void createBTree() + { + dataDirWithTxn = tempFolder.newFolder( UUID.randomUUID().toString() ); + dataDirNoTxn = tempFolder.newFolder( UUID.randomUUID().toString() ); + + openRecordManagerAndBtrees(); + + try + { + // Create a new BTree with transaction and another one without + btreeWithTransactions = recordManagerTxn.addBTree( "testWithTxn", new LongSerializer(), new StringSerializer(), false ); + btreeNoTransactions = recordManagerNoTxn.addBTree( "testNoTxn", new LongSerializer(), new StringSerializer(), false ); + } + catch ( Exception e ) + { + throw new RuntimeException( e ); + } + } + + + private void openRecordManagerAndBtrees() + { + try + { + if ( recordManagerTxn != null ) + { + recordManagerTxn.close(); + } + + if ( recordManagerNoTxn != null ) + { + recordManagerNoTxn.close(); + } + + // Now, try to reload the file back + recordManagerTxn = new RecordManager( dataDirWithTxn.getAbsolutePath() ); + recordManagerNoTxn = new RecordManager( dataDirNoTxn.getAbsolutePath() ); + + // load the last created btree + if ( btreeWithTransactions != null ) + { + btreeWithTransactions = recordManagerTxn.getManagedTree( btreeWithTransactions.getName() ); + } + + if ( btreeNoTransactions != null ) + { + btreeNoTransactions = recordManagerNoTxn.getManagedTree( btreeNoTransactions.getName() ); + } + } + catch ( Exception e ) + { + throw new RuntimeException( e ); + } + } + + + @Test + public void testWithoutTransaction() throws IOException + { + long t0 = System.currentTimeMillis(); + + for ( long i = 0L; i < 1000L; i++ ) + { + btreeNoTransactions.insert( i, Long.toString( i ) ); + } + + long t1 = System.currentTimeMillis(); + + System.out.println( "Delta without transaction for 100K elements = " + ( t1 - t0 ) ); + } + + + @Test + @Ignore("Fails atm") + public void testWithTransaction() throws IOException + { + long t0 = System.currentTimeMillis(); + + for ( long i = 0L; i < 1000L; i++ ) + { + System.out.println( i ); + btreeWithTransactions.beginTransaction(); + btreeWithTransactions.insert( i, Long.toString( i ) ); + btreeWithTransactions.commit(); + } + + long t1 = System.currentTimeMillis(); + + System.out.println( "Delta with transaction for 100K elements = " + ( t1 - t0 ) ); + } +}