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 2012/02/02 13:38:42 UTC
svn commit: r1239581 [9/9] - in /directory/apacheds/trunk/jdbm2: ./ src/
src/etc/ src/examples/ src/main/ src/main/java/ src/main/java/jdbm/
src/main/java/jdbm/btree/ src/main/java/jdbm/helper/
src/main/java/jdbm/htree/ src/main/java/jdbm/recman/ src/s...
Added: directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestBTreeBrowser.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestBTreeBrowser.java?rev=1239581&view=auto
==============================================================================
--- directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestBTreeBrowser.java (added)
+++ directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestBTreeBrowser.java Thu Feb 2 12:38:39 2012
@@ -0,0 +1,430 @@
+/*
+ * 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 jdbm.btree;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import jdbm.RecordManager;
+import jdbm.RecordManagerFactory;
+import jdbm.helper.StringComparator;
+import jdbm.helper.Tuple;
+import jdbm.helper.TupleBrowser;
+import jdbm.recman.SnapshotRecordManager;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+
+import com.mycila.junit.concurrent.Concurrency;
+import com.mycila.junit.concurrent.ConcurrentJunitRunner;
+
+
+/**
+ * Tests proper function of {@link TupleBrowser} and {@link BPage.Browser}
+ * when structural changes happen on the BTree.
+ */
+@RunWith(ConcurrentJunitRunner.class)
+@Concurrency()
+public class TestBTreeBrowser
+{
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ private RecordManager recordManager;
+ private SnapshotRecordManager snapshotRecman;
+ private BTree<String, String> tree;
+ private Tuple<String, String> tuple;
+
+
+ private String getTemporaryFile( String name ) throws IOException
+ {
+ String file = folder.newFile( name ).getAbsolutePath();
+ return file;
+ }
+
+
+ @Before
+ public void setup() throws IOException
+ {
+ tuple = new Tuple<String, String>();
+ recordManager = RecordManagerFactory.createRecordManager( getTemporaryFile( "testBrowser" ) );
+ snapshotRecman = new SnapshotRecordManager( recordManager, 1 << 12 );
+ tree = new BTree<String, String>( snapshotRecman, new StringComparator() );
+ tree.setPageSize( 4 );
+
+ // insert different objects and retrieve them
+ tree.insert( "test15", "value1", false );
+ tree.insert( "test25", "value2", false );
+ tree.insert( "test35", "value3", false );
+ tree.insert( "test45", "value4", false );
+ tree.insert( "test55", "value5", false );
+ tree.insert( "test65", "value6", false );
+ }
+
+
+ @After
+ public void teardown() throws IOException
+ {
+ recordManager.close();
+ }
+
+
+ /**
+ * Test the browser.
+ */
+ @Test
+ public void testBrowse() throws IOException
+ {
+ TupleBrowser<String, String> browser = tree.browse();
+
+ int count = 0;
+ while ( browser.getNext( tuple ) )
+ {
+ count++;
+ }
+ assertEquals( 6, count );
+
+ count = 0;
+ while ( browser.getPrevious( tuple ) )
+ {
+ count++;
+ }
+ assertEquals( 6, count );
+ }
+
+
+ @Test
+ public void testBrowseWithRemoveFirstBeforeStart() throws IOException
+ {
+ TupleBrowser<String, String> browser = tree.browse();
+
+ tree.remove( "test15" );
+ tree.remove( "test55" );
+
+ // removed tuples should still be visible
+ assertHasNext( browser, "test15", "value1" );
+ assertHasNext( browser, "test25", "value2" );
+ assertHasNext( browser, "test35", "value3" );
+ assertHasNext( browser, "test45", "value4" );
+ assertHasNext( browser, "test55", "value5" );
+ assertHasNext( browser, "test65", "value6" );
+ assertFalse( browser.getNext( tuple ) );
+
+ tree.remove( "test65" );
+ tree.remove( "test35" );
+
+ // removed tuples should still be visible
+ assertHasPrevious( browser, "test65", "value6" );
+ assertHasPrevious( browser, "test55", "value5" );
+ assertHasPrevious( browser, "test45", "value4" );
+ assertHasPrevious( browser, "test35", "value3" );
+ assertHasPrevious( browser, "test25", "value2" );
+ assertHasPrevious( browser, "test15", "value1" );
+ assertFalse( browser.getPrevious( tuple ) );
+ }
+
+
+ @Test
+ public void testBrowseWithInsertFirstBeforeStart() throws IOException
+ {
+ TupleBrowser<String, String> browser = tree.browse();
+
+ tree.insert( "test11", "value1", false );
+ tree.insert( "test59", "value5", false );
+
+ // inserted tuples should not be visible
+ assertHasNext( browser, "test15", "value1" );
+ assertHasNext( browser, "test25", "value2" );
+ assertHasNext( browser, "test35", "value3" );
+ assertHasNext( browser, "test45", "value4" );
+ assertHasNext( browser, "test55", "value5" );
+ assertHasNext( browser, "test65", "value6" );
+ assertFalse( browser.getNext( tuple ) );
+
+ tree.insert( "test29", "value2", false );
+ tree.insert( "test69", "value6", false );
+
+ // inserted tuples should not be visible
+ assertHasPrevious( browser, "test65", "value6" );
+ assertHasPrevious( browser, "test55", "value5" );
+ assertHasPrevious( browser, "test45", "value4" );
+ assertHasPrevious( browser, "test35", "value3" );
+ assertHasPrevious( browser, "test25", "value2" );
+ assertHasPrevious( browser, "test15", "value1" );
+ assertFalse( browser.getPrevious( tuple ) );
+ }
+
+
+ @Test
+ public void testBrowseWithRemoveFirstWhileBrowsing() throws IOException
+ {
+ TupleBrowser<String, String> browser = tree.browse();
+
+ assertHasNext( browser, "test15", "value1" );
+ assertHasNext( browser, "test25", "value2" );
+ assertHasNext( browser, "test35", "value3" );
+
+ tree.remove( "test15" );
+
+ assertHasNext( browser, "test45", "value4" );
+ assertHasNext( browser, "test55", "value5" );
+ assertHasNext( browser, "test65", "value6" );
+ assertFalse( browser.getNext( tuple ) );
+
+ assertHasPrevious( browser, "test65", "value6" );
+ assertHasPrevious( browser, "test55", "value5" );
+
+ tree.remove( "test65" );
+
+ assertHasPrevious( browser, "test45", "value4" );
+ assertHasPrevious( browser, "test35", "value3" );
+ assertHasPrevious( browser, "test25", "value2" );
+ assertHasPrevious( browser, "test15", "value1" );
+ assertFalse( browser.getPrevious( tuple ) );
+ }
+
+
+ @Test
+ public void testBrowseWithInsertFirstWhileBrowsing() throws IOException
+ {
+ TupleBrowser<String, String> browser = tree.browse();
+
+ assertHasNext( browser, "test15", "value1" );
+ assertHasNext( browser, "test25", "value2" );
+ assertHasNext( browser, "test35", "value3" );
+
+ tree.insert( "test11", "value1", false );
+
+ assertHasNext( browser, "test45", "value4" );
+ assertHasNext( browser, "test55", "value5" );
+ assertHasNext( browser, "test65", "value6" );
+ assertFalse( browser.getNext( tuple ) );
+
+ assertHasPrevious( browser, "test65", "value6" );
+ assertHasPrevious( browser, "test55", "value5" );
+
+ tree.insert( "test69", "value6", false );
+
+ assertHasPrevious( browser, "test45", "value4" );
+ assertHasPrevious( browser, "test35", "value3" );
+ assertHasPrevious( browser, "test25", "value2" );
+ assertHasPrevious( browser, "test15", "value1" );
+ assertFalse( browser.getPrevious( tuple ) );
+ }
+
+
+ @Test
+ public void testBrowseWithRemovePreviousWhileBrowsing() throws IOException
+ {
+ TupleBrowser<String, String> browser = tree.browse();
+
+ assertHasNext( browser, "test15", "value1" );
+ assertHasNext( browser, "test25", "value2" );
+ assertHasNext( browser, "test35", "value3" );
+
+ tree.remove( "test35" );
+
+ assertHasNext( browser, "test45", "value4" );
+ assertHasNext( browser, "test55", "value5" );
+ assertHasNext( browser, "test65", "value6" );
+ assertFalse( browser.getNext( tuple ) );
+
+ assertHasPrevious( browser, "test65", "value6" );
+ assertHasPrevious( browser, "test55", "value5" );
+
+ tree.remove( "test55" );
+
+ assertHasPrevious( browser, "test45", "value4" );
+ assertHasPrevious( browser, "test35", "value3" );
+ assertHasPrevious( browser, "test25", "value2" );
+ assertHasPrevious( browser, "test15", "value1" );
+ assertFalse( browser.getPrevious( tuple ) );
+ }
+
+
+ @Test
+ public void testBrowseWithInsertPreviousWhileBrowsing() throws IOException
+ {
+ TupleBrowser<String, String> browser = tree.browse();
+
+ assertHasNext( browser, "test15", "value1" );
+ assertHasNext( browser, "test25", "value2" );
+ assertHasNext( browser, "test35", "value3" );
+
+ tree.insert( "test29", "value2", false );
+
+ assertHasNext( browser, "test45", "value4" );
+ assertHasNext( browser, "test55", "value5" );
+ assertHasNext( browser, "test65", "value6" );
+ assertFalse( browser.getNext( tuple ) );
+
+ assertHasPrevious( browser, "test65", "value6" );
+ assertHasPrevious( browser, "test55", "value5" );
+
+ tree.insert( "test59", "value5", false );
+
+ assertHasPrevious( browser, "test45", "value4" );
+ assertHasPrevious( browser, "test35", "value3" );
+ assertHasPrevious( browser, "test25", "value2" );
+ assertHasPrevious( browser, "test15", "value1" );
+ assertFalse( browser.getPrevious( tuple ) );
+ }
+
+
+ @Test
+ public void testBrowseWithRemoveNextWhileBrowsing() throws IOException
+ {
+ TupleBrowser<String, String> browser = tree.browse();
+
+ assertHasNext( browser, "test15", "value1" );
+ assertHasNext( browser, "test25", "value2" );
+ assertHasNext( browser, "test35", "value3" );
+
+ tree.remove( "test45" );
+
+ assertHasNext( browser, "test45", "value4" );
+ assertHasNext( browser, "test55", "value5" );
+ assertHasNext( browser, "test65", "value6" );
+ assertFalse( browser.getNext( tuple ) );
+
+ assertHasPrevious( browser, "test65", "value6" );
+ assertHasPrevious( browser, "test55", "value5" );
+ assertHasPrevious( browser, "test45", "value4" );
+
+ tree.remove( "test35" );
+
+ assertHasPrevious( browser, "test35", "value3" );
+ assertHasPrevious( browser, "test25", "value2" );
+ assertHasPrevious( browser, "test15", "value1" );
+ assertFalse( browser.getPrevious( tuple ) );
+ }
+
+
+ @Test
+ public void testBrowseWithInsertNextWhileBrowsing() throws IOException
+ {
+ TupleBrowser<String, String> browser = tree.browse();
+
+ assertHasNext( browser, "test15", "value1" );
+ assertHasNext( browser, "test25", "value2" );
+ assertHasNext( browser, "test35", "value3" );
+
+ tree.insert( "test39", "value3", false );
+
+ assertHasNext( browser, "test45", "value4" );
+ assertHasNext( browser, "test55", "value5" );
+ assertHasNext( browser, "test65", "value6" );
+ assertFalse( browser.getNext( tuple ) );
+
+ assertHasPrevious( browser, "test65", "value6" );
+ assertHasPrevious( browser, "test55", "value5" );
+ assertHasPrevious( browser, "test45", "value4" );
+
+ tree.insert( "test41", "value4", false );
+
+ assertHasPrevious( browser, "test35", "value3" );
+ assertHasPrevious( browser, "test25", "value2" );
+ assertHasPrevious( browser, "test15", "value1" );
+ assertFalse( browser.getPrevious( tuple ) );
+ }
+
+
+ @Test
+ public void testBrowseWithRemoveLastWhileBrowsing() throws IOException
+ {
+ TupleBrowser<String, String> browser = tree.browse();
+
+ assertHasNext( browser, "test15", "value1" );
+ assertHasNext( browser, "test25", "value2" );
+ assertHasNext( browser, "test35", "value3" );
+
+ tree.remove( "test65" );
+
+ assertHasNext( browser, "test45", "value4" );
+ assertHasNext( browser, "test55", "value5" );
+ assertHasNext( browser, "test65", "value6" );
+ assertFalse( browser.getNext( tuple ) );
+
+ assertHasPrevious( browser, "test65", "value6" );
+ assertHasPrevious( browser, "test55", "value5" );
+ assertHasPrevious( browser, "test45", "value4" );
+
+ tree.remove( "test15" );
+
+ assertHasPrevious( browser, "test35", "value3" );
+ assertHasPrevious( browser, "test25", "value2" );
+ assertHasPrevious( browser, "test15", "value1" );
+ assertFalse( browser.getPrevious( tuple ) );
+ }
+
+
+ @Test
+ public void testBrowseWithInsertLastWhileBrowsing() throws IOException
+ {
+ TupleBrowser<String, String> browser = tree.browse();
+
+ assertHasNext( browser, "test15", "value1" );
+ assertHasNext( browser, "test25", "value2" );
+ assertHasNext( browser, "test35", "value3" );
+
+ tree.insert( "test69", "value6", false );
+
+ assertHasNext( browser, "test45", "value4" );
+ assertHasNext( browser, "test55", "value5" );
+ assertHasNext( browser, "test65", "value6" );
+ assertFalse( browser.getNext( tuple ) );
+
+ assertHasPrevious( browser, "test65", "value6" );
+ assertHasPrevious( browser, "test55", "value5" );
+ assertHasPrevious( browser, "test45", "value4" );
+
+ tree.insert( "test11", "value1", false );
+
+ assertHasPrevious( browser, "test35", "value3" );
+ assertHasPrevious( browser, "test25", "value2" );
+ assertHasPrevious( browser, "test15", "value1" );
+ assertFalse( browser.getPrevious( tuple ) );
+ }
+
+
+ private void assertHasNext( TupleBrowser<String, String> browser, String key, String value ) throws IOException
+ {
+ assertTrue( browser.getNext( tuple ) );
+ assertEquals( key, tuple.getKey() );
+ assertEquals( value, tuple.getValue() );
+ }
+
+
+ private void assertHasPrevious( TupleBrowser<String, String> browser, String key, String value ) throws IOException
+ {
+ assertTrue( browser.getPrevious( tuple ) );
+ assertEquals( key, tuple.getKey() );
+ assertEquals( value, tuple.getValue() );
+ }
+
+}
Added: directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestSnapshotBTree.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestSnapshotBTree.java?rev=1239581&view=auto
==============================================================================
--- directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestSnapshotBTree.java (added)
+++ directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestSnapshotBTree.java Thu Feb 2 12:38:39 2012
@@ -0,0 +1,607 @@
+/*
+ * 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 jdbm.btree;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Random;
+import java.util.concurrent.Semaphore;
+
+import jdbm.RecordManager;
+import jdbm.RecordManagerFactory;
+import jdbm.helper.IntegerComparator;
+import jdbm.helper.Tuple;
+import jdbm.helper.TupleBrowser;
+import jdbm.recman.SnapshotRecordManager;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ *
+ * TODO SnapshotBTree.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class TestSnapshotBTree
+{
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ private static class IntWrapper implements Serializable
+ {
+ int value;
+ IntWrapper( int value )
+ {
+ this.value = value;
+ }
+ }
+
+ private String getTemporaryFile( String name ) throws IOException
+ {
+ String file = folder.newFile( name ).getAbsolutePath();
+ return file;
+ }
+
+ @Test
+ public void testBasic1() throws IOException, InterruptedException
+ {
+ RecordManager recman;
+ BTree<Integer, IntWrapper> tree;
+
+ int idx;
+ int numReadThreads = 1;
+ BasicTestThread readThreads[] = new BasicTestThread[numReadThreads];
+ BasicTestThread updateThread;
+
+ Semaphore browseSem = new Semaphore( 0 );
+ Semaphore updateSem = new Semaphore( 0 );
+
+ recman = RecordManagerFactory.createRecordManager( getTemporaryFile( "testBasic1" ) );
+ SnapshotRecordManager snapshotRecman = new SnapshotRecordManager( recman, 1 << 12 );
+
+ tree = new BTree<Integer, IntWrapper>( snapshotRecman, new IntegerComparator() );
+
+ for ( idx = 0; idx < 1024; idx++ )
+ {
+ tree.insert( new Integer( idx ), new IntWrapper( idx ), true );
+ }
+
+ for ( idx = 0; idx < numReadThreads; idx++ )
+ {
+ readThreads[idx] = new BasicTestThread( true, tree, browseSem, updateSem, numReadThreads );
+ }
+ updateThread = new BasicTestThread( false, tree, browseSem, updateSem, numReadThreads );
+
+ updateThread.start();
+
+ for ( idx = 0; idx < numReadThreads; idx++ )
+ {
+ readThreads[idx].start();
+ }
+
+ for ( idx = 0; idx < numReadThreads; idx++ )
+ {
+ readThreads[idx].join();
+ }
+ updateThread.join();
+
+ snapshotRecman.close();
+ }
+
+
+
+
+ class BasicTestThread extends Thread
+ {
+ boolean readOnly;
+ BTree<Integer, IntWrapper> btree;
+ Semaphore browseSem;
+ Semaphore updateSem;
+ int numReadThreads;
+
+ BasicTestThread( boolean readOnly, BTree<Integer, IntWrapper> btree, Semaphore firstBrowse,
+ Semaphore updateDone, int numReadThreads )
+ {
+ this.readOnly = readOnly;
+ this.btree = btree;
+ this.browseSem = firstBrowse;
+ this.updateSem = updateDone;
+ this.numReadThreads = numReadThreads;
+ }
+
+
+
+ private void readOnlyActions() throws IOException, InterruptedException
+ {
+ int count = 0;
+ int idx;
+ TupleBrowser<Integer, IntWrapper> browser = btree.browse();
+ Tuple<Integer, IntWrapper> tuple = new Tuple();
+ browseSem.release();
+
+ assertTrue( browser.getNext( tuple ) );
+ assertEquals( tuple.getKey().intValue(), 0 );
+ count++;
+
+ assertTrue( browser.getNext( tuple ) );
+ assertEquals( tuple.getKey().intValue(), 1 );
+ count++;
+
+ while( browser.getNext( tuple ) )
+ {
+ count++;
+
+ // Sleep a little randomly.
+ if ( (count & 7) == 0 )
+ {
+ Thread.sleep( 1 );
+ }
+
+ assertTrue( tuple.getValue().value != -1 );
+ }
+
+
+ System.out.println( "count is " + count );
+ assertEquals( count, 1024 );
+ browser.close();
+
+ updateSem.acquireUninterruptibly();
+ browser = btree.browse( new Integer( 10 ) );
+
+ browseSem.release();
+
+ for ( idx = 20; idx < 1024; idx++ )
+ {
+ assertTrue( browser.getNext( tuple ) );
+
+ //System.out.println( "key:"+ tuple.getKey().intValue() + " idx:" + idx );
+ assertTrue( tuple.getKey().intValue() == idx );
+ }
+
+ browser.close();
+ }
+
+ private void readWriteActions() throws IOException
+ {
+ int idx;
+
+ for ( idx = 0; idx < numReadThreads; idx++ )
+ {
+ browseSem.acquireUninterruptibly();
+ }
+
+
+ Integer key = new Integer( 1023 );
+ IntWrapper value = btree.find( key );
+ value = new IntWrapper( -1 );
+ btree.insert( key, value, true );
+
+ key = new Integer(46);
+ value = btree.find( key );
+ value = new IntWrapper( -1 );
+
+ btree.insert( key, value , true );
+ for ( idx = 1024; idx < 2048; idx++ )
+ {
+ btree.insert( new Integer( idx ), new IntWrapper( idx ), true );
+ }
+
+ key = new Integer(1);
+ value = btree.find( key );
+ value = new IntWrapper( -1 );
+
+ btree.insert( key, value , true );
+ btree.insert( new Integer(1024), new IntWrapper( -1 ), true );
+
+ for ( idx = 10; idx < 20; idx++ )
+ {
+ btree.remove( new Integer( idx ) );
+ }
+
+ updateSem.release();
+
+ for ( idx = 0; idx < numReadThreads; idx++ )
+ {
+ browseSem.acquireUninterruptibly();
+ }
+
+ for ( idx = 0; idx < 10; idx++ )
+ {
+ btree.remove( new Integer( idx ) );
+ }
+
+ for ( idx = 20; idx < 1024; idx++ )
+ {
+ btree.remove( new Integer( idx ) );
+ }
+ }
+
+
+ public void run()
+ {
+ try
+ {
+ if ( readOnly )
+ {
+ this.readOnlyActions();
+ }
+ else
+ {
+ this.readWriteActions();
+ }
+ }
+ catch( IOException e )
+ {
+ e.printStackTrace();
+ assertTrue( false );
+ }
+ catch( InterruptedException e )
+ {
+ e.printStackTrace();
+ assertTrue( false );
+ }
+
+ }
+ } // end of class BasicTestThread
+
+
+ @Test
+ public void testLongBrowsing() throws IOException, InterruptedException
+ {
+ RecordManager recman;
+ BTree<Integer, IntWrapper> tree;
+ int numElements = 10000;
+
+ int idx;
+ int numReadThreads = 4;
+ LongBrowsingTestThread readThreads[] = new LongBrowsingTestThread[numReadThreads];
+ LongBrowsingTestThread updateThread;
+
+ recman = RecordManagerFactory.createRecordManager( getTemporaryFile( "testLongBrowsing" ) );
+ SnapshotRecordManager snapshotRecman = new SnapshotRecordManager( recman, 1 << 10 );
+
+ tree = new BTree<Integer, IntWrapper>( snapshotRecman, new IntegerComparator() );
+
+ for ( idx = 0; idx < numElements; idx++ )
+ {
+ tree.insert( new Integer( idx ), new IntWrapper( 0 ), true );
+ }
+
+ for ( idx = 0; idx < numReadThreads; idx++ )
+ {
+ readThreads[idx] = new LongBrowsingTestThread( true, tree, numElements);
+ }
+ updateThread = new LongBrowsingTestThread( false, tree, numElements );
+
+
+ readThreads[0].start();
+
+ Thread.sleep( 10 );
+
+ updateThread.start();
+
+ for ( idx = 1; idx < numReadThreads; idx++ )
+ {
+ Thread.sleep( 1000 );
+ readThreads[idx].start();
+ }
+
+ for ( idx = 0; idx < numReadThreads; idx++ )
+ {
+ readThreads[idx].join();
+ }
+
+ updateThread.join();
+
+ snapshotRecman.close();
+ }
+
+ class LongBrowsingTestThread extends Thread
+ {
+ boolean readOnly;
+ BTree<Integer, IntWrapper> btree;
+ int numElements;
+
+
+ LongBrowsingTestThread( boolean readOnly, BTree<Integer, IntWrapper> btree, int numElements)
+ {
+ this.readOnly = readOnly;
+ this.btree = btree;
+ this.numElements = numElements;
+ }
+
+
+
+ private void readOnlyActions() throws IOException, InterruptedException
+ {
+ int count = 0;
+ TupleBrowser<Integer, IntWrapper> browser = btree.browse();
+ Tuple<Integer, IntWrapper> tuple = new Tuple();
+
+ assertTrue( browser.getNext( tuple ) );
+ int max = tuple.getValue().value;
+ count++;
+ System.out.println( " TestLongBrowsing read thread min key is" + tuple.getKey() + "max value is" + max );
+
+ while( browser.getNext( tuple ) )
+ {
+ count++;
+
+ // Sleep for a while to keep browsing long
+ Thread.sleep( 10 );
+
+
+ if ( tuple.getValue().value > max )
+ {
+ System.out.println(" tupe value:" + tuple.getValue().value + " Expected max:" + max + " count:" + count);
+
+ }
+
+ assertTrue( tuple.getValue().value <= max );
+
+ }
+
+
+ System.out.println( "TestLongBrowsing read thread count is " + count );
+ assertEquals( count, numElements );
+ browser.close();
+ }
+
+ private void readWriteActions()
+ {
+ int idx;
+ Random updateRandomizer = new Random();
+
+ try
+ {
+ for ( idx = 1; idx < 100; idx++ )
+ {
+ Integer key = new Integer( 0 );
+ IntWrapper value = btree.find( key );
+ value = new IntWrapper( idx );
+ btree.insert( key, value, true );
+
+ for ( int updates = 0; updates < 2048; updates++ )
+ {
+ key = new Integer( updateRandomizer.nextInt( numElements ) );
+ value = btree.find( key );
+
+ assertTrue( value.value <= idx );
+
+ value = new IntWrapper( idx );
+ btree.insert( key, value, true );
+ }
+ }
+
+ System.out.println( "TestLongBrowsing updates ended" );
+
+ }
+ catch( IOException e )
+ {
+ e.printStackTrace();
+ assertTrue( false );
+ }
+ }
+
+
+ public void run()
+ {
+ try
+ {
+ if ( readOnly )
+ {
+ this.readOnlyActions();
+ }
+ else
+ {
+ this.readWriteActions();
+ }
+ }
+ catch( IOException e )
+ {
+ e.printStackTrace();
+ assertTrue( false );
+ }
+ catch( InterruptedException e )
+ {
+ e.printStackTrace();
+ assertTrue( false );
+ }
+
+ }
+ } // end of class LongBrowsingTestThread
+
+
+
+ @Test
+ public void testRemoveInsert() throws IOException, InterruptedException
+ {
+ RecordManager recman;
+ BTree<Integer, IntWrapper> tree;
+ int numElements = 10000;
+
+ int idx;
+ int numReadThreads = 4;
+ RemoveInsertTestThread readThreads[] = new RemoveInsertTestThread[numReadThreads];
+ RemoveInsertTestThread updateThread;
+
+ Semaphore browseSem = new Semaphore( 0 );
+
+ recman = RecordManagerFactory.createRecordManager( getTemporaryFile( "testRemoveInsert" ) );
+ SnapshotRecordManager snapshotRecman = new SnapshotRecordManager( recman, 1 << 12 );
+
+ tree = new BTree<Integer, IntWrapper>( snapshotRecman, new IntegerComparator() );
+
+ for ( idx = 0; idx < numElements; idx++ )
+ {
+ tree.insert( new Integer( idx ), new IntWrapper( 0 ), true );
+ }
+
+ for ( idx = 0; idx < numReadThreads; idx++ )
+ {
+ readThreads[idx] = new RemoveInsertTestThread( true, tree, numElements, browseSem, numReadThreads );
+ }
+ updateThread = new RemoveInsertTestThread( false, tree, numElements, browseSem, numReadThreads );
+
+
+ updateThread.start();
+
+ for ( idx = 0; idx < numReadThreads; idx++ )
+ {
+ Thread.sleep( 1000 );
+ readThreads[idx].start();
+ }
+
+ for ( idx = 0; idx < numReadThreads; idx++ )
+ {
+ readThreads[idx].join();
+ }
+ updateThread.join();
+
+ snapshotRecman.close();
+ }
+
+
+
+ class RemoveInsertTestThread extends Thread
+ {
+ boolean readOnly;
+ BTree<Integer, IntWrapper> btree;
+ int numElements;
+ Semaphore browseSem;
+ int numReadThreads;
+
+ RemoveInsertTestThread( boolean readOnly, BTree<Integer, IntWrapper> btree, int numElements, Semaphore browseSem, int numReadThreads )
+ {
+ this.readOnly = readOnly;
+ this.btree = btree;
+ this.numElements = numElements;
+ this.browseSem = browseSem;
+ this.numReadThreads = numReadThreads;
+ }
+
+ private void readOnlyActions() throws IOException, InterruptedException
+ {
+ int count = 0;
+ TupleBrowser<Integer, IntWrapper> browser = btree.browse();
+ Tuple<Integer, IntWrapper> tuple = new Tuple();
+
+ browseSem.release();
+
+ while( browser.getNext( tuple ) )
+ {
+ count++;
+
+ // Sleep for a while to keep browsing long
+ Thread.sleep( 10 );
+
+
+ if ( tuple.getValue().value == -1 )
+ {
+ System.out.println(" tupe key:" + tuple.getKey() + " value:" + tuple.getValue().value);
+
+ }
+
+ assertTrue( tuple.getValue().value != -1 );
+ }
+
+
+ System.out.println( "TestRemoveInsert read thread count is " + count );
+ assertEquals( count, numElements );
+ browser.close();
+ }
+
+ private void readWriteActions() throws IOException, InterruptedException
+ {
+ int idx;
+ Random updateRandomizer = new Random();
+
+ for ( idx = 0; idx < numReadThreads; idx++ )
+ {
+ browseSem.acquireUninterruptibly();
+ }
+
+
+ Integer key;
+ IntWrapper value = new IntWrapper( -1 );
+
+ for ( idx = 0; idx < 10; idx++ )
+ {
+ Thread.sleep( 10000 );
+
+ int startingIndex = updateRandomizer.nextInt( numElements );
+
+ for ( int updates = 0; updates < 32; updates++ )
+ {
+ key = new Integer( startingIndex + updates );
+
+ if ( key.intValue() >= numElements )
+ {
+ break;
+ }
+
+ btree.remove( key );
+ }
+
+ for ( int updates = 0; updates < 32; updates++ )
+ {
+ key = new Integer( startingIndex + updates );
+ btree.insert( key, value, true );
+ }
+ }
+
+ System.out.println( "TestRemoveInsert updates ended" );
+
+ }
+
+
+ public void run()
+ {
+ try
+ {
+ if ( readOnly )
+ {
+ this.readOnlyActions();
+ }
+ else
+ {
+ this.readWriteActions();
+ }
+ }
+ catch( IOException e )
+ {
+ e.printStackTrace();
+ assertTrue( false );
+ }
+ catch( InterruptedException e )
+ {
+ e.printStackTrace();
+ assertTrue( false );
+ }
+
+
+ }
+ } // end of class RemoveInsertTestThread
+}
\ No newline at end of file
Added: directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestStreamCorrupted.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestStreamCorrupted.java?rev=1239581&view=auto
==============================================================================
--- directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestStreamCorrupted.java (added)
+++ directory/apacheds/trunk/jdbm2/src/test/java/jdbm/btree/TestStreamCorrupted.java Thu Feb 2 12:38:39 2012
@@ -0,0 +1,141 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ * statements and notices. Redistributions must also contain a
+ * copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. The name "JDBM" must not be used to endorse or promote
+ * products derived from this Software without prior written
+ * permission of Cees de Groot. For written permission,
+ * please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ * nor may "JDBM" appear in their names without prior written
+ * permission of Cees de Groot.
+ *
+ * 5. Due credit should be given to the JDBM Project
+ * (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ */
+package jdbm.btree;
+
+
+import java.io.IOException;
+
+import jdbm.RecordManager;
+import jdbm.RecordManagerFactory;
+import jdbm.helper.StringComparator;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Contributed test case for BTree by Christof Dallermassl (cdaller@iicm.edu):
+ *
+ * -= quote from original message posted on jdbm-general =-
+ * <pre>
+ *
+ * I tried to insert a couple of elements into a BTree and then remove
+ * them one by one. After a number or removals, there is always (if more
+ * than 20 elements in btree) a java.io.StreamCorruptedException thrown.
+ *
+ * The strange thing is, that on 50 elements, the exception is thrown
+ * after removing 22, on 200 it is thrown after 36, on 1000 it is thrown
+ * after 104, on 10000 it is thrown after 1003....
+ *
+ * The full stackTrace is here:
+ * ---------------------- snip ------- snap -------------------------
+ * java.io.StreamCorruptedException: Caught EOFException while reading the
+ * stream header
+ * at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:845)
+ * at java.io.ObjectInputStream.<init>(ObjectInputStream.java:168)
+ * at jdbm.recman.RecordManager.byteArrayToObject(RecordManager.java:296)
+ * at jdbm.recman.RecordManager.fetchObject(RecordManager.java:239)
+ * at jdbm.helper.ObjectCache.fetchObject(ObjectCache.java:104)
+ * at jdbm.btree.BPage.loadBPage(BPage.java:670)
+ * at jdbm.btree.BPage.remove(BPage.java:492)
+ * at jdbm.btree.BPage.remove(BPage.java:437)
+ * at jdbm.btree.BTree.remove(BTree.java:313)
+ * at JDBMTest.main(JDBMTest.java:41)
+ *
+ * </pre>
+ *
+ * @author <a href="mailto:cdaller@iicm.edu">Christof Dallermassl</a>
+ */
+public class TestStreamCorrupted
+{
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+
+ private String getTemporaryFile( String name ) throws IOException
+ {
+ String file = folder.newFile( name ).getAbsolutePath();
+ return file;
+ }
+
+
+ /**
+ * Basic tests
+ */
+ @Test
+ public void testStreamCorrupted() throws IOException
+ {
+ RecordManager recman;
+ BTree<String, Integer> btree;
+ int iterations;
+
+ iterations = 100; // 23 works :-(((((
+
+ // open database
+ recman = RecordManagerFactory.createRecordManager( getTemporaryFile( "test" ) );
+
+ // create a new B+Tree data structure
+ btree = new BTree<String, Integer>( recman, new StringComparator() );
+ recman.setNamedObject( "testbtree", btree.getRecordId() );
+
+ // action:
+ // insert data
+ for( int count = 0; count < iterations; count++ )
+ {
+ btree.insert( "num" + count, Integer.valueOf( count ), true );
+ }
+
+ // delete data
+ for( int count = 0; count < iterations; count++ )
+ {
+ btree.remove( "num" + count );
+ }
+
+ // close database
+ recman.close();
+ recman = null;
+ }
+}
Added: directory/apacheds/trunk/jdbm2/src/test/java/jdbm/helper/TestActionVersioning.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm2/src/test/java/jdbm/helper/TestActionVersioning.java?rev=1239581&view=auto
==============================================================================
--- directory/apacheds/trunk/jdbm2/src/test/java/jdbm/helper/TestActionVersioning.java (added)
+++ directory/apacheds/trunk/jdbm2/src/test/java/jdbm/helper/TestActionVersioning.java Thu Feb 2 12:38:39 2012
@@ -0,0 +1,77 @@
+/*
+ * 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 jdbm.helper;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.mycila.junit.concurrent.Concurrency;
+import com.mycila.junit.concurrent.ConcurrentJunitRunner;
+
+/**
+ *
+ * TODO TestActionVersioning.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+@RunWith(ConcurrentJunitRunner.class)
+@Concurrency()
+public class TestActionVersioning
+{
+ @Test
+ public void testVersioning()
+ {
+ ActionVersioning.Version version1, version2;
+ ActionVersioning.Version writeVersion;
+ ActionVersioning.Version minVersion;
+
+ ActionVersioning versioning = new ActionVersioning();
+ version1 = versioning.beginReadAction();
+ assertEquals( version1.getVersion(), 0 );
+
+ writeVersion = versioning.beginWriteAction();
+ assertEquals( writeVersion.getVersion(), 1 );
+
+ version2 = versioning.beginReadAction();
+ assertEquals( version2.getVersion(), 0 );
+
+ minVersion = versioning.endWriteAction();
+ assertEquals( minVersion.getVersion(), 0 );
+
+ writeVersion = versioning.beginWriteAction();
+ assertEquals( writeVersion.getVersion(), 2 );
+
+ minVersion = versioning.endWriteAction();
+ assertEquals( minVersion.getVersion(), 0 );
+
+ versioning.endReadAction( version1 );
+ minVersion = versioning.endReadAction( version2 );
+ assertEquals( minVersion.getVersion(), 2 );
+
+ version1 = versioning.beginReadAction();
+ assertEquals( version1.getVersion(), 2 );
+
+ minVersion = versioning.endReadAction( version1 );
+ assertEquals( minVersion, null );
+
+ }
+}
\ No newline at end of file
Added: directory/apacheds/trunk/jdbm2/src/test/java/jdbm/helper/TestVersionedCache.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm2/src/test/java/jdbm/helper/TestVersionedCache.java?rev=1239581&view=auto
==============================================================================
--- directory/apacheds/trunk/jdbm2/src/test/java/jdbm/helper/TestVersionedCache.java (added)
+++ directory/apacheds/trunk/jdbm2/src/test/java/jdbm/helper/TestVersionedCache.java Thu Feb 2 12:38:39 2012
@@ -0,0 +1,271 @@
+/*
+ * 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 jdbm.helper;
+
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.mycila.junit.concurrent.Concurrency;
+import com.mycila.junit.concurrent.ConcurrentJunitRunner;
+
+/**
+ *
+ * TODO TestVersionedCache.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+@RunWith(ConcurrentJunitRunner.class)
+@Concurrency()
+public class TestVersionedCache
+{
+ private int expectedSum;
+ static final int THREAD_NUMBER = 5;
+
+
+ @Test
+ public void testBasics() throws IOException, CacheEvictionException
+ {
+ int idx;
+ int numEntries = 1024;
+ Integer intsArray[] = new Integer[numEntries];
+
+ for ( idx = 0; idx < numEntries; idx++ )
+ {
+ intsArray[idx] = new Integer( 1 );
+ }
+
+ ArrayEntryIO arrayIO = new ArrayEntryIO(intsArray);
+
+ LRUCache<Integer, Integer> cache = new LRUCache<Integer, Integer>( arrayIO, numEntries );
+
+ Integer val = cache.get( new Integer ( 5 ), 0, null, false );
+ assertEquals( val.intValue(), 1 );
+
+ val = cache.get( new Integer ( 20 ), 0, null, false );
+ assertEquals( val.intValue(), 1 );
+
+ cache.put( new Integer(1), 2, 1, null, false );
+ cache.put( new Integer(5), 2, 1, null, false );
+ cache.put( new Integer(30), 2, 1, null, false );
+
+ int sum = 0;
+ for ( idx = 0; idx < numEntries; idx++ )
+ {
+ sum += cache.get( new Integer( idx ), 0, null, false ).intValue();
+ }
+
+ assertEquals( sum, numEntries );
+
+ sum = 0;
+ cache.advanceMinReadVersion( 1 );
+ for ( idx = 0; idx < numEntries; idx++ )
+ {
+ sum += cache.get( new Integer( idx ), 1, null, false ).intValue();
+ }
+
+ System.out.println( "Sum is: "+ sum);
+ assertEquals( sum, ( numEntries + 3 ) );
+
+ }
+
+ @Test
+ public void testMultiThreadedAccess() throws IOException, CacheEvictionException
+ {
+ int idx;
+ int numEntries = 1024;
+ Integer intsArray[] = new Integer[numEntries];
+
+ for ( idx = 0; idx < numEntries; idx++ )
+ {
+ intsArray[idx] = new Integer( 1 );
+ }
+
+ ArrayEntryIO arrayIO = new ArrayEntryIO(intsArray, 10, 20);
+
+ LRUCache<Integer, Integer> cache = new LRUCache<Integer, Integer>( arrayIO, numEntries );
+
+ TestThread[] threadPool = new TestThread[THREAD_NUMBER];
+
+ // create content for the tree, different content for different threads!
+ for ( int threadCount = 0; threadCount < THREAD_NUMBER; threadCount++ )
+ {
+ if ( threadCount == ( THREAD_NUMBER - 1 ) )
+ threadPool[threadCount] = new TestThread( false, intsArray, cache );
+ else
+ threadPool[threadCount] = new TestThread( true, intsArray, cache );
+
+ threadPool[threadCount].start();
+ }
+
+ // wait until the threads really stop:
+ try
+ {
+ for ( int threadCount = 0; threadCount < THREAD_NUMBER; threadCount++ )
+ {
+ threadPool[threadCount].join();
+ }
+ }
+ catch ( InterruptedException ignore )
+ {
+ ignore.printStackTrace();
+ }
+
+ int sum = 0;
+ cache.advanceMinReadVersion( 2 );
+ for ( idx = 0; idx < intsArray.length; idx++ )
+ {
+ sum += cache.get( new Integer( idx ), 2, null, false ).intValue();
+ }
+
+ assertEquals( sum, expectedSum );
+
+
+ }
+
+
+ private class ArrayEntryIO implements EntryIO<Integer, Integer>
+ {
+ Integer intsArray[];
+ int readSleepTime;
+ int writeSleepTime;
+
+ public ArrayEntryIO( Integer intsArray[] )
+ {
+ this.intsArray = intsArray;
+ }
+
+ public ArrayEntryIO( Integer intsArray[], int readSleepTIme, int writeSleepTime )
+ {
+ this.intsArray = intsArray;
+ this.readSleepTime = readSleepTime;
+ this.writeSleepTime = writeSleepTime;
+ }
+
+ public Integer read( Integer key, Serializer serializer) throws IOException
+ {
+ if ( readSleepTime != 0 )
+ {
+ try
+ {
+ Thread.sleep( readSleepTime );
+ }
+ catch ( InterruptedException e )
+ {
+ // ignore
+ }
+ }
+
+ return intsArray[key.intValue()];
+ }
+
+ public void write( Integer key, Integer value, Serializer serializer ) throws IOException
+ {
+ if ( writeSleepTime != 0 )
+ {
+ try
+ {
+ Thread.sleep( writeSleepTime );
+ }
+ catch ( InterruptedException e )
+ {
+ // ignore
+ }
+ }
+
+ intsArray[key.intValue()] = value;
+ }
+ }
+
+
+ class TestThread extends Thread
+ {
+ boolean readOnly;
+ Integer intsArray[];
+ LRUCache<Integer, Integer> cache;
+
+ TestThread( boolean readOnly, Integer intsArray[] , LRUCache<Integer, Integer> cache)
+ {
+ this.readOnly = readOnly;
+ this.intsArray = intsArray;
+ this.cache = cache;
+ }
+
+
+
+ private void action() throws IOException, CacheEvictionException
+ {
+ int idx;
+ int sum = 0;
+ if ( readOnly )
+ {
+
+ for ( idx = 0; idx < intsArray.length; idx++ )
+ {
+ sum += cache.get( new Integer( idx ), 0, null, false ).intValue();
+ }
+
+ assertEquals( sum, intsArray.length );
+ }
+ else
+ {
+ expectedSum = intsArray.length;
+
+ for ( idx = 0; idx <= intsArray.length; idx = idx + 100)
+ {
+ cache.put( new Integer( idx ), 2, 1, null, false );
+ expectedSum = expectedSum + 1;
+ }
+
+ for ( idx = 0; idx <= intsArray.length; idx = idx + 100)
+ {
+ cache.put( new Integer( idx ), 3, 2, null, false );
+ expectedSum = expectedSum + 1;
+ }
+
+ for ( idx = 0; idx < intsArray.length; idx++ )
+ {
+ sum += cache.get( new Integer( idx ), 2, null, false ).intValue();
+ }
+
+ assertEquals( sum, expectedSum );
+ }
+ }
+
+
+ public void run()
+ {
+ try
+ {
+ this.action();
+ }
+ catch ( IOException e)
+ {
+ }
+ catch ( CacheEvictionException e)
+ {
+ }
+ }
+ } // end of class TestThread
+}
\ No newline at end of file
Added: directory/apacheds/trunk/jdbm2/src/test/java/jdbm/recman/BlockIoTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm2/src/test/java/jdbm/recman/BlockIoTest.java?rev=1239581&view=auto
==============================================================================
--- directory/apacheds/trunk/jdbm2/src/test/java/jdbm/recman/BlockIoTest.java (added)
+++ directory/apacheds/trunk/jdbm2/src/test/java/jdbm/recman/BlockIoTest.java Thu Feb 2 12:38:39 2012
@@ -0,0 +1,217 @@
+/*
+ * 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 jdbm.recman;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class BlockIoTest
+{
+ BlockIo blockIo;
+ BlockIo blockIoData;
+
+ @Before
+ public void init()
+ {
+ blockIo = new BlockIo( 0L, new byte[1024] );
+
+ // Init the blockIo with 1024 bytes from 0x00 to 0xFF, 4 times
+ for ( int i = 0; i < 1024; i++ )
+ {
+ blockIo.writeByte( i, (byte)( i & 0x00fff ) );
+ }
+
+ blockIoData = new BlockIo( 0L, new byte[1024] );
+ blockIoData.writeLong( 0, 0x8081828384858687L );
+ blockIoData.writeInt( 8, 0x000000ff );
+
+ for ( int i = 0; i < 256; i++ )
+ {
+ blockIoData.writeByte( 12+i, (byte)0x80 );
+ }
+ }
+
+
+ @Test
+ public void testReadByte()
+ {
+ assertEquals( (byte)0x00, blockIo.readByte( 0 ) );
+ assertEquals( (byte)0xff, blockIo.readByte( 1023 ) );
+
+ try
+ {
+ blockIo.readByte( -1 );
+ fail();
+ }
+ catch ( ArrayIndexOutOfBoundsException aioobe )
+ {
+ // Expected
+ }
+
+ try
+ {
+ blockIo.readByte( 1024 );
+ fail();
+ }
+ catch ( ArrayIndexOutOfBoundsException aioobe )
+ {
+ // Expected
+ }
+ }
+
+
+ @Test
+ public void testReadInt()
+ {
+ assertEquals( 0x00010203, blockIo.readInt( 0 ) );
+ assertEquals( 0x7c7d7e7f, blockIo.readInt( 124 ) );
+ assertEquals( 0x7d7e7f80, blockIo.readInt( 125 ) );
+ assertEquals( 0x7e7f8081, blockIo.readInt( 126 ) );
+ assertEquals( 0x7f808182, blockIo.readInt( 127 ) );
+ assertEquals( 0x80818283, blockIo.readInt( 128 ) );
+ assertEquals( 0xfbfcfdfe, blockIo.readInt( 1019 ) );
+ assertEquals( 0xfcfdfeff, blockIo.readInt( 1020 ) );
+
+ try
+ {
+ blockIo.readInt( -1 );
+ fail();
+ }
+ catch ( ArrayIndexOutOfBoundsException aioobe )
+ {
+ // Expected
+ }
+
+ try
+ {
+ blockIo.readInt( 1021 );
+ fail();
+ }
+ catch ( ArrayIndexOutOfBoundsException aioobe )
+ {
+ // Expected
+ }
+
+ try
+ {
+ blockIo.readInt( 1024 );
+ fail();
+ }
+ catch ( ArrayIndexOutOfBoundsException aioobe )
+ {
+ // Expected
+ }
+ }
+
+
+ @Test
+ public void testReadShort()
+ {
+ assertEquals( 0x0001, blockIo.readShort( 0 ) );
+ assertEquals( 0x7c7d, blockIo.readShort( 124 ) );
+ assertEquals( 0x7d7e, blockIo.readShort( 125 ) );
+ assertEquals( 0x7e7f, blockIo.readShort( 126 ) );
+ assertEquals( 0x7f80, blockIo.readShort( 127 ) );
+ assertEquals( (short)0x8081, blockIo.readShort( 128 ) );
+ assertEquals( (short)0xfdfe, blockIo.readShort( 1021 ) );
+ assertEquals( (short)0xfeff, blockIo.readShort( 1022 ) );
+
+ try
+ {
+ blockIo.readShort( -1 );
+ fail();
+ }
+ catch ( ArrayIndexOutOfBoundsException aioobe )
+ {
+ // Expected
+ }
+
+ try
+ {
+ blockIo.readShort( 1023 );
+ fail();
+ }
+ catch ( ArrayIndexOutOfBoundsException aioobe )
+ {
+ // Expected
+ }
+
+ try
+ {
+ blockIo.readShort( 1024 );
+ fail();
+ }
+ catch ( ArrayIndexOutOfBoundsException aioobe )
+ {
+ // Expected
+ }
+ }
+
+
+ @Test
+ public void testReadLong()
+ {
+ assertEquals( 0x0001020304050607L, blockIo.readLong( 0 ) );
+ assertEquals( 0x78797a7b7c7d7e7fL, blockIo.readLong( 120 ) );
+ assertEquals( 0x797a7b7c7d7e7f80L, blockIo.readLong( 121 ) );
+ assertEquals( 0x7a7b7c7d7e7f8081L, blockIo.readLong( 122 ) );
+ assertEquals( 0x7b7c7d7e7f808182L, blockIo.readLong( 123 ) );
+ assertEquals( 0x7c7d7e7f80818283L, blockIo.readLong( 124 ) );
+ assertEquals( 0x7d7e7F8081828384L, blockIo.readLong( 125 ) );
+ assertEquals( 0x7e7f808182838485L, blockIo.readLong( 126 ) );
+ assertEquals( 0x7f80818283848586L, blockIo.readLong( 127 ) );
+ assertEquals( 0x8081828384858687L, blockIo.readLong( 128 ) );
+ assertEquals( 0xf7f8f9fafbfcfdfeL, blockIo.readLong( 1015 ) );
+ assertEquals( 0xf8f9fafbfcfdfeffL, blockIo.readLong( 1016 ) );
+
+ try
+ {
+ blockIo.readLong( -1 );
+ fail();
+ }
+ catch ( ArrayIndexOutOfBoundsException aioobe )
+ {
+ // Expected
+ }
+
+ try
+ {
+ blockIo.readLong( 1017 );
+ fail();
+ }
+ catch ( ArrayIndexOutOfBoundsException aioobe )
+ {
+ // Expected
+ }
+
+ try
+ {
+ blockIo.readLong( 1024 );
+ fail();
+ }
+ catch ( ArrayIndexOutOfBoundsException aioobe )
+ {
+ // Expected
+ }
+ }
+}
Added: directory/apacheds/trunk/jdbm2/src/test/java/jdbm/recman/LocationTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm2/src/test/java/jdbm/recman/LocationTest.java?rev=1239581&view=auto
==============================================================================
--- directory/apacheds/trunk/jdbm2/src/test/java/jdbm/recman/LocationTest.java (added)
+++ directory/apacheds/trunk/jdbm2/src/test/java/jdbm/recman/LocationTest.java Thu Feb 2 12:38:39 2012
@@ -0,0 +1,148 @@
+/*
+ * 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 jdbm.recman;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import com.mycila.junit.concurrent.Concurrency;
+import com.mycila.junit.concurrent.ConcurrentJunitRunner;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Unit tests class LocationEntry.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+@RunWith(ConcurrentJunitRunner.class)
+@Concurrency()
+public class LocationTest
+{
+ private static Location clonedServerEntryA;
+ private static Location clonedServerEntryACopy;
+ private static Location clonedServerEntryB;
+ private static Location clonedServerEntryA1;
+ private static Location clonedServerEntryACopy1;
+ private static Location clonedServerEntryB1;
+ private static Location clonedServerEntryC1;
+ private static Location clonedServerEntryD1;
+
+
+ /**
+ * Initialize name instances
+ */
+ @BeforeClass
+ public static void initNames() throws Exception
+ {
+ clonedServerEntryA = new Location( 1L );
+ clonedServerEntryACopy = new Location( 1L );
+ clonedServerEntryB = new Location( 1L );
+ clonedServerEntryA1 = new Location( 1L, ( short ) 1 );
+ clonedServerEntryACopy1 = new Location( 1L, ( short ) 1 );
+ clonedServerEntryB1 = new Location( 1L, ( short ) 1 );
+ clonedServerEntryC1 = new Location( 1L, ( short ) 2 );
+ clonedServerEntryD1 = new Location( 2L, ( short ) 1 );
+ }
+
+
+ @Test
+ public void testEqualsNull() throws Exception
+ {
+ assertFalse( clonedServerEntryA.equals( null ) );
+ assertFalse( clonedServerEntryA1.equals( null ) );
+ }
+
+
+ @Test
+ public void testEqualsReflexive() throws Exception
+ {
+ assertEquals( clonedServerEntryA, clonedServerEntryA );
+ assertEquals( clonedServerEntryA1, clonedServerEntryA1 );
+ }
+
+
+ @Test
+ public void testHashCodeReflexive() throws Exception
+ {
+ assertEquals( clonedServerEntryA.hashCode(), clonedServerEntryA.hashCode() );
+ assertEquals( clonedServerEntryA1.hashCode(), clonedServerEntryA1.hashCode() );
+ }
+
+
+ @Test
+ public void testEqualsSymmetric() throws Exception
+ {
+ assertEquals( clonedServerEntryA, clonedServerEntryACopy );
+ assertEquals( clonedServerEntryACopy, clonedServerEntryA );
+ assertEquals( clonedServerEntryA1, clonedServerEntryACopy1 );
+ assertEquals( clonedServerEntryACopy1, clonedServerEntryA1 );
+ }
+
+
+ @Test
+ @Ignore
+ public void testHashCodeSymmetric() throws Exception
+ {
+ assertEquals( clonedServerEntryA.hashCode(), clonedServerEntryACopy.hashCode() );
+ assertEquals( clonedServerEntryACopy.hashCode(), clonedServerEntryA.hashCode() );
+ assertEquals( clonedServerEntryA1.hashCode(), clonedServerEntryACopy1.hashCode() );
+ assertEquals( clonedServerEntryACopy1.hashCode(), clonedServerEntryA1.hashCode() );
+ }
+
+
+ @Test
+ public void testEqualsTransitive() throws Exception
+ {
+ assertEquals( clonedServerEntryA, clonedServerEntryACopy );
+ assertEquals( clonedServerEntryACopy, clonedServerEntryB );
+ assertEquals( clonedServerEntryA, clonedServerEntryB );
+ assertEquals( clonedServerEntryA1, clonedServerEntryACopy1 );
+ assertEquals( clonedServerEntryACopy1, clonedServerEntryB1 );
+ assertEquals( clonedServerEntryA1, clonedServerEntryB1 );
+ }
+
+
+ @Test
+ @Ignore
+ public void testHashCodeTransitive() throws Exception
+ {
+ assertEquals( clonedServerEntryA.hashCode(), clonedServerEntryACopy.hashCode() );
+ assertEquals( clonedServerEntryACopy.hashCode(), clonedServerEntryB.hashCode() );
+ assertEquals( clonedServerEntryA.hashCode(), clonedServerEntryB.hashCode() );
+ assertEquals( clonedServerEntryA1.hashCode(), clonedServerEntryACopy1.hashCode() );
+ assertEquals( clonedServerEntryACopy1.hashCode(), clonedServerEntryB1.hashCode() );
+ assertEquals( clonedServerEntryA1.hashCode(), clonedServerEntryB1.hashCode() );
+ }
+
+
+ @Test
+ public void testNotEqualDiffValue() throws Exception
+ {
+ assertFalse( clonedServerEntryA1.equals( clonedServerEntryC1 ) );
+ assertFalse( clonedServerEntryC1.equals( clonedServerEntryA1 ) );
+ assertFalse( clonedServerEntryA1.equals( clonedServerEntryD1 ) );
+ assertFalse( clonedServerEntryD1.equals( clonedServerEntryA1 ) );
+ }
+}
Added: directory/apacheds/trunk/jdbm2/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm2/src/test/resources/log4j.properties?rev=1239581&view=auto
==============================================================================
--- directory/apacheds/trunk/jdbm2/src/test/resources/log4j.properties (added)
+++ directory/apacheds/trunk/jdbm2/src/test/resources/log4j.properties Thu Feb 2 12:38:39 2012
@@ -0,0 +1,22 @@
+#############################################################################
+# 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.
+#############################################################################
+log4j.rootCategory=ERROR, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %p [%c] - %m%n
+