@@ -98,7 +98,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
9898 * Late binding entry set.
9999 */
100100 @ Nullable
101- private Set <Map .Entry <K , V >> entrySet ;
101+ private volatile Set <Map .Entry <K , V >> entrySet ;
102102
103103
104104 /**
@@ -167,8 +167,8 @@ public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor, int con
167167 * @param referenceType the reference type used for entries (soft or weak)
168168 */
169169 @ SuppressWarnings ("unchecked" )
170- public ConcurrentReferenceHashMap (int initialCapacity , float loadFactor , int concurrencyLevel ,
171- ReferenceType referenceType ) {
170+ public ConcurrentReferenceHashMap (
171+ int initialCapacity , float loadFactor , int concurrencyLevel , ReferenceType referenceType ) {
172172
173173 Assert .isTrue (initialCapacity >= 0 , "Initial capacity must not be negative" );
174174 Assert .isTrue (loadFactor > 0f , "Load factor must be positive" );
@@ -215,7 +215,7 @@ protected ReferenceManager createReferenceManager() {
215215 * @return the resulting hash code
216216 */
217217 protected int getHash (@ Nullable Object o ) {
218- int hash = o == null ? 0 : o .hashCode ();
218+ int hash = ( o != null ? o .hashCode () : 0 );
219219 hash += (hash << 15 ) ^ 0xffffcd7d ;
220220 hash ^= (hash >>> 10 );
221221 hash += (hash << 3 );
@@ -247,8 +247,8 @@ public boolean containsKey(@Nullable Object key) {
247247
248248 @ Nullable
249249 private Entry <K , V > getEntryIfAvailable (@ Nullable Object key ) {
250- Reference <K , V > reference = getReference (key , Restructure .WHEN_NECESSARY );
251- return (reference != null ? reference .get () : null );
250+ Reference <K , V > ref = getReference (key , Restructure .WHEN_NECESSARY );
251+ return (ref != null ? ref .get () : null );
252252 }
253253
254254 /**
@@ -281,7 +281,7 @@ private V put(@Nullable final K key, @Nullable final V value, final boolean over
281281 return doTask (key , new Task <V >(TaskOption .RESTRUCTURE_BEFORE , TaskOption .RESIZE ) {
282282 @ Override
283283 @ Nullable
284- protected V execute (@ Nullable Reference <K , V > reference , @ Nullable Entry <K , V > entry , @ Nullable Entries entries ) {
284+ protected V execute (@ Nullable Reference <K , V > ref , @ Nullable Entry <K , V > entry , @ Nullable Entries entries ) {
285285 if (entry != null ) {
286286 V oldValue = entry .getValue ();
287287 if (overwriteExisting ) {
@@ -302,10 +302,10 @@ public V remove(Object key) {
302302 return doTask (key , new Task <V >(TaskOption .RESTRUCTURE_AFTER , TaskOption .SKIP_IF_EMPTY ) {
303303 @ Override
304304 @ Nullable
305- protected V execute (@ Nullable Reference <K , V > reference , @ Nullable Entry <K , V > entry ) {
305+ protected V execute (@ Nullable Reference <K , V > ref , @ Nullable Entry <K , V > entry ) {
306306 if (entry != null ) {
307- if (reference != null ) {
308- reference .release ();
307+ if (ref != null ) {
308+ ref .release ();
309309 }
310310 return entry .value ;
311311 }
@@ -318,10 +318,10 @@ protected V execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> e
318318 public boolean remove (Object key , final Object value ) {
319319 Boolean result = doTask (key , new Task <Boolean >(TaskOption .RESTRUCTURE_AFTER , TaskOption .SKIP_IF_EMPTY ) {
320320 @ Override
321- protected Boolean execute (@ Nullable Reference <K , V > reference , @ Nullable Entry <K , V > entry ) {
321+ protected Boolean execute (@ Nullable Reference <K , V > ref , @ Nullable Entry <K , V > entry ) {
322322 if (entry != null && ObjectUtils .nullSafeEquals (entry .getValue (), value )) {
323- if (reference != null ) {
324- reference .release ();
323+ if (ref != null ) {
324+ ref .release ();
325325 }
326326 return true ;
327327 }
@@ -335,7 +335,7 @@ protected Boolean execute(@Nullable Reference<K, V> reference, @Nullable Entry<K
335335 public boolean replace (K key , final V oldValue , final V newValue ) {
336336 Boolean result = doTask (key , new Task <Boolean >(TaskOption .RESTRUCTURE_BEFORE , TaskOption .SKIP_IF_EMPTY ) {
337337 @ Override
338- protected Boolean execute (@ Nullable Reference <K , V > reference , @ Nullable Entry <K , V > entry ) {
338+ protected Boolean execute (@ Nullable Reference <K , V > ref , @ Nullable Entry <K , V > entry ) {
339339 if (entry != null && ObjectUtils .nullSafeEquals (entry .getValue (), oldValue )) {
340340 entry .setValue (newValue );
341341 return true ;
@@ -352,7 +352,7 @@ public V replace(K key, final V value) {
352352 return doTask (key , new Task <V >(TaskOption .RESTRUCTURE_BEFORE , TaskOption .SKIP_IF_EMPTY ) {
353353 @ Override
354354 @ Nullable
355- protected V execute (@ Nullable Reference <K , V > reference , @ Nullable Entry <K , V > entry ) {
355+ protected V execute (@ Nullable Reference <K , V > ref , @ Nullable Entry <K , V > entry ) {
356356 if (entry != null ) {
357357 V oldValue = entry .getValue ();
358358 entry .setValue (value );
@@ -393,11 +393,23 @@ public int size() {
393393 }
394394
395395 @ Override
396- public Set <java .util .Map .Entry <K , V >> entrySet () {
397- if (this .entrySet == null ) {
398- this .entrySet = new EntrySet ();
396+ public boolean isEmpty () {
397+ for (Segment segment : this .segments ) {
398+ if (segment .getCount () > 0 ) {
399+ return false ;
400+ }
399401 }
400- return this .entrySet ;
402+ return true ;
403+ }
404+
405+ @ Override
406+ public Set <Map .Entry <K , V >> entrySet () {
407+ Set <Map .Entry <K , V >> entrySet = this .entrySet ;
408+ if (entrySet == null ) {
409+ entrySet = new EntrySet ();
410+ this .entrySet = entrySet ;
411+ }
412+ return entrySet ;
401413 }
402414
403415 @ Nullable
@@ -512,8 +524,8 @@ public <T> T doTask(final int hash, @Nullable final Object key, final Task<T> ta
512524 try {
513525 final int index = getIndex (hash , this .references );
514526 final Reference <K , V > head = this .references [index ];
515- Reference <K , V > reference = findInChain (head , key , hash );
516- Entry <K , V > entry = (reference != null ? reference .get () : null );
527+ Reference <K , V > ref = findInChain (head , key , hash );
528+ Entry <K , V > entry = (ref != null ? ref .get () : null );
517529 Entries entries = new Entries () {
518530 @ Override
519531 public void add (@ Nullable V value ) {
@@ -524,7 +536,7 @@ public void add(@Nullable V value) {
524536 Segment .this .count ++;
525537 }
526538 };
527- return task .execute (reference , entry , entries );
539+ return task .execute (ref , entry , entries );
528540 }
529541 finally {
530542 unlock ();
@@ -559,19 +571,18 @@ public void clear() {
559571 * @param allowResize if resizing is permitted
560572 */
561573 protected final void restructureIfNecessary (boolean allowResize ) {
562- boolean needsResize = (( this .count > 0 ) && ( this .count >= this .resizeThreshold ) );
563- Reference <K , V > reference = this .referenceManager .pollForPurge ();
564- if (( reference != null ) || (needsResize && allowResize )) {
574+ boolean needsResize = (this .count > 0 && this .count >= this .resizeThreshold );
575+ Reference <K , V > ref = this .referenceManager .pollForPurge ();
576+ if (ref != null || (needsResize && allowResize )) {
565577 lock ();
566578 try {
567579 int countAfterRestructure = this .count ;
568-
569580 Set <Reference <K , V >> toPurge = Collections .emptySet ();
570- if (reference != null ) {
581+ if (ref != null ) {
571582 toPurge = new HashSet <>();
572- while (reference != null ) {
573- toPurge .add (reference );
574- reference = this .referenceManager .pollForPurge ();
583+ while (ref != null ) {
584+ toPurge .add (ref );
585+ ref = this .referenceManager .pollForPurge ();
575586 }
576587 }
577588 countAfterRestructure -= toPurge .size ();
@@ -587,24 +598,25 @@ protected final void restructureIfNecessary(boolean allowResize) {
587598 }
588599
589600 // Either create a new table or reuse the existing one
590- Reference <K , V >[] restructured = (resizing ? createReferenceArray (restructureSize ) : this .references );
601+ Reference <K , V >[] restructured =
602+ (resizing ? createReferenceArray (restructureSize ) : this .references );
591603
592604 // Restructure
593605 for (int i = 0 ; i < this .references .length ; i ++) {
594- reference = this .references [i ];
606+ ref = this .references [i ];
595607 if (!resizing ) {
596608 restructured [i ] = null ;
597609 }
598- while (reference != null ) {
599- if (!toPurge .contains (reference )) {
600- Entry <K , V > entry = reference .get ();
610+ while (ref != null ) {
611+ if (!toPurge .contains (ref )) {
612+ Entry <K , V > entry = ref .get ();
601613 if (entry != null ) {
602- int index = getIndex (reference .getHash (), restructured );
614+ int index = getIndex (ref .getHash (), restructured );
603615 restructured [index ] = this .referenceManager .createReference (
604- entry , reference .getHash (), restructured [index ]);
616+ entry , ref .getHash (), restructured [index ]);
605617 }
606618 }
607- reference = reference .getNext ();
619+ ref = ref .getNext ();
608620 }
609621 }
610622
@@ -622,8 +634,8 @@ protected final void restructureIfNecessary(boolean allowResize) {
622634 }
623635
624636 @ Nullable
625- private Reference <K , V > findInChain (Reference <K , V > reference , @ Nullable Object key , int hash ) {
626- Reference <K , V > currRef = reference ;
637+ private Reference <K , V > findInChain (Reference <K , V > ref , @ Nullable Object key , int hash ) {
638+ Reference <K , V > currRef = ref ;
627639 while (currRef != null ) {
628640 if (currRef .getHash () == hash ) {
629641 Entry <K , V > entry = currRef .get ();
@@ -774,26 +786,26 @@ public boolean hasOption(TaskOption option) {
774786
775787 /**
776788 * Execute the task.
777- * @param reference the found reference or {@code null}
778- * @param entry the found entry or {@code null}
789+ * @param ref the found reference ( or {@code null})
790+ * @param entry the found entry ( or {@code null})
779791 * @param entries access to the underlying entries
780792 * @return the result of the task
781793 * @see #execute(Reference, Entry)
782794 */
783795 @ Nullable
784- protected T execute (@ Nullable Reference <K , V > reference , @ Nullable Entry <K , V > entry , @ Nullable Entries entries ) {
785- return execute (reference , entry );
796+ protected T execute (@ Nullable Reference <K , V > ref , @ Nullable Entry <K , V > entry , @ Nullable Entries entries ) {
797+ return execute (ref , entry );
786798 }
787799
788800 /**
789801 * Convenience method that can be used for tasks that do not need access to {@link Entries}.
790- * @param reference the found reference or {@code null}
791- * @param entry the found entry or {@code null}
802+ * @param ref the found reference ( or {@code null})
803+ * @param entry the found entry ( or {@code null})
792804 * @return the result of the task
793805 * @see #execute(Reference, Entry, Entries)
794806 */
795807 @ Nullable
796- protected T execute (@ Nullable Reference <K , V > reference , @ Nullable Entry <K , V > entry ) {
808+ protected T execute (@ Nullable Reference <K , V > ref , @ Nullable Entry <K , V > entry ) {
797809 return null ;
798810 }
799811 }
@@ -834,9 +846,9 @@ public Iterator<Map.Entry<K, V>> iterator() {
834846 @ Override
835847 public boolean contains (@ Nullable Object o ) {
836848 if (o instanceof Map .Entry <?, ?>) {
837- Map .Entry <?, ?> entry = (java . util . Map .Entry <?, ?>) o ;
838- Reference <K , V > reference = ConcurrentReferenceHashMap .this .getReference (entry .getKey (), Restructure .NEVER );
839- Entry <K , V > otherEntry = (reference != null ? reference .get () : null );
849+ Map .Entry <?, ?> entry = (Map .Entry <?, ?>) o ;
850+ Reference <K , V > ref = ConcurrentReferenceHashMap .this .getReference (entry .getKey (), Restructure .NEVER );
851+ Entry <K , V > otherEntry = (ref != null ? ref .get () : null );
840852 if (otherEntry != null ) {
841853 return ObjectUtils .nullSafeEquals (otherEntry .getValue (), otherEntry .getValue ());
842854 }
0 commit comments