2 * Copyright (C) 2006 Robin Rosenberg <robin.rosenberg@dewire.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License, version 2, as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
17 package org
.spearce
.jgit
.lib
;
19 import java
.util
.Arrays
;
20 import java
.util
.Collection
;
21 import java
.util
.Comparator
;
22 import java
.util
.HashMap
;
23 import java
.util
.Iterator
;
25 import java
.util
.TreeMap
;
27 import junit
.framework
.AssertionFailedError
;
28 import junit
.framework
.TestCase
;
31 * Test functionality and performance.
33 * Performance (put performance) is included because that is the very reason
34 * that {@link ObjectIdMap} exists.
37 public class ObjectIdMapTest
extends TestCase
{
39 ObjectId
[] ids
= new ObjectId
[500000];
41 protected void setUp() throws Exception
{
43 for (int i
=0; i
<ids
.length
; ++i
) {
44 byte[] data
= new byte[Constants
.OBJECT_ID_LENGTH
];
45 for (int j
=0; j
<Constants
.OBJECT_ID_LENGTH
; ++j
)
46 data
[j
] = (byte) (b
++^
0xEE);
47 ids
[i
] = new ObjectId(data
);
51 protected void tearDown() throws Exception
{
52 ids
= null; // avoid out of memory
56 * Test performance of {@link ObjectIdMap#put(ObjectId, Object)}
58 @SuppressWarnings("unchecked")
59 public void testBothPut() {
67 for (int j
=0; j
<64; ++j
) {
69 ((j
& 1)!=0 ?
1 : 0) |
70 ((j
& 2)!=0 ?
2 : 0) |
71 ((j
& 4)!=0 ?
16 : 0) |
72 ((j
& 8)!=0 ?
32 : 0) |
73 ((j
& 16)!=0 ?
4 : 0) |
74 ((j
& 32)!=0 ?
8 : 0);
77 long t0
= System
.currentTimeMillis();
79 Map treeMap
= new TreeMap();
80 for (int i
=0; i
<ids
.length
; ++i
)
81 treeMap
.put(ids
[i
],ids
[i
]);
83 long t1
= System
.currentTimeMillis();
87 long t0
= System
.currentTimeMillis();
88 Map hashMap
= new HashMap();
89 for (int i
=0; i
<ids
.length
; ++i
)
90 hashMap
.put(ids
[i
],ids
[i
]);
91 long t1
= System
.currentTimeMillis();
96 long t0
= System
.currentTimeMillis();
98 Map levelMapWithTree
= new ObjectIdMap(new TreeMap());
99 for (int i
=0; i
<ids
.length
; ++i
)
100 levelMapWithTree
.put(ids
[i
],ids
[i
]);
102 long t1
= System
.currentTimeMillis();
107 long t0
= System
.currentTimeMillis();
108 Map levelMapWithHash
= new ObjectIdMap(new HashMap());
109 for (int i
=0; i
<ids
.length
; ++i
)
110 levelMapWithHash
.put(ids
[i
],ids
[i
]);
112 long t1
= System
.currentTimeMillis();
118 long t0
= System
.currentTimeMillis();
120 Map levelMapWithTreeAndSpecialCompare
= new ObjectIdMap(new TreeMap(new Comparator() {
122 public int compare(Object arg0
, Object arg1
) {
123 byte[] b0
=((ObjectId
)arg0
).getBytes();
124 byte[] b1
=((ObjectId
)arg1
).getBytes();
125 for (int i
=1; i
<Constants
.OBJECT_ID_LENGTH
; ++i
) {
136 for (int i
=0; i
<ids
.length
; ++i
)
137 levelMapWithTreeAndSpecialCompare
.put(ids
[i
],ids
[i
]);
139 long t1
= System
.currentTimeMillis();
144 long t0
= System
.currentTimeMillis();
146 Map levelMapWithTreeAndSpecialCompare
= new ObjectIdMap(new TreeMap(new Comparator() {
148 public int compare(Object arg0
, Object arg1
) {
149 return ((Comparable
)arg0
).compareTo(arg1
);
153 for (int i
=0; i
<ids
.length
; ++i
)
154 levelMapWithTreeAndSpecialCompare
.put(ids
[i
],ids
[i
]);
156 long t1
= System
.currentTimeMillis();
161 System
.out
.println("TreeMap ="+d1
);
162 System
.out
.println("HashMap ="+d2
);
163 System
.out
.println("Partitioned TreeMap ObjectId.compare ="+d3
);
164 System
.out
.println("Partitioned HashMap ="+d4
);
165 System
.out
.println("Partitioned TreeMap enhanced compare ="+d5
);
166 System
.out
.println("Partitioned TreeMap dummy compare ="+d6
);
167 assertFaster(1.2f
, 3f
, d5
, d2
);
171 * Test performance of {@link ObjectIdMap#get(Object)}
173 @SuppressWarnings("unchecked")
174 public void testBothGet() {
182 Map treeMap
= new TreeMap();
183 for (int i
=0; i
<ids
.length
; ++i
)
184 treeMap
.put(ids
[i
],ids
[i
]);
186 Map hashMap
= new HashMap();
187 for (int i
=0; i
<ids
.length
; ++i
)
188 hashMap
.put(ids
[i
],ids
[i
]);
190 Map levelMapWithTree
= new ObjectIdMap(new TreeMap());
191 for (int i
=0; i
<ids
.length
; ++i
)
192 levelMapWithTree
.put(ids
[i
],ids
[i
]);
194 Map levelMapWithHash
= new ObjectIdMap(new HashMap());
195 for (int i
=0; i
<ids
.length
; ++i
)
196 levelMapWithHash
.put(ids
[i
],ids
[i
]);
198 Map levelMapWithTreeAndSpecialCompare
= new ObjectIdMap(new TreeMap(new Comparator() {
199 public int compare(Object arg0
, Object arg1
) {
200 byte[] b0
=((ObjectId
)arg0
).getBytes();
201 byte[] b1
=((ObjectId
)arg1
).getBytes();
202 for (int i
=1; i
<Constants
.OBJECT_ID_LENGTH
; ++i
) {
212 for (int i
=0; i
<ids
.length
; ++i
)
213 levelMapWithTreeAndSpecialCompare
.put(ids
[i
],ids
[i
]);
215 Map levelMapWithTreeAndSpecialCompare2
= new ObjectIdMap(new TreeMap(new Comparator() {
216 public int compare(Object arg0
, Object arg1
) {
217 return ((Comparable
)arg0
).compareTo(arg1
);
220 for (int i
=0; i
<ids
.length
; ++i
)
221 levelMapWithTreeAndSpecialCompare2
.put(ids
[i
],ids
[i
]);
223 for (int j
=0; j
<64; ++j
) {
225 ((j
& 1)!=0 ?
1 : 0) |
226 ((j
& 2)!=0 ?
2 : 0) |
227 ((j
& 4)!=0 ?
16 : 0) |
228 ((j
& 8)!=0 ?
32 : 0) |
229 ((j
& 16)!=0 ?
4 : 0) |
230 ((j
& 32)!=0 ?
8 : 0);
233 long t0
= System
.currentTimeMillis();
235 for (int i
=0; i
<ids
.length
; ++i
)
238 long t1
= System
.currentTimeMillis();
242 long t0
= System
.currentTimeMillis();
243 for (int i
=0; i
<ids
.length
; ++i
)
245 long t1
= System
.currentTimeMillis();
250 long t0
= System
.currentTimeMillis();
252 for (int i
=0; i
<ids
.length
; ++i
)
253 levelMapWithTree
.get(ids
[i
]);
255 long t1
= System
.currentTimeMillis();
260 long t0
= System
.currentTimeMillis();
261 for (int i
=0; i
<ids
.length
; ++i
)
262 levelMapWithHash
.get(ids
[i
]);
264 long t1
= System
.currentTimeMillis();
270 long t0
= System
.currentTimeMillis();
272 for (int i
=0; i
<ids
.length
; ++i
)
273 levelMapWithTreeAndSpecialCompare
.get(ids
[i
]);
275 long t1
= System
.currentTimeMillis();
280 long t0
= System
.currentTimeMillis();
282 for (int i
=0; i
<ids
.length
; ++i
)
283 levelMapWithTreeAndSpecialCompare2
.get(ids
[i
]);
285 long t1
= System
.currentTimeMillis();
290 System
.out
.println("TreeMap ="+d1
);
291 System
.out
.println("HashMap ="+d2
);
292 System
.out
.println("Partitioned TreeMap ObjectId.compare ="+d3
);
293 System
.out
.println("Partitioned HashMap ="+d4
);
294 System
.out
.println("Partitioned TreeMap enhanced compare ="+d5
);
295 System
.out
.println("Partitioned TreeMap dummy compare ="+d6
);
296 assertFaster(1.0f
, 3f
, d5
, d2
); // d5 is twice as fast
300 * Test performance of {@link ObjectIdMap#keySet()} iterator
302 @SuppressWarnings("unchecked")
303 public void testBothIterate() {
311 Map treeMap
= new TreeMap();
312 for (int i
=0; i
<ids
.length
; ++i
)
313 treeMap
.put(ids
[i
],ids
[i
]);
315 Map hashMap
= new HashMap();
316 for (int i
=0; i
<ids
.length
; ++i
)
317 hashMap
.put(ids
[i
],ids
[i
]);
319 Map levelMapWithTree
= new ObjectIdMap(new TreeMap());
320 for (int i
=0; i
<ids
.length
; ++i
)
321 levelMapWithTree
.put(ids
[i
],ids
[i
]);
323 Map levelMapWithHash
= new ObjectIdMap(new HashMap());
324 for (int i
=0; i
<ids
.length
; ++i
)
325 levelMapWithHash
.put(ids
[i
],ids
[i
]);
327 Map levelMapWithTreeAndSpecialCompare
= new ObjectIdMap(new TreeMap(new Comparator() {
328 public int compare(Object arg0
, Object arg1
) {
329 byte[] b0
=((ObjectId
)arg0
).getBytes();
330 byte[] b1
=((ObjectId
)arg1
).getBytes();
331 for (int i
=1; i
<Constants
.OBJECT_ID_LENGTH
; ++i
) {
341 for (int i
=0; i
<ids
.length
; ++i
)
342 levelMapWithTreeAndSpecialCompare
.put(ids
[i
],ids
[i
]);
344 Map levelMapWithTreeAndSpecialCompare2
= new ObjectIdMap(new TreeMap(new Comparator() {
345 public int compare(Object arg0
, Object arg1
) {
346 return ((Comparable
)arg0
).compareTo(arg1
);
349 for (int i
=0; i
<ids
.length
; ++i
)
350 levelMapWithTreeAndSpecialCompare2
.put(ids
[i
],ids
[i
]);
352 for (int j
=0; j
<64; ++j
) {
354 ((j
& 1)!=0 ?
1 : 0) |
355 ((j
& 2)!=0 ?
2 : 0) |
356 ((j
& 4)!=0 ?
16 : 0) |
357 ((j
& 8)!=0 ?
32 : 0) |
358 ((j
& 16)!=0 ?
4 : 0) |
359 ((j
& 32)!=0 ?
8 : 0);
362 long t0
= System
.currentTimeMillis();
364 for (int l
=0; l
<100; ++l
)
365 for (Iterator k
=treeMap
.keySet().iterator(); k
.hasNext(); )
368 long t1
= System
.currentTimeMillis();
372 long t0
= System
.currentTimeMillis();
373 for (int l
=0; l
<100; ++l
)
374 for (Iterator k
=hashMap
.keySet().iterator(); k
.hasNext(); )
376 long t1
= System
.currentTimeMillis();
381 long t0
= System
.currentTimeMillis();
383 for (int l
=0; l
<100; ++l
)
384 for (Iterator k
=levelMapWithTree
.keySet().iterator(); k
.hasNext(); )
387 long t1
= System
.currentTimeMillis();
392 long t0
= System
.currentTimeMillis();
394 for (int l
=0; l
<100; ++l
)
395 for (Iterator k
=levelMapWithHash
.keySet().iterator(); k
.hasNext(); )
398 long t1
= System
.currentTimeMillis();
404 long t0
= System
.currentTimeMillis();
406 for (int l
=0; l
<100; ++l
)
407 for (Iterator k
=levelMapWithTreeAndSpecialCompare
.keySet().iterator(); k
.hasNext(); )
410 long t1
= System
.currentTimeMillis();
415 long t0
= System
.currentTimeMillis();
417 for (int l
=0; l
<100; ++l
)
418 for (Iterator k
=levelMapWithTreeAndSpecialCompare2
.keySet().iterator(); k
.hasNext(); )
421 long t1
= System
.currentTimeMillis();
426 System
.out
.println("TreeMap ="+d1
);
427 System
.out
.println("HashMap ="+d2
);
428 System
.out
.println("Partitioned TreeMap ObjectId.compare ="+d3
);
429 System
.out
.println("Partitioned HashMap ="+d4
);
430 System
.out
.println("Partitioned TreeMap enhanced compare ="+d5
);
431 System
.out
.println("Partitioned TreeMap dummy compare ="+d6
);
432 assertSlower(5f
, 15f
, d5
, d2
);
436 * Test performance of {@link ObjectIdMap#values()}
438 @SuppressWarnings("unchecked")
439 public void testBothValues() {
447 Map treeMap
= new TreeMap();
448 for (int i
=0; i
<ids
.length
; ++i
)
449 treeMap
.put(ids
[i
],ids
[i
]);
451 Map hashMap
= new HashMap();
452 for (int i
=0; i
<ids
.length
; ++i
)
453 hashMap
.put(ids
[i
],ids
[i
]);
455 Map levelMapWithTree
= new ObjectIdMap(new TreeMap());
456 for (int i
=0; i
<ids
.length
; ++i
)
457 levelMapWithTree
.put(ids
[i
],ids
[i
]);
459 Map levelMapWithHash
= new ObjectIdMap(new HashMap());
460 for (int i
=0; i
<ids
.length
; ++i
)
461 levelMapWithHash
.put(ids
[i
],ids
[i
]);
463 Map levelMapWithTreeAndSpecialCompare
= new ObjectIdMap(new TreeMap(new Comparator() {
464 public int compare(Object arg0
, Object arg1
) {
465 byte[] b0
=((ObjectId
)arg0
).getBytes();
466 byte[] b1
=((ObjectId
)arg1
).getBytes();
467 for (int i
=1; i
<Constants
.OBJECT_ID_LENGTH
; ++i
) {
477 for (int i
=0; i
<ids
.length
; ++i
)
478 levelMapWithTreeAndSpecialCompare
.put(ids
[i
],ids
[i
]);
480 Map levelMapWithTreeAndSpecialCompare2
= new ObjectIdMap(new TreeMap(new Comparator() {
481 public int compare(Object arg0
, Object arg1
) {
482 return ((Comparable
)arg0
).compareTo(arg1
);
485 for (int i
=0; i
<ids
.length
; ++i
)
486 levelMapWithTreeAndSpecialCompare2
.put(ids
[i
],ids
[i
]);
488 for (int j
=0; j
<8192; ++j
) {
490 ((j
& 1)!=0 ?
1 : 0) |
491 ((j
& 2)!=0 ?
2 : 0) |
492 ((j
& 4)!=0 ?
16 : 0) |
493 ((j
& 8)!=0 ?
32 : 0) |
494 ((j
& 16)!=0 ?
4 : 0) |
495 ((j
& 32)!=0 ?
8 : 0);
498 long t0
= System
.currentTimeMillis();
500 for (int l
=0; l
<100; ++l
)
503 long t1
= System
.currentTimeMillis();
507 long t0
= System
.currentTimeMillis();
509 for (int l
=0; l
<100; ++l
)
512 long t1
= System
.currentTimeMillis();
517 long t0
= System
.currentTimeMillis();
519 for (int l
=0; l
<100; ++l
)
520 levelMapWithTree
.values();
522 long t1
= System
.currentTimeMillis();
527 long t0
= System
.currentTimeMillis();
529 for (int l
=0; l
<100; ++l
)
530 levelMapWithHash
.values();
532 long t1
= System
.currentTimeMillis();
538 long t0
= System
.currentTimeMillis();
540 for (int l
=0; l
<100; ++l
)
541 levelMapWithTreeAndSpecialCompare
.values();
543 long t1
= System
.currentTimeMillis();
548 long t0
= System
.currentTimeMillis();
550 for (int l
=0; l
<100; ++l
)
551 levelMapWithTreeAndSpecialCompare2
.values();
553 long t1
= System
.currentTimeMillis();
558 System
.out
.println("TreeMap ="+d1
);
559 System
.out
.println("HashMap ="+d2
);
560 System
.out
.println("Partitioned TreeMap ObjectId.compare ="+d3
);
561 System
.out
.println("Partitioned HashMap ="+d4
);
562 System
.out
.println("Partitioned TreeMap enhanced compare ="+d5
);
563 System
.out
.println("Partitioned TreeMap dummy compare ="+d6
);
564 assertFaster(1.5f
, 3f
, d5
, d2
);
568 * Verify that ObjectIdMap and TreeMap functionally are equivalent.
570 @SuppressWarnings("unchecked")
571 public void testFunc() {
572 Map treeMap
= new TreeMap();
573 for (int i
=0; i
<ids
.length
/100; ++i
)
574 treeMap
.put(ids
[i
],ids
[i
]);
575 Map levelMapWithTree
= new ObjectIdMap(new TreeMap());
576 for (int i
=0; i
<ids
.length
/100; ++i
)
577 levelMapWithTree
.put(ids
[i
],ids
[i
]);
579 assertEquals(treeMap
, levelMapWithTree
);
580 assertEquals(treeMap
.values(), levelMapWithTree
.values());
581 assertEquals(treeMap
.keySet(), levelMapWithTree
.keySet());
583 treeMap
.remove(ids
[30]);
584 levelMapWithTree
.remove(ids
[30]);
585 assertFalse(treeMap
.containsKey(ids
[30]));
586 assertFalse(levelMapWithTree
.containsKey(ids
[30]));
587 assertEquals(treeMap
.values(), levelMapWithTree
.values());
588 assertEquals(treeMap
.keySet(), levelMapWithTree
.keySet());
591 void assertEquals(Collection a
, Collection b
) {
592 Object
[] aa
= a
.toArray();
593 Object
[] ba
= b
.toArray();
596 assertTrue(Arrays
.equals(aa
, ba
));
599 void assertSlower(float min
,float max
, long d5
, long d2
) {
600 float ratio
= d5
/(float)d2
;
601 ratio
= ((int)(ratio
*10+0.5))/10.0f
;
602 if (ratio
< min
|| ratio
> max
)
603 throw new AssertionFailedError("Expected (slower) "+ min
+ " <= " + ratio
+ " <= " + max
);
604 StackTraceElement frame
= new Throwable().getStackTrace()[1];
605 System
.out
.println("Expected slower (ok) "+ frame
.getClassName()+"."+frame
.getMethodName() + " in range: " + min
+ " <= " + ratio
+ " <= " + max
);
608 void assertFaster(float min
,float max
, long d5
, long d2
) {
609 float ratio
= d2
/(float)d5
;
610 ratio
= ((int)(ratio
*10+0.5))/10.0f
;
611 if (ratio
< min
|| ratio
> max
)
612 throw new AssertionFailedError("Expected (faster) "+ min
+ " <= " + ratio
+ " <= " + max
);
613 StackTraceElement frame
= new Throwable().getStackTrace()[1];
614 System
.out
.println("Expected faster (ok) "+ frame
.getClassName()+"."+frame
.getMethodName() + " in range: " + min
+ " <= " + ratio
+ " <= " + max
);