1
1
/*
2
- * Copyright 2002-2012 the original author or authors.
2
+ * Copyright 2002-2013 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
16
16
17
17
package org .springframework .util ;
18
18
19
- import static org .hamcrest .Matchers .*;
20
- import static org .junit .Assert .*;
21
-
22
19
import java .lang .ref .WeakReference ;
23
20
import java .util .ArrayList ;
24
21
import java .util .Collections ;
36
33
import org .junit .Rule ;
37
34
import org .junit .Test ;
38
35
import org .junit .rules .ExpectedException ;
36
+
39
37
import org .springframework .util .ConcurrentReferenceHashMap .Entry ;
40
38
import org .springframework .util .ConcurrentReferenceHashMap .Reference ;
41
39
import org .springframework .util .ConcurrentReferenceHashMap .Restructure ;
42
40
import org .springframework .util .comparator .ComparableComparator ;
43
41
import org .springframework .util .comparator .NullSafeComparator ;
44
42
43
+ import static org .hamcrest .Matchers .*;
44
+ import static org .junit .Assert .*;
45
+
45
46
/**
46
47
* Tests for {@link ConcurrentReferenceHashMap}.
48
+ *
47
49
* @author Phillip Webb
48
50
*/
49
51
public class ConcurrentReferenceHashMapTests {
@@ -56,6 +58,7 @@ public class ConcurrentReferenceHashMapTests {
56
58
57
59
private TestWeakConcurrentCache <Integer , String > map = new TestWeakConcurrentCache <Integer , String >();
58
60
61
+
59
62
@ Test
60
63
public void shouldCreateWithDefaults () throws Exception {
61
64
ConcurrentReferenceHashMap <Integer , String > map = new ConcurrentReferenceHashMap <Integer , String >();
@@ -66,66 +69,62 @@ public void shouldCreateWithDefaults() throws Exception {
66
69
67
70
@ Test
68
71
public void shouldCreateWithInitialCapacity () throws Exception {
69
- ConcurrentReferenceHashMap <Integer , String > map = new ConcurrentReferenceHashMap <Integer , String >(
70
- 32 );
72
+ ConcurrentReferenceHashMap <Integer , String > map = new ConcurrentReferenceHashMap <Integer , String >(32 );
71
73
assertThat (map .getSegmentsSize (), is (16 ));
72
74
assertThat (map .getSegment (0 ).getSize (), is (2 ));
73
75
assertThat (map .getLoadFactor (), is (0.75f ));
74
76
}
75
77
76
78
@ Test
77
79
public void shouldCreateWithInitialCapacityAndLoadFactor () throws Exception {
78
- ConcurrentReferenceHashMap <Integer , String > map = new ConcurrentReferenceHashMap <Integer , String >(
79
- 32 , 0.5f );
80
+ ConcurrentReferenceHashMap <Integer , String > map = new ConcurrentReferenceHashMap <Integer , String >(32 , 0.5f );
80
81
assertThat (map .getSegmentsSize (), is (16 ));
81
82
assertThat (map .getSegment (0 ).getSize (), is (2 ));
82
83
assertThat (map .getLoadFactor (), is (0.5f ));
83
84
}
84
85
85
86
@ Test
86
87
public void shouldCreateWithInitialCapacityAndConcurrenyLevel () throws Exception {
87
- ConcurrentReferenceHashMap <Integer , String > map = new ConcurrentReferenceHashMap <Integer , String >(
88
- 16 , 2 );
88
+ ConcurrentReferenceHashMap <Integer , String > map = new ConcurrentReferenceHashMap <Integer , String >(16 , 2 );
89
89
assertThat (map .getSegmentsSize (), is (2 ));
90
90
assertThat (map .getSegment (0 ).getSize (), is (8 ));
91
91
assertThat (map .getLoadFactor (), is (0.75f ));
92
92
}
93
93
94
94
@ Test
95
95
public void shouldCreateFullyCustom () throws Exception {
96
- ConcurrentReferenceHashMap <Integer , String > map = new ConcurrentReferenceHashMap <Integer , String >(
97
- 5 , 0.5f , 3 );
96
+ ConcurrentReferenceHashMap <Integer , String > map = new ConcurrentReferenceHashMap <Integer , String >(5 , 0.5f , 3 );
98
97
// concurrencyLevel of 3 ends up as 4 (nearest power of 2)
99
98
assertThat (map .getSegmentsSize (), is (4 ));
100
99
// initialCapacity is 5/4 (rounded up, to nearest power of 2)
101
100
assertThat (map .getSegment (0 ).getSize (), is (2 ));
102
101
assertThat (map .getLoadFactor (), is (0.5f ));
103
102
}
104
103
105
- @ Test
106
- public void shouldNeedPositiveConcurrenyLevel () throws Exception {
107
- new ConcurrentReferenceHashMap <Integer , String >(1 , 1 );
108
- this .thrown .expect (IllegalArgumentException .class );
109
- this .thrown .expectMessage ("ConcurrencyLevel must be positive" );
110
- new TestWeakConcurrentCache <Integer , String >(1 , 0 );
111
- }
112
-
113
104
@ Test
114
105
public void shouldNeedNonNegativeInitialCapacity () throws Exception {
115
106
new ConcurrentReferenceHashMap <Integer , String >(0 , 1 );
116
107
this .thrown .expect (IllegalArgumentException .class );
117
- this .thrown .expectMessage ("InitialCapacity must not be negative" );
108
+ this .thrown .expectMessage ("Initial capacity must not be negative" );
118
109
new TestWeakConcurrentCache <Integer , String >(-1 , 1 );
119
110
}
120
111
121
112
@ Test
122
113
public void shouldNeedPositiveLoadFactor () throws Exception {
123
114
new ConcurrentReferenceHashMap <Integer , String >(0 , 0.1f , 1 );
124
115
this .thrown .expect (IllegalArgumentException .class );
125
- this .thrown .expectMessage ("LoadFactor must be positive" );
116
+ this .thrown .expectMessage ("Load factor must be positive" );
126
117
new TestWeakConcurrentCache <Integer , String >(0 , 0.0f , 1 );
127
118
}
128
119
120
+ @ Test
121
+ public void shouldNeedPositiveConcurrencyLevel () throws Exception {
122
+ new ConcurrentReferenceHashMap <Integer , String >(1 , 1 );
123
+ this .thrown .expect (IllegalArgumentException .class );
124
+ this .thrown .expectMessage ("Concurrency level must be positive" );
125
+ new TestWeakConcurrentCache <Integer , String >(1 , 0 );
126
+ }
127
+
129
128
@ Test
130
129
public void shouldPutAndGet () throws Exception {
131
130
// NOTE we are using mock references so we don't need to worry about GC
@@ -521,13 +520,11 @@ public void shouldSupportNullReference() throws Exception {
521
520
522
521
/**
523
522
* Time a multi-threaded access to a cache.
524
- *
525
- * @param cache the cache to test
526
523
* @return the timing stopwatch
527
- * @throws InterruptedException
528
524
*/
529
525
private <V > StopWatch timeMultiThreaded (String id , final Map <Integer , V > map ,
530
526
ValueFactory <V > factory ) throws InterruptedException {
527
+
531
528
StopWatch stopWatch = new StopWatch (id );
532
529
for (int i = 0 ; i < 500 ; i ++) {
533
530
map .put (i , factory .newValue (i ));
@@ -536,37 +533,37 @@ private <V> StopWatch timeMultiThreaded(String id, final Map<Integer, V> map,
536
533
stopWatch .start ("Running threads" );
537
534
for (int threadIndex = 0 ; threadIndex < threads .length ; threadIndex ++) {
538
535
threads [threadIndex ] = new Thread ("Cache access thread " + threadIndex ) {
539
-
540
536
@ Override
541
537
public void run () {
542
538
for (int j = 0 ; j < 1000 ; j ++) {
543
539
for (int i = 0 ; i < 1000 ; i ++) {
544
540
map .get (i );
545
541
}
546
542
}
547
- };
543
+ }
548
544
};
549
545
}
550
- for (int i = 0 ; i < threads . length ; i ++ ) {
551
- threads [ i ] .start ();
546
+ for (Thread thread : threads ) {
547
+ thread .start ();
552
548
}
553
549
554
- for (int i = 0 ; i < threads . length ; i ++ ) {
555
- if (threads [ i ] .isAlive ()) {
556
- threads [ i ] .join (2000 );
550
+ for (Thread thread : threads ) {
551
+ if (thread .isAlive ()) {
552
+ thread .join (2000 );
557
553
}
558
554
}
559
555
stopWatch .stop ();
560
556
return stopWatch ;
561
557
}
562
558
559
+
563
560
private static interface ValueFactory <V > {
564
561
565
562
V newValue (int k );
566
563
}
567
564
568
- private static class TestWeakConcurrentCache < K , V > extends
569
- ConcurrentReferenceHashMap <K , V > {
565
+
566
+ private static class TestWeakConcurrentCache < K , V > extends ConcurrentReferenceHashMap <K , V > {
570
567
571
568
private int supplimentalHash ;
572
569
@@ -582,8 +579,7 @@ public void setDisableTestHooks(boolean disableTestHooks) {
582
579
this .disableTestHooks = disableTestHooks ;
583
580
}
584
581
585
- public TestWeakConcurrentCache (int initialCapacity , float loadFactor ,
586
- int concurrencyLevel ) {
582
+ public TestWeakConcurrentCache (int initialCapacity , float loadFactor , int concurrencyLevel ) {
587
583
super (initialCapacity , loadFactor , concurrencyLevel );
588
584
}
589
585
@@ -607,9 +603,7 @@ public int getSupplimentalHash() {
607
603
608
604
@ Override
609
605
protected ReferenceManager createReferenceManager () {
610
-
611
606
return new ReferenceManager () {
612
-
613
607
@ Override
614
608
public Reference <K , V > createReference (Entry <K , V > entry , int hash ,
615
609
Reference <K , V > next ) {
@@ -618,7 +612,6 @@ public Reference<K, V> createReference(Entry<K, V> entry, int hash,
618
612
}
619
613
return new MockReference <K , V >(entry , hash , next , TestWeakConcurrentCache .this .queue );
620
614
}
621
-
622
615
@ Override
623
616
public Reference <K , V > pollForPurge () {
624
617
if (TestWeakConcurrentCache .this .disableTestHooks ) {
@@ -634,6 +627,7 @@ public MockReference<K, V> getMockReference(K key, Restructure restructure) {
634
627
}
635
628
}
636
629
630
+
637
631
private static class MockReference <K , V > implements Reference <K , V > {
638
632
639
633
private final int hash ;
@@ -644,8 +638,7 @@ private static class MockReference<K, V> implements Reference<K, V> {
644
638
645
639
private final LinkedList <MockReference <K , V >> queue ;
646
640
647
- public MockReference (Entry <K , V > entry , int hash , Reference <K , V > next ,
648
- LinkedList <MockReference <K , V >> queue ) {
641
+ public MockReference (Entry <K , V > entry , int hash , Reference <K , V > next , LinkedList <MockReference <K , V >> queue ) {
649
642
this .hash = hash ;
650
643
this .entry = entry ;
651
644
this .next = next ;
@@ -677,4 +670,5 @@ public void queueForPurge() {
677
670
this .queue .add (this );
678
671
}
679
672
}
673
+
680
674
}
0 commit comments