2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0.
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 package gov.nasa.jpf.util;
21 import gov.nasa.jpf.util.test.TestJPF;
22 import java.util.Arrays;
23 import java.util.BitSet;
24 import java.util.HashMap;
25 import java.util.Iterator;
27 import java.util.Random;
28 import org.junit.Test;
31 * regression test for PSIntMap
33 public class PSIntMapTest extends TestJPF {
35 PSIntMap<Integer> createPersistentIntMap(){
36 return new PSIntMap<Integer>();
39 PSIntMap<Integer> set (PSIntMap<Integer> m, int i){
40 return m.set(i, Integer.valueOf(i));
43 PSIntMap<Integer> set (PSIntMap<Integer> m, int[] data){
44 for (int i=0; i<data.length; i++){
47 m = m.set( v, Integer.valueOf(v));
55 static class IntegerProcessor implements Processor<Integer>{
59 public void process( Integer i){
61 System.out.print(',');
66 public int getCount(){
71 static void dump (String prefix, PSIntMap<Integer> map, String postfix){
73 System.out.print(prefix);
74 System.out.print(' ');
77 System.out.print(map.getClass().getSimpleName() + " {");
78 map.process( new IntegerProcessor());
79 System.out.print('}');
82 System.out.print(' ');
83 System.out.print(postfix);
87 static void dump (PSIntMap<Integer> map){
91 static void assertNullValue (PSIntMap<Integer> map, int key){
92 Integer v = map.get(key);
94 fail("non-null value for: " + key + " = " + v);
98 static void assertNonNullValue (PSIntMap<Integer> map, int key){
99 Integer v = map.get(key);
100 if (v == null || v.intValue() != key){
101 fail("wrong value for: " + key + " = " + v);
105 static void assertEquals( PSIntMap<Integer> map, int[] data){
106 int[] a = data.clone();
109 System.out.print("assertEquals {");
110 for (int i=0; i<data.length; i++){
112 System.out.print(',');
114 System.out.print(a[i]);
116 System.out.println('}');
118 assertTrue( map.size() == data.length);
120 int[] b = new int[data.length];
122 for (Integer v : map){
123 int i = v.intValue();
128 for (int i=0; i<a.length; i++){
130 fail("different values : " + a[i] + ',' + b[i]);
138 public void testSingleAdd(){
139 PSIntMap<Integer> m = createPersistentIntMap();
140 assertTrue( m.size() == 0);
143 dump("0: ", m, "\n");
144 assertTrue( m.size() == 1);
145 assertNonNullValue( m, 0);
146 assertNullValue( m, 42);
148 m = new PSIntMap<Integer>();
150 dump("42: ", m, "\n");
151 assertTrue( m.size() == 1);
152 assertNullValue( m, 0);
153 assertNonNullValue( m, 42);
155 int k = 32*32*32*32 + 1;
156 m = new PSIntMap<Integer>();
158 dump("32**4 + 1: ", m, "\n");
159 assertTrue( m.size() == 1);
160 assertNullValue( m, 0);
161 assertNonNullValue( m, k);
162 m.printOn(System.out);
166 public void testMultiAdd(){
167 PSIntMap<Integer> m = createPersistentIntMap();
169 int[] data = { 0,1, 32, 4,10, 666,669, 36, 37 };
173 //m.printOn(System.out);
175 assertEquals( m, data);
179 public void testConsecutiveAdd(){
181 PSIntMap<Integer> m = createPersistentIntMap();
182 for (int i=0; i<len; i++){
186 for (int i=0; i<len; i++){
187 Integer v = m.get(i);
188 assertNonNullValue( m, i);
191 System.out.println("m.size() = " + m.size());
192 assertTrue(m.size() == len);
196 public void testConsecutiveAddRemove(){
198 PSIntMap<Integer> m = createPersistentIntMap();
199 for (int i=0; i<len; i++){
203 for (int i=0; i<len; i++){
204 Integer v = m.get(i);
205 assertNonNullValue( m, i);
208 for (int i=len-1; i>= 0; i--){
212 System.out.println("m.size() = " + m.size());
213 assertTrue(m.size() == 0);
217 public void testPredicateRemoval(){
218 PSIntMap<Integer> m = createPersistentIntMap();
220 int[] data = { 0,1, 32, 4,10, 666,669, 36, 37, 95,97 };
223 dump("before removal:", m, "\n");
225 Predicate<Integer> pred = new Predicate<Integer>(){
227 public boolean isTrue(Integer i){
228 return ((i & 1) != 0);
232 m = m.removeAllSatisfying(pred);
234 dump("after removal:", m, "\n");
235 m.printOn(System.out);
239 public void testRangePredicateRemoval(){
240 PSIntMap<Integer> m = createPersistentIntMap();
242 for (int i=0; i<len; i++){
246 // completely remove first value node
247 Predicate<Integer> pred = new Predicate<Integer>(){
249 public boolean isTrue (Integer n){
253 m = m.removeAllSatisfying(pred);
255 System.out.println("m.size() = " + m.size());
256 assertTrue( m.size() == (len - 32));
257 for (int i=0; i<32; i++){
258 assertTrue( m.get(i) == null);
262 // remove all but one value from the second node
263 pred = new Predicate<Integer>(){
265 public boolean isTrue (Integer n){
266 return (n >32 && n <= 63);
269 m = m.removeAllSatisfying(pred);
270 System.out.println("m.size() = " + m.size());
271 assertTrue( m.size() == (len - 31));
272 assertTrue( m.get(32) != null);
273 for (int i=33; i<64; i++){
274 assertTrue( m.get(i) == null);
278 // remove all but one from bitmap node
279 pred = new Predicate<Integer>(){
281 public boolean isTrue (Integer n){
285 m = m.removeAllSatisfying(pred);
286 pred = new Predicate<Integer>(){
288 public boolean isTrue (Integer n){
289 return (n >= 64 && n < 95);
292 m = m.removeAllSatisfying(pred);
293 for (int i=64; i<95; i++){
294 assertTrue( m.get(i) == null);
296 assertTrue( m.get(95) != null);
300 public void testHeapPattern(){
301 Random r = new Random(42);
302 final BitSet removed = new BitSet();
304 Predicate<Integer> pred = new Predicate<Integer>(){
306 public boolean isTrue (Integer n){
307 return removed.get(n.intValue());
311 PSIntMap<Integer> m = createPersistentIntMap();
313 for (int i=0; i<max; i++){
316 if ((i > 0) && (i % 500) == 0){
317 for (int j=0; j<120; j++){
318 int k = r.nextInt(i);
322 m = m.removeAllSatisfying(pred);
326 System.out.println("m.size() = " + m.size());
327 int nRemoved = removed.cardinality();
328 assertTrue( m.size() == (max - nRemoved));
331 for (int i=0; i<max; i++){
333 assertTrue( m.get(i) == null);
335 assertTrue( m.get(i) != null);
339 assertTrue( n == (max - nRemoved));
345 final static int NSTATES = 20000;
346 final static int NOBJECTS = 2000;
347 final static int NGC = 400;
350 public void benchmark (){
353 //--- PersistentIntMap
354 Predicate<Integer> pred = new Predicate<Integer>() {
356 public boolean isTrue (Integer o) {
357 int i = o.intValue();
362 Runtime.getRuntime().gc();
363 t1 = System.currentTimeMillis();
364 for (int l=0; l<NSTATES; l++) {
365 PSIntMap<Integer> t = createPersistentIntMap();
368 for (int i=0; i<NOBJECTS; i++){
369 t = t.set(i, Integer.valueOf(i));
373 for (int i=0; i<NOBJECTS; i++) {
374 Integer o = t.get(i);
378 t = t.removeAllSatisfying(pred);
380 //--- no store/backtrack costs for container
382 t2 = System.currentTimeMillis();
383 System.out.println("PersistentIntMap (" + NSTATES + " cycles): " + (t2 - t1));
387 Runtime.getRuntime().gc();
388 t1 = System.currentTimeMillis();
389 for (int l=0; l<NSTATES; l++) {
390 HashMap<Integer,Integer> m = new HashMap<Integer,Integer>();
392 for (int i=0; i<NOBJECTS; i++){
397 for (int i=0; i<NOBJECTS; i++) {
398 Integer o = m.get(i);
402 for (Iterator<Map.Entry<Integer,Integer>> it = m.entrySet().iterator(); it.hasNext();) {
403 Map.Entry<Integer, Integer> e = it.next();
404 if (pred.isTrue(e.getValue())) {
409 //--- 2 x clone (upon store and backtrack)
410 m = (HashMap<Integer,Integer>)m.clone();
411 m = (HashMap<Integer,Integer>)m.clone();
413 t2 = System.currentTimeMillis();
414 System.out.println("HashMap (" + NSTATES + " cycles): " + (t2 - t1));
416 //--- ObjVector (needs to be adjusted for holes -> increased size)
417 Runtime.getRuntime().gc();
418 t1 = System.currentTimeMillis();
419 for (int l=0; l<NSTATES; l++) {
420 ObjVector<Integer> v = new ObjVector<Integer>();
422 for (int i=0; i<NOBJECTS; i++){
427 for (int i=0; i<NOBJECTS; i++) {
428 Integer o = v.get(i);
432 v.clearAllSatisfying(pred);
435 ObjVector.Snapshot<Integer> snap = v.getSnapshot();
438 t2 = System.currentTimeMillis();
439 System.out.println("ObjVector (" + NSTATES + " cycles): " + (t2 - t1));