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;
21 private static void p() { System.out.println( " passed" ); }
22 private static void f() { System.out.println( " !!!FAILED!!!" ); }
24 private static void verify( Map<MultiKey, Integer> expected,
25 Map<MultiKey, Integer> actual ) {
26 if( expected.equals( actual ) ) {
30 System.out.println( "expected = "+expected );
31 System.out.println( "actual = "+actual );
36 public static void main(String[] args) {
38 int randomSeed = 12345;
39 if( args.length > 0 ) {
40 randomSeed = Integer.parseInt( args[0] );
42 random = new Random( randomSeed );
44 joinOp = new JoinOpInteger();
47 System.out.println("");
49 System.out.println("");
51 System.out.println("");
55 public static void testBuilder() {
56 System.out.println( "Testing MultiViewMapBuilder..." );
58 MultiViewMapBuilder builder;
61 builder = new MultiViewMapBuilder<Integer>( new Class[]{}, joinOp );
63 } catch( IllegalArgumentException expected ) {
65 } catch( Exception e ) {
71 new MultiViewMapBuilder<Integer>( new Class[]
78 } catch( Exception e ) {
84 new MultiViewMapBuilder<Integer>( new Class[]
92 // can't build a map with no views yet
95 } catch( Exception expected ) {
100 builder.addPartialView();
102 } catch( IllegalArgumentException expected ) {
104 } catch( Exception e ) {
109 // an index is out of bounds for this multikey (0-3)
110 builder.addPartialView( 1, 6 );
112 } catch( IllegalArgumentException expected ) {
114 } catch( Exception e ) {
119 // an index is out of bounds for this multikey (0-3)
120 builder.addPartialView( 2, -1, 3 );
122 } catch( IllegalArgumentException expected ) {
124 } catch( Exception e ) {
129 // an index is specified more than once
130 builder.addPartialView( 0, 3, 0 );
132 } catch( IllegalArgumentException expected ) {
134 } catch( Exception e ) {
139 // the full view is implicit
140 builder.addPartialView( 0, 1, 2, 3 );
142 } catch( IllegalArgumentException expected ) {
144 } catch( Exception e ) {
149 builder.addPartialView( 1, 3 );
151 } catch( Exception e ) {
156 builder.addPartialView( 0, 1, 3 );
158 } catch( Exception e ) {
164 builder.addPartialView( 1, 3 );
166 } catch( IllegalArgumentException expected ) {
168 } catch( Exception e ) {
171 System.out.println( "DONE" );
175 public static void testMap() {
176 System.out.println( "Testing MultiViewMap..." );
178 Map<MultiKey, Integer> expected;
180 MultiViewMapBuilder<Integer> builder =
181 new MultiViewMapBuilder<Integer>( new Class[]
182 {Integer.class, // key0
183 Boolean.class, // key1
184 String.class}, // key2
186 final BitSet view012 = builder.getFullView();
187 final BitSet view01 = builder.addPartialView( 0, 1 );
188 final BitSet view0 = builder.addPartialView( 0 );
189 final BitSet view2 = builder.addPartialView( 2 );
190 builder.setCheckTypes( true );
191 builder.setCheckConsistency( true );
193 MultiViewMap<Integer> mapA = builder.build();
196 // Simple put and remove
197 MultiKey partialKey4 = MultiKey.factory( 4 );
198 expected = new HashMap<MultiKey, Integer>();
199 verify( expected, mapA.get( view0, partialKey4 ) );
201 MultiKey vader = MultiKey.factory( 4, true, "Vader" );
202 mapA.put( vader, 1001 );
203 expected = new HashMap<MultiKey, Integer>();
204 expected.put( vader, 1001 );
205 verify( expected, mapA.get( view0, partialKey4 ) );
207 mapA.remove( view0, partialKey4 );
208 expected = new HashMap<MultiKey, Integer>();
209 verify( expected, mapA.get( view0, partialKey4 ) );
212 // Try across a merge
213 mapA.put( vader, 1001 );
214 expected = new HashMap<MultiKey, Integer>();
215 expected.put( vader, 1001 );
216 verify( expected, mapA.get( view0, partialKey4 ) );
218 MultiViewMap<Integer> mapB = builder.build();
219 expected = new HashMap<MultiKey, Integer>();
220 verify( expected, mapB.get( view0, partialKey4 ) );
223 expected = new HashMap<MultiKey, Integer>();
224 expected.put( vader, 1001 );
225 verify( expected, mapB.get( view0, partialKey4 ) );
228 // Remove the correct entries
229 MultiKey luke = MultiKey.factory( 5, true, "Luke" );
230 MultiKey han = MultiKey.factory( 4, true, "Han Solo" );
231 MultiKey r2 = MultiKey.factory( 4, false, "R2-D2" );
233 mapA.put( luke, 1002 );
234 mapA.put( han, 1003 );
235 mapA.put( r2, 1004 );
236 expected = new HashMap<MultiKey, Integer>();
237 expected.put( vader, 1001 );
238 expected.put( han, 1003 );
239 expected.put( r2, 1004 );
240 verify( expected, mapA.get( view0, partialKey4 ) );
242 // removes vader and han
243 MultiKey partialKey4true = MultiKey.factory( 4, true );
244 mapA.remove( view01, partialKey4true );
246 expected = new HashMap<MultiKey, Integer>();
247 expected.put( r2, 1004 );
248 verify( expected, mapA.get( view0, partialKey4 ) );
250 MultiKey partialKeyLuke = MultiKey.factory( "Luke" );
251 expected = new HashMap<MultiKey, Integer>();
252 expected.put( luke, 1002 );
253 verify( expected, mapA.get( view2, partialKeyLuke ) );
256 System.out.println( "DONE" );
260 public static void stressTest() {
261 System.out.println( "Stressing MultiViewMap..." );
263 // Just pound away with operations to see if we can crash anything.
265 MultiViewMapBuilder<Integer> builder =
266 new MultiViewMapBuilder<Integer>( new Class[]
267 {Integer.class, // key0
268 Boolean.class, // key1
269 String.class}, // key2
271 builder.setCheckTypes( true );
272 builder.setCheckConsistency( true );
274 Integer[] ints = new Integer[] {
278 Boolean[] bools = new Boolean[] {
279 true, false, false, // skew distribution
282 String[] strs = new String[] {
283 "Vader", "Han Solo", "R2-D2", "Luke", "Leia",
286 final BitSet view012 = builder.getFullView();
287 final BitSet view01 = builder.addPartialView( 0, 1 );
288 final BitSet view12 = builder.addPartialView( 1, 2 );
289 final BitSet view02 = builder.addPartialView( 0, 2 );
290 final BitSet view0 = builder.addPartialView( 0 );
291 final BitSet view1 = builder.addPartialView( 1 );
292 final BitSet view2 = builder.addPartialView( 2 );
294 // This might be the ugliest line of Java I've ever written. BARF
295 @SuppressWarnings({"unchecked"})
296 MultiViewMap<Integer>[] maps =
297 (MultiViewMap<Integer>[]) Array.newInstance( builder.build().getClass(), 8 );
299 for( int i = 0; i < maps.length; ++i ) {
300 maps[i] = builder.build();
304 System.out.println( " Number of full keys in each table per op cycle:" );
306 for( int reps = 0; reps < 100; ++reps ) {
307 int nextOp = random.nextInt( 100 );
309 System.out.print( " Op: " );
312 // put some new values in
313 System.out.print( "PT " );
314 int numNewValues = 1 + random.nextInt( 8 );
315 for( int i = 0; i < numNewValues; ++i ) {
316 MultiKey newKey = MultiKey.factory( getInt( ints ),
319 getMap( maps ).put( newKey, random.nextInt() );
322 } else if( nextOp < 70 ) {
323 // remove values by a random view
324 System.out.print( "RM " );
325 MultiViewMap<Integer> map = getMap( maps );
327 switch( random.nextInt( 6 ) ) {
328 case 0: { map.remove( view0, MultiKey.factory( getInt (ints ) ) ); } break;
329 case 1: { map.remove( view1, MultiKey.factory( getBool(bools) ) ); } break;
330 case 2: { map.remove( view2, MultiKey.factory( getStr (strs ) ) ); } break;
331 case 3: { map.remove( view01, MultiKey.factory( getInt (ints ), getBool(bools) ) ); } break;
332 case 4: { map.remove( view12, MultiKey.factory( getBool(bools), getStr (strs ) ) ); } break;
333 case 5: { map.remove( view02, MultiKey.factory( getInt (ints ), getStr (strs ) ) ); } break;
338 System.out.print( "MG " );
339 getMap( maps ).merge( getMap( maps ) );
342 for( int i = 0; i < maps.length - 1; ++i ) {
343 if( i < maps.length - 1 ) {
344 System.out.print( maps[i].size() + ", " );
347 System.out.println( maps[maps.length-1].size() );
350 System.out.println( "DONE" );
353 private static Integer getInt( Integer[] ints ) {
354 return ints[random.nextInt( ints.length )];
357 private static Boolean getBool( Boolean[] bools ) {
358 return bools[random.nextInt( bools.length )];
361 private static String getStr( String[] strs ) {
362 return strs[random.nextInt( strs.length )];
365 private static MultiViewMap<Integer> getMap( MultiViewMap<Integer>[] maps ) {
366 return maps[random.nextInt( maps.length )];