package org.jctools.maps.nbhs_test; import static org.hamcrest.CoreMatchers.anyOf; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Iterator; import org.jctools.maps.NonBlockingSetInt; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; /* * Written by Cliff Click and released to the public domain, as explained at * http://creativecommons.org/licenses/publicdomain */ // Test NonBlockingSetInt via JUnit public class nbsi_tester { static private NonBlockingSetInt _nbsi; @BeforeClass public static void setUp () { _nbsi = new NonBlockingSetInt(); } @AfterClass public static void tearDown() { _nbsi = null; } // Test some basic stuff; add a few keys, remove a few keys @Test public void testBasic() { assertTrue ( _nbsi.isEmpty() ); assertTrue ( _nbsi.add(1) ); checkSizes (1); assertTrue ( _nbsi.add(2) ); checkSizes (2); assertFalse( _nbsi.add(1) ); assertFalse( _nbsi.add(2) ); checkSizes (2); assertThat ( _nbsi.remove(1), is(true ) ); checkSizes (1); assertThat ( _nbsi.remove(1), is(false) ); assertTrue ( _nbsi.remove(2) ); checkSizes (0); assertFalse( _nbsi.remove(2) ); assertFalse( _nbsi.remove(3) ); assertTrue ( _nbsi.isEmpty() ); assertTrue ( _nbsi.add(63) ); checkSizes (1); assertTrue ( _nbsi.remove(63) ); assertFalse( _nbsi.remove(63) ); assertTrue ( _nbsi.isEmpty() ); assertTrue ( _nbsi.add(10000) ); checkSizes (1); assertTrue ( _nbsi.add(20000) ); checkSizes (2); assertFalse( _nbsi.add(10000) ); assertFalse( _nbsi.add(20000) ); checkSizes (2); assertThat ( _nbsi.remove(10000), is(true ) ); checkSizes (1); assertThat ( _nbsi.remove(10000), is(false) ); assertTrue ( _nbsi.remove(20000) ); checkSizes (0); assertFalse( _nbsi.remove(20000) ); _nbsi.clear(); } // Check all iterators for correct size counts private void checkSizes(int expectedSize) { assertEquals( "size()", _nbsi.size(), expectedSize ); Iterator it = _nbsi.iterator(); int result = 0; while (it.hasNext()) { result++; it.next(); } assertEquals( "iterator missed", expectedSize, result ); } @Test public void testIteration() { assertTrue ( _nbsi.isEmpty() ); assertTrue ( _nbsi.add(1) ); assertTrue ( _nbsi.add(2) ); StringBuilder buf = new StringBuilder(); for( Integer val : _nbsi ) buf.append(val); assertThat("found all vals",buf.toString(),anyOf(is("12"),is("21"))); assertThat("toString works",_nbsi.toString(), anyOf(is("[1, 2]"),is("[2, 1]"))); _nbsi.clear(); } @Test public void testIterationBig() { for( int i=0; i<100; i++ ) _nbsi.add(i); assertThat( _nbsi.size(), is(100) ); int sz =0; int sum = 0; for( Integer x : _nbsi ) { sz++; sum += x; assertTrue(x>=0 && x<=99); } assertThat("Found 100 ints",sz,is(100)); assertThat("Found all integers in list",sum,is(100*99/2)); assertThat( "can remove 3", _nbsi.remove(3), is(true) ); assertThat( "can remove 4", _nbsi.remove(4), is(true) ); sz =0; sum = 0; for( Integer x : _nbsi ) { sz++; sum += x; assertTrue(x>=0 && x<=99); } assertThat("Found 98 ints",sz,is(98)); assertThat("Found all integers in list",sum,is(100*99/2 - (3+4))); _nbsi.clear(); } @Test public void testSerial() { assertTrue ( _nbsi.isEmpty() ); assertTrue ( _nbsi.add(1) ); assertTrue ( _nbsi.add(2) ); // Serialize it out try { FileOutputStream fos = new FileOutputStream("NBSI_test.txt"); ObjectOutputStream out = new ObjectOutputStream(fos); out.writeObject(_nbsi); out.close(); } catch(IOException ex) { ex.printStackTrace(); } // Read it back try { File f = new File("NBSI_test.txt"); FileInputStream fis = new FileInputStream(f); ObjectInputStream in = new ObjectInputStream(fis); NonBlockingSetInt nbsi = (NonBlockingSetInt)in.readObject(); in.close(); assertEquals(_nbsi.toString(),nbsi.toString()); if( !f.delete() ) throw new IOException("delete failed"); } catch(IOException|ClassNotFoundException ex) { ex.printStackTrace(); } _nbsi.clear(); } // Do some simple concurrent testing @Test public void testConcurrentSimple() throws InterruptedException { final NonBlockingSetInt nbsi = new NonBlockingSetInt(); // In 2 threads, add & remove even & odd elements concurrently Thread t1 = new Thread() { public void run() { work_helper(nbsi,"T1",1); } }; t1.start(); work_helper(nbsi,"T0",1); t1.join(); // In the end, all members should be removed StringBuffer buf = new StringBuffer(); buf.append("Should be emptyset but has these elements: {"); boolean found = false; for( Integer x : nbsi ) { buf.append(" ").append(x); found = true; } if( found ) System.out.println(buf); assertThat( "concurrent size=0", nbsi.size(), is(0) ); for( Integer x : nbsi ) { assertTrue("No elements so never get here",false); } _nbsi.clear(); } void work_helper(NonBlockingSetInt nbsi, String thrd, int d) { final int ITERS = 100000; for( int j=0; j<10; j++ ) { //long start = System.nanoTime(); for( int i=d; i<ITERS; i+=2 ) nbsi.add(i); for( int i=d; i<ITERS; i+=2 ) nbsi.remove(i); //double delta_nanos = System.nanoTime()-start; //double delta_secs = delta_nanos/1000000000.0; //double ops = ITERS*2; //System.out.println("Thrd"+thrd+" "+(ops/delta_secs)+" ops/sec size="+nbsi.size()); } } }