1 package Util.UnitTests;
6 import java.util.HashSet;
7 import java.util.BitSet;
9 import java.util.HashMap;
10 import java.util.Random;
11 import java.lang.reflect.Array;
14 public class MultiViewMapTest {
16 private static JoinOpInteger joinOp;
18 private static Random random;
20 private static int numTests = 0;
21 private static int numPassed = 0;
23 private static void p() { numTests++; numPassed++; System.out.print( "." ); }
24 private static void f() { numTests++; System.out.println( "!!!FAILED!!!" ); }
26 private static void verify( Map<MultiKey, Integer> expected,
27 Map<MultiKey, Integer> actual ) {
28 if( expected.equals( actual ) ) {
32 System.out.println( "expected = "+expected );
33 System.out.println( "actual = "+actual );
38 public static void main(String[] args) {
40 int randomSeed = 12345;
41 if( args.length > 0 ) {
42 randomSeed = Integer.parseInt( args[0] );
44 random = new Random( randomSeed );
46 joinOp = new JoinOpInteger();
48 System.out.println("");
50 System.out.println("");
52 System.out.println("");
54 System.out.println("");
55 System.out.println(numPassed+"/"+numTests+" passed.");
59 public static void testBuilder() {
60 System.out.println( "Testing MultiViewMapBuilder..." );
62 MultiViewMapBuilder builder;
65 builder = new MultiViewMapBuilder<Integer>( new Class[]{}, joinOp );
67 } catch( IllegalArgumentException expected ) {
69 } catch( Exception e ) {
75 new MultiViewMapBuilder<Integer>( new Class[]
82 } catch( Exception e ) {
88 new MultiViewMapBuilder<Integer>( new Class[]
96 // can't build a map with no views yet
99 } catch( Exception expected ) {
104 builder.addPartialView();
106 } catch( IllegalArgumentException expected ) {
108 } catch( Exception e ) {
113 // an index is out of bounds for this multikey (0-3)
114 builder.addPartialView( 1, 6 );
116 } catch( IllegalArgumentException expected ) {
118 } catch( Exception e ) {
123 // an index is out of bounds for this multikey (0-3)
124 builder.addPartialView( 2, -1, 3 );
126 } catch( IllegalArgumentException expected ) {
128 } catch( Exception e ) {
133 // an index is specified more than once
134 builder.addPartialView( 0, 3, 0 );
136 } catch( IllegalArgumentException expected ) {
138 } catch( Exception e ) {
143 // the full view is implicit
144 builder.addPartialView( 0, 1, 2, 3 );
146 } catch( IllegalArgumentException expected ) {
148 } catch( Exception e ) {
153 builder.addPartialView( 1, 3 );
155 } catch( Exception e ) {
160 builder.addPartialView( 0, 1, 3 );
162 } catch( Exception e ) {
168 builder.addPartialView( 1, 3 );
170 } catch( IllegalArgumentException expected ) {
172 } catch( Exception e ) {
175 System.out.println( "DONE" );
179 public static void testMap() {
180 System.out.println( "Testing MultiViewMap..." );
182 Map<MultiKey, Integer> expected;
184 MultiViewMapBuilder<Integer> builder =
185 new MultiViewMapBuilder<Integer>( new Class[]
186 {Integer.class, // key0
187 Boolean.class, // key1
188 String.class}, // key2
190 final BitSet view012 = builder.getFullView();
191 final BitSet view01 = builder.addPartialView( 0, 1 );
192 final BitSet view0 = builder.addPartialView( 0 );
193 final BitSet view2 = builder.addPartialView( 2 );
194 builder.setCheckTypes( true );
195 builder.setCheckConsistency( true );
197 MultiViewMap<Integer> mapA = builder.build();
200 // Simple put and remove
201 MultiKey partialKey4 = MultiKey.factory( 4 );
202 expected = new HashMap<MultiKey, Integer>();
203 verify( expected, mapA.get( view0, partialKey4 ) );
205 MultiKey vader = MultiKey.factory( 4, true, "Vader" );
206 mapA.put( vader, 1001 );
207 expected = new HashMap<MultiKey, Integer>();
208 expected.put( vader, 1001 );
209 verify( expected, mapA.get( view0, partialKey4 ) );
211 mapA.remove( view0, partialKey4 );
212 expected = new HashMap<MultiKey, Integer>();
213 verify( expected, mapA.get( view0, partialKey4 ) );
216 // Try across a merge
217 mapA.put( vader, 1001 );
218 expected = new HashMap<MultiKey, Integer>();
219 expected.put( vader, 1001 );
220 verify( expected, mapA.get( view0, partialKey4 ) );
222 MultiViewMap<Integer> mapB = builder.build();
223 expected = new HashMap<MultiKey, Integer>();
224 verify( expected, mapB.get( view0, partialKey4 ) );
227 expected = new HashMap<MultiKey, Integer>();
228 expected.put( vader, 1001 );
229 verify( expected, mapB.get( view0, partialKey4 ) );
232 // Remove the correct entries
233 MultiKey luke = MultiKey.factory( 5, true, "Luke" );
234 MultiKey han = MultiKey.factory( 4, true, "Han Solo" );
235 MultiKey r2 = MultiKey.factory( 4, false, "R2-D2" );
237 mapA.put( luke, 1002 );
238 mapA.put( han, 1003 );
239 mapA.put( r2, 1004 );
240 expected = new HashMap<MultiKey, Integer>();
241 expected.put( vader, 1001 );
242 expected.put( han, 1003 );
243 expected.put( r2, 1004 );
244 verify( expected, mapA.get( view0, partialKey4 ) );
247 // Get for full keys didn't work in production,
248 // so test it explicitly
249 expected = new HashMap<MultiKey, Integer>();
250 expected.put( luke, 1002 );
251 verify( expected, mapA.get( view012, luke ) );
254 // removes vader and han
255 MultiKey partialKey4true = MultiKey.factory( 4, true );
256 mapA.remove( view01, partialKey4true );
258 expected = new HashMap<MultiKey, Integer>();
259 expected.put( r2, 1004 );
260 verify( expected, mapA.get( view0, partialKey4 ) );
262 MultiKey partialKeyLuke = MultiKey.factory( "Luke" );
263 expected = new HashMap<MultiKey, Integer>();
264 expected.put( luke, 1002 );
265 verify( expected, mapA.get( view2, partialKeyLuke ) );
268 System.out.println( "DONE" );
272 public static void stressTest() {
273 System.out.println( "Stressing MultiViewMap..." );
275 // Just pound away with operations to see if we can crash anything.
277 MultiViewMapBuilder<Integer> builder =
278 new MultiViewMapBuilder<Integer>( new Class[]
279 {Integer.class, // key0
280 Boolean.class, // key1
281 String.class}, // key2
283 builder.setCheckTypes( true );
284 builder.setCheckConsistency( true );
286 Integer[] ints = new Integer[] {
290 Boolean[] bools = new Boolean[] {
291 true, false, false, // skew distribution
294 String[] strs = new String[] {
295 "Vader", "Han Solo", "R2-D2", "Luke", "Leia",
298 final BitSet view012 = builder.getFullView();
299 final BitSet view01 = builder.addPartialView( 0, 1 );
300 final BitSet view12 = builder.addPartialView( 1, 2 );
301 final BitSet view02 = builder.addPartialView( 0, 2 );
302 final BitSet view0 = builder.addPartialView( 0 );
303 final BitSet view1 = builder.addPartialView( 1 );
304 final BitSet view2 = builder.addPartialView( 2 );
306 // This might be the ugliest line of Java I've ever written. BARF
307 @SuppressWarnings({"unchecked"})
308 MultiViewMap<Integer>[] maps =
309 (MultiViewMap<Integer>[]) Array.newInstance( builder.build().getClass(), 8 );
311 for( int i = 0; i < maps.length; ++i ) {
312 maps[i] = builder.build();
316 //System.out.println( " Number of full keys in each table per op cycle:" );
318 for( int reps = 0; reps < 100; ++reps ) {
319 int nextOp = random.nextInt( 100 );
321 //System.out.print( " Op: " );
324 // put some new values in
325 //System.out.print( "PT " );
326 int numNewValues = 1 + random.nextInt( 8 );
327 for( int i = 0; i < numNewValues; ++i ) {
328 MultiKey newKey = MultiKey.factory( getInt( ints ),
331 getMap( maps ).put( newKey, random.nextInt() );
334 } else if( nextOp < 70 ) {
335 // remove values by a random view
336 //System.out.print( "RM " );
337 MultiViewMap<Integer> map = getMap( maps );
339 switch( random.nextInt( 6 ) ) {
340 case 0: { map.remove( view0, MultiKey.factory( getInt (ints ) ) ); } break;
341 case 1: { map.remove( view1, MultiKey.factory( getBool(bools) ) ); } break;
342 case 2: { map.remove( view2, MultiKey.factory( getStr (strs ) ) ); } break;
343 case 3: { map.remove( view01, MultiKey.factory( getInt (ints ), getBool(bools) ) ); } break;
344 case 4: { map.remove( view12, MultiKey.factory( getBool(bools), getStr (strs ) ) ); } break;
345 case 5: { map.remove( view02, MultiKey.factory( getInt (ints ), getStr (strs ) ) ); } break;
350 //System.out.print( "MG " );
351 getMap( maps ).merge( getMap( maps ) );
354 for( int i = 0; i < maps.length - 1; ++i ) {
355 if( i < maps.length - 1 ) {
356 //System.out.print( maps[i].size() + ", " );
359 //System.out.println( maps[maps.length-1].size() );
362 System.out.println( "DONE" );
365 private static Integer getInt( Integer[] ints ) {
366 return ints[random.nextInt( ints.length )];
369 private static Boolean getBool( Boolean[] bools ) {
370 return bools[random.nextInt( bools.length )];
373 private static String getStr( String[] strs ) {
374 return strs[random.nextInt( strs.length )];
377 private static MultiViewMap<Integer> getMap( MultiViewMap<Integer>[] maps ) {
378 return maps[random.nextInt( maps.length )];