001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018/* 019 * Copyright (c) 2008-2020, Hazelcast, Inc. All Rights Reserved. 020 */ 021 022package org.apache.commons.collections4.map; 023 024/* 025 * Written by Doug Lea with assistance from members of JCP JSR-166 026 * Expert Group and released to the public domain, as explained at 027 * http://creativecommons.org/licenses/publicdomain 028 */ 029 030import java.lang.ref.Reference; 031import java.lang.ref.ReferenceQueue; 032import java.lang.ref.SoftReference; 033import java.lang.ref.WeakReference; 034import java.util.AbstractCollection; 035import java.util.AbstractMap; 036import java.util.AbstractSet; 037import java.util.Arrays; 038import java.util.Collection; 039import java.util.ConcurrentModificationException; 040import java.util.EnumSet; 041import java.util.Enumeration; 042import java.util.HashMap; 043import java.util.Hashtable; 044import java.util.IdentityHashMap; 045import java.util.Iterator; 046import java.util.Map; 047import java.util.NoSuchElementException; 048import java.util.Objects; 049import java.util.Set; 050import java.util.WeakHashMap; 051import java.util.concurrent.ConcurrentHashMap; 052import java.util.concurrent.ConcurrentMap; 053import java.util.concurrent.locks.ReentrantLock; 054import java.util.function.BiFunction; 055import java.util.function.Function; 056import java.util.function.Supplier; 057 058/** 059 * An advanced hash map supporting configurable garbage collection semantics of keys and values, optional referential-equality, full concurrency of retrievals, 060 * and adjustable expected concurrency for updates. 061 * <p> 062 * This map is designed around specific advanced use-cases. If there is any doubt whether this map is for you, you most likely should be using 063 * {@link ConcurrentHashMap} instead. 064 * </p> 065 * <p> 066 * This map supports strong, weak, and soft keys and values. By default, keys are weak, and values are strong. Such a configuration offers similar behavior to 067 * {@link WeakHashMap}, entries of this map are periodically removed once their corresponding keys are no longer referenced outside of this map. In 068 * other words, this map will not prevent a key from being discarded by the garbage collector. Once a key has been discarded by the collector, the corresponding 069 * entry is no longer visible to this map; however, the entry may occupy space until a future map operation decides to reclaim it. For this reason, summary 070 * functions such as {@code size} and {@code isEmpty} might return a value greater than the observed number of entries. In order to support a high level of 071 * concurrency, stale entries are only reclaimed during blocking (usually mutating) operations. 072 * </p> 073 * <p> 074 * Enabling soft keys allows entries in this map to remain until their space is absolutely needed by the garbage collector. This is unlike weak keys which can 075 * be reclaimed as soon as they are no longer referenced by a normal strong reference. The primary use case for soft keys is a cache, which ideally occupies 076 * memory that is not in use for as long as possible. 077 * </p> 078 * <p> 079 * By default, values are held using a normal strong reference. This provides the commonly desired guarantee that a value will always have at least the same 080 * life-span as its key. For this reason, care should be taken to ensure that a value never refers, either directly or indirectly, to its key, thereby 081 * preventing reclamation. If this is unavoidable, then it is recommended to use the same reference type in use for the key. However, it should be noted that 082 * non-strong values may disappear before their corresponding key. 083 * </p> 084 * <p> 085 * While this map does allow the use of both strong keys and values, it is recommended you use {@link ConcurrentHashMap} for such a 086 * configuration, since it is optimized for that case. 087 * </p> 088 * <p> 089 * Just like {@link ConcurrentHashMap}, this class obeys the same functional specification as {@link Hashtable}, and includes versions of 090 * methods corresponding to each method of {@code Hashtable}. However, even though all operations are thread-safe, retrieval operations do <em>not</em> entail 091 * locking, and there is <em>not</em> any support for locking the entire map in a way that prevents all access. This class is fully interoperable with 092 * {@code Hashtable} in programs that rely on its thread safety but not on its synchronization details. 093 * </p> 094 * <p> 095 * Retrieval operations (including {@code get}) generally do not block, so they may overlap with update operations (including {@code put} and {@code remove}). 096 * Retrievals reflect the results of the most recently <em>completed</em> update operations holding upon their onset. For aggregate operations such as 097 * {@code putAll} and {@code clear}, concurrent retrievals may reflect insertion or removal of only some entries. Similarly, Iterators and Enumerations return 098 * elements reflecting the state of the hash map at some point at or since the creation of the iterator/enumeration. They do <em>not</em> throw 099 * {@link ConcurrentModificationException}. However, iterators are designed to be used by only one thread at a time. 100 * </p> 101 * <p> 102 * The allowed concurrency among update operations is guided by the optional {@code concurrencyLevel} constructor argument (default 103 * {@value #DEFAULT_CONCURRENCY_LEVEL}), which is used as a hint for internal sizing. The map is internally partitioned to try to permit the indicated number of 104 * concurrent updates without contention. Because placement in hash tables is essentially random, the actual concurrency will vary. Ideally, you should choose a 105 * value to accommodate as many threads as will ever concurrently modify the map. Using a significantly higher value than you need can waste space and time, and 106 * a significantly lower value can lead to thread contention. But overestimates and underestimates within an order of magnitude do not usually have much 107 * noticeable impact. A value of one is appropriate when it is known that only one thread will modify and all others will only read. Also, resizing this or any 108 * other kind of hash map is a relatively slow operation, so, when possible, it is a good idea that you provide estimates of expected map sizes in constructors. 109 * </p> 110 * <p> 111 * This class and its views and iterators implement all of the <em>optional</em> methods of the {@link Map} and {@link Iterator} interfaces. 112 * </p> 113 * <p> 114 * Like {@link Hashtable} but unlike {@link HashMap}, this class does <em>not</em> allow {@code null} to be used as a key or value. 115 * </p> 116 * <p> 117 * Provenance: Copied and edited from Apache Groovy git master at commit 77dc80a7512ceb2168b1bc866c3d0c69b002fe11; via Doug Lea, Jason T. Greene, with 118 * assistance from members of JCP JSR-166, and Hazelcast. 119 * </p> 120 * 121 * @param <K> The type of keys maintained by this map. 122 * @param <V> The type of mapped values. 123 */ 124public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> { 125 126 /** 127 * Builds new ConcurrentReferenceHashMap instances. 128 * <p> 129 * By default, keys are weak, and values are strong. 130 * </p> 131 * <p> 132 * The default values are: 133 * </p> 134 * <ul> 135 * <li>concurrency level: {@value #DEFAULT_CONCURRENCY_LEVEL}</li> 136 * <li>initial capacity: {@value #DEFAULT_INITIAL_CAPACITY}</li> 137 * <li>key reference type: {@link ReferenceType#WEAK}</li> 138 * <li>load factor: {@value #DEFAULT_LOAD_FACTOR}</li> 139 * <li>options: {@code null}</li> 140 * <li>source map: {@code null}</li> 141 * <li>value reference type: {@link ReferenceType#STRONG}</li> 142 * </ul> 143 * 144 * @param <K> The type of keys. 145 * @param <V> The type of values. 146 */ 147 public static class Builder<K, V> implements Supplier<ConcurrentReferenceHashMap<K, V>> { 148 149 private static final Map<?, ?> DEFAULT_SOURCE_MAP = null; 150 151 private int initialCapacity = DEFAULT_INITIAL_CAPACITY; 152 private float loadFactor = DEFAULT_LOAD_FACTOR; 153 private int concurrencyLevel = DEFAULT_CONCURRENCY_LEVEL; 154 private ReferenceType keyReferenceType = DEFAULT_KEY_TYPE; 155 private ReferenceType valueReferenceType = DEFAULT_VALUE_TYPE; 156 private EnumSet<Option> options = DEFAULT_OPTIONS; 157 @SuppressWarnings("unchecked") 158 private Map<? extends K, ? extends V> sourceMap = (Map<? extends K, ? extends V>) DEFAULT_SOURCE_MAP; 159 160 /** 161 * Constructs a new instances of {@link ConcurrentReferenceHashMap}. 162 */ 163 public Builder() { 164 // empty 165 } 166 167 /** 168 * Builds a new {@link ConcurrentReferenceHashMap}. 169 * <p> 170 * By default, keys are weak, and values are strong. 171 * </p> 172 * <p> 173 * The default values are: 174 * </p> 175 * <ul> 176 * <li>concurrency level: {@value #DEFAULT_CONCURRENCY_LEVEL}</li> 177 * <li>initial capacity: {@value #DEFAULT_INITIAL_CAPACITY}</li> 178 * <li>key reference type: {@link ReferenceType#WEAK}</li> 179 * <li>load factor: {@value #DEFAULT_LOAD_FACTOR}</li> 180 * <li>options: {@code null}</li> 181 * <li>source map: {@code null}</li> 182 * <li>value reference type: {@link ReferenceType#STRONG}</li> 183 * </ul> 184 */ 185 @Override 186 public ConcurrentReferenceHashMap<K, V> get() { 187 final ConcurrentReferenceHashMap<K, V> map = new ConcurrentReferenceHashMap<>(initialCapacity, loadFactor, concurrencyLevel, keyReferenceType, 188 valueReferenceType, options); 189 if (sourceMap != null) { 190 map.putAll(sourceMap); 191 } 192 return map; 193 } 194 195 /** 196 * Sets the estimated number of concurrently updating threads. The implementation performs internal sizing to try to accommodate this many threads. 197 * 198 * @param concurrencyLevel estimated number of concurrently updating threads 199 * @return {@code this} instance. 200 */ 201 public Builder<K, V> setConcurrencyLevel(final int concurrencyLevel) { 202 this.concurrencyLevel = concurrencyLevel; 203 return this; 204 } 205 206 /** 207 * Sets the initial capacity. The implementation performs internal sizing to accommodate this many elements. 208 * 209 * @param initialCapacity The initial capacity. 210 * @return {@code this} instance. 211 */ 212 public Builder<K, V> setInitialCapacity(final int initialCapacity) { 213 this.initialCapacity = initialCapacity; 214 return this; 215 } 216 217 /** 218 * Sets the reference type to use for keys. 219 * 220 * @param keyReferenceType The reference type to use for keys. 221 * @return {@code this} instance. 222 */ 223 public Builder<K, V> setKeyReferenceType(final ReferenceType keyReferenceType) { 224 this.keyReferenceType = keyReferenceType; 225 return this; 226 } 227 228 /** 229 * Sets the load factor factor, used to control resizing. Resizing may be performed when the average number of elements per bin exceeds this threshold. 230 * 231 * @param loadFactor The load factor factor, used to control resizing 232 * @return {@code this} instance. 233 */ 234 public Builder<K, V> setLoadFactor(final float loadFactor) { 235 this.loadFactor = loadFactor; 236 return this; 237 } 238 239 /** 240 * Sets the behavioral options. 241 * 242 * @param options The behavioral options. 243 * @return {@code this} instance. 244 */ 245 public Builder<K, V> setOptions(final EnumSet<Option> options) { 246 this.options = options; 247 return this; 248 } 249 250 /** 251 * Sets the values to load into a new map. 252 * 253 * @param sourceMap The values to load into a new map. 254 * @return {@code this} instance. 255 */ 256 public Builder<K, V> setSourceMap(final Map<? extends K, ? extends V> sourceMap) { 257 this.sourceMap = sourceMap; 258 return this; 259 } 260 261 /** 262 * Sets the reference type to use for values. 263 * 264 * @param valueReferenceType The reference type to use for values. 265 * @return {@code this} instance. 266 */ 267 public Builder<K, V> setValueReferenceType(final ReferenceType valueReferenceType) { 268 this.valueReferenceType = valueReferenceType; 269 return this; 270 } 271 272 /** 273 * Sets key reference type to {@link ReferenceType#SOFT}. 274 * 275 * @return {@code this} instance. 276 */ 277 public Builder<K, V> softKeys() { 278 setKeyReferenceType(ReferenceType.SOFT); 279 return this; 280 } 281 282 /** 283 * Sets value reference type to {@link ReferenceType#SOFT}. 284 * 285 * @return {@code this} instance. 286 */ 287 public Builder<K, V> softValues() { 288 setValueReferenceType(ReferenceType.SOFT); 289 return this; 290 } 291 292 /** 293 * Sets key reference type to {@link ReferenceType#STRONG}. 294 * 295 * @return {@code this} instance. 296 */ 297 public Builder<K, V> strongKeys() { 298 setKeyReferenceType(ReferenceType.STRONG); 299 return this; 300 } 301 302 /** 303 * Sets value reference type to {@link ReferenceType#STRONG}. 304 * 305 * @return {@code this} instance. 306 */ 307 public Builder<K, V> strongValues() { 308 setValueReferenceType(ReferenceType.STRONG); 309 return this; 310 } 311 312 /** 313 * Sets key reference type to {@link ReferenceType#WEAK}. 314 * 315 * @return {@code this} instance. 316 */ 317 public Builder<K, V> weakKeys() { 318 setKeyReferenceType(ReferenceType.WEAK); 319 return this; 320 } 321 322 /** 323 * Sets value reference type to {@link ReferenceType#WEAK}. 324 * 325 * @return {@code this} instance. 326 */ 327 public Builder<K, V> weakValues() { 328 setValueReferenceType(ReferenceType.WEAK); 329 return this; 330 } 331 332 } 333 334 /** 335 * The basic strategy is to subdivide the table among Segments, each of which itself is a concurrently readable hash table. 336 */ 337 private final class CachedEntryIterator extends HashIterator implements Iterator<Entry<K, V>> { 338 private final InitializableEntry<K, V> entry = new InitializableEntry<>(); 339 340 @Override 341 public Entry<K, V> next() { 342 final HashEntry<K, V> e = super.nextEntry(); 343 return entry.init(e.key(), e.value()); 344 } 345 } 346 347 private final class EntryIterator extends HashIterator implements Iterator<Entry<K, V>> { 348 @Override 349 public Entry<K, V> next() { 350 final HashEntry<K, V> e = super.nextEntry(); 351 return new WriteThroughEntry(e.key(), e.value()); 352 } 353 } 354 355 private final class EntrySet extends AbstractSet<Entry<K, V>> { 356 357 private final boolean cached; 358 359 private EntrySet(final boolean cached) { 360 this.cached = cached; 361 } 362 363 @Override 364 public void clear() { 365 ConcurrentReferenceHashMap.this.clear(); 366 } 367 368 @Override 369 public boolean contains(final Object o) { 370 if (!(o instanceof Map.Entry)) { 371 return false; 372 } 373 final V v = ConcurrentReferenceHashMap.this.get(((Entry<?, ?>) o).getKey()); 374 return Objects.equals(v, ((Entry<?, ?>) o).getValue()); 375 } 376 377 @Override 378 public boolean isEmpty() { 379 return ConcurrentReferenceHashMap.this.isEmpty(); 380 } 381 382 @Override 383 public Iterator<Entry<K, V>> iterator() { 384 return cached ? new CachedEntryIterator() : new EntryIterator(); 385 } 386 387 @Override 388 public boolean remove(final Object o) { 389 if (!(o instanceof Map.Entry)) { 390 return false; 391 } 392 final Entry<?, ?> e = (Entry<?, ?>) o; 393 return ConcurrentReferenceHashMap.this.remove(e.getKey(), e.getValue()); 394 } 395 396 @Override 397 public int size() { 398 return ConcurrentReferenceHashMap.this.size(); 399 } 400 } 401 402 /** 403 * ConcurrentReferenceHashMap list entry. Note that this is never exported out as a user-visible Map.Entry. 404 * <p> 405 * Because the value field is volatile, not final, it is legal with respect to the Java Memory Model for an unsynchronized reader to see null instead of 406 * initial value when read via a data race. Although a reordering leading to this is not likely to ever actually occur, the Segment.readValueUnderLock 407 * method is used as a backup in case a null (pre-initialized) value is ever seen in an unsynchronized access method. 408 * </p> 409 */ 410 private static final class HashEntry<K, V> { 411 412 @SuppressWarnings("unchecked") 413 static <K, V> HashEntry<K, V>[] newArray(final int i) { 414 return new HashEntry[i]; 415 } 416 417 private final Object keyRef; 418 private final int hash; 419 private volatile Object valueRef; 420 private final HashEntry<K, V> next; 421 422 HashEntry(final K key, final int hash, final HashEntry<K, V> next, final V value, final ReferenceType keyType, final ReferenceType valueType, 423 final ReferenceQueue<Object> refQueue) { 424 this.hash = hash; 425 this.next = next; 426 this.keyRef = newKeyReference(key, keyType, refQueue); 427 this.valueRef = newValueReference(value, valueType, refQueue); 428 } 429 430 @SuppressWarnings("unchecked") 431 V dereferenceValue(final Object value) { 432 if (value instanceof KeyReference) { 433 return ((Reference<V>) value).get(); 434 } 435 return (V) value; 436 } 437 438 @SuppressWarnings("unchecked") 439 K key() { 440 if (keyRef instanceof KeyReference) { 441 return ((Reference<K>) keyRef).get(); 442 } 443 return (K) keyRef; 444 } 445 446 Object newKeyReference(final K key, final ReferenceType keyType, final ReferenceQueue<Object> refQueue) { 447 if (keyType == ReferenceType.WEAK) { 448 return new WeakKeyReference<>(key, hash, refQueue); 449 } 450 if (keyType == ReferenceType.SOFT) { 451 return new SoftKeyReference<>(key, hash, refQueue); 452 } 453 454 return key; 455 } 456 457 Object newValueReference(final V value, final ReferenceType valueType, final ReferenceQueue<Object> refQueue) { 458 if (valueType == ReferenceType.WEAK) { 459 return new WeakValueReference<>(value, keyRef, hash, refQueue); 460 } 461 if (valueType == ReferenceType.SOFT) { 462 return new SoftValueReference<>(value, keyRef, hash, refQueue); 463 } 464 465 return value; 466 } 467 468 void setValue(final V value, final ReferenceType valueType, final ReferenceQueue<Object> refQueue) { 469 this.valueRef = newValueReference(value, valueType, refQueue); 470 } 471 472 V value() { 473 return dereferenceValue(valueRef); 474 } 475 } 476 477 private abstract class HashIterator { 478 private int nextSegmentIndex; 479 private int nextTableIndex; 480 private HashEntry<K, V>[] currentTable; 481 private HashEntry<K, V> nextEntry; 482 private HashEntry<K, V> lastReturned; 483 // Strong reference to weak key (prevents gc) 484 private K currentKey; 485 486 private HashIterator() { 487 nextSegmentIndex = segments.length - 1; 488 nextTableIndex = -1; 489 advance(); 490 } 491 492 final void advance() { 493 if (nextEntry != null && (nextEntry = nextEntry.next) != null) { 494 return; 495 } 496 while (nextTableIndex >= 0) { 497 if ((nextEntry = currentTable[nextTableIndex--]) != null) { 498 return; 499 } 500 } 501 while (nextSegmentIndex >= 0) { 502 final Segment<K, V> seg = segments[nextSegmentIndex--]; 503 if (seg.count != 0) { 504 currentTable = seg.table; 505 for (int j = currentTable.length - 1; j >= 0; --j) { 506 if ((nextEntry = currentTable[j]) != null) { 507 nextTableIndex = j - 1; 508 return; 509 } 510 } 511 } 512 } 513 } 514 515 public boolean hasMoreElements() { 516 return hasNext(); 517 } 518 519 public boolean hasNext() { 520 while (nextEntry != null) { 521 if (nextEntry.key() != null) { 522 return true; 523 } 524 advance(); 525 } 526 return false; 527 } 528 529 HashEntry<K, V> nextEntry() { 530 do { 531 if (nextEntry == null) { 532 throw new NoSuchElementException(); 533 } 534 lastReturned = nextEntry; 535 currentKey = lastReturned.key(); 536 advance(); 537 } while /* Skip GC'd keys */ (currentKey == null); 538 return lastReturned; 539 } 540 541 public void remove() { 542 if (lastReturned == null) { 543 throw new IllegalStateException(); 544 } 545 ConcurrentReferenceHashMap.this.remove(currentKey); 546 lastReturned = null; 547 } 548 } 549 550 private static final class InitializableEntry<K, V> implements Entry<K, V> { 551 private K key; 552 private V value; 553 554 @Override 555 public K getKey() { 556 return key; 557 } 558 559 @Override 560 public V getValue() { 561 return value; 562 } 563 564 public Entry<K, V> init(final K key, final V value) { 565 this.key = key; 566 this.value = value; 567 return this; 568 } 569 570 /** 571 * Always throws {@link UnsupportedOperationException}. 572 * 573 * @param value Ignored. 574 * @throws UnsupportedOperationException Always thrown. 575 */ 576 @Override 577 public V setValue(final V value) { 578 throw new UnsupportedOperationException(); 579 } 580 } 581 582 private final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> { 583 @Override 584 public K next() { 585 return super.nextEntry().key(); 586 } 587 588 @Override 589 public K nextElement() { 590 return super.nextEntry().key(); 591 } 592 } 593 594 private interface KeyReference { 595 int keyHash(); 596 597 Object keyRef(); 598 } 599 600 private final class KeySet extends AbstractSet<K> { 601 @Override 602 public void clear() { 603 ConcurrentReferenceHashMap.this.clear(); 604 } 605 606 @Override 607 public boolean contains(final Object o) { 608 return ConcurrentReferenceHashMap.this.containsKey(o); 609 } 610 611 @Override 612 public boolean isEmpty() { 613 return ConcurrentReferenceHashMap.this.isEmpty(); 614 } 615 616 @Override 617 public Iterator<K> iterator() { 618 return new KeyIterator(); 619 } 620 621 @Override 622 public boolean remove(final Object o) { 623 return ConcurrentReferenceHashMap.this.remove(o) != null; 624 } 625 626 @Override 627 public int size() { 628 return ConcurrentReferenceHashMap.this.size(); 629 } 630 } 631 632 /** 633 * Enumerates eehavior-changing configuration options for the map. 634 */ 635 public enum Option { 636 637 /** 638 * Indicates that referential-equality (== instead of .equals()) should be used when locating keys. This offers similar behavior to 639 * {@link IdentityHashMap} 640 */ 641 IDENTITY_COMPARISONS 642 } 643 644 /** 645 * Enumerates which Java reference type should be used to refer to a key and/or value. 646 */ 647 public enum ReferenceType { 648 649 /** 650 * Indicates a normal Java strong reference should be used 651 */ 652 STRONG, 653 654 /** 655 * Indicates a {@link WeakReference} should be used 656 */ 657 WEAK, 658 659 /** 660 * Indicates a {@link SoftReference} should be used 661 */ 662 SOFT 663 } 664 665 /** 666 * Segments are specialized versions of hash tables. This subclasses from ReentrantLock opportunistically, just to simplify some locking and avoid separate 667 * construction. 668 * <p> 669 * Segments maintain a table of entry lists that are ALWAYS kept in a consistent state, so they can be read without locking. Next fields of nodes are 670 * immutable (final). All list additions are performed at the front of each bin. This makes it easy to check changes, and also fast to traverse. When nodes 671 * would otherwise be changed, new nodes are created to replace them. This works well for hash tables since the bin lists tend to be short. (The average 672 * length is less than two for the default load factor threshold.) 673 * </p> 674 * <p> 675 * Read operations can thus proceed without locking, but rely on selected uses of volatiles to ensure that completed write operations performed by other 676 * threads are noticed. For most purposes, the "count" field, tracking the number of elements, serves as that volatile variable ensuring visibility. This is 677 * convenient because this field needs to be read in many read operations anyway: 678 * </p> 679 * <ul> 680 * <li>All (unsynchronized) read operations must first read the "count" field, and should not look at table entries if it is 0.</li> 681 * <li>All (synchronized) write operations should write to the "count" field after structurally changing any bin. The operations must not take any action 682 * that could even momentarily cause a concurrent read operation to see inconsistent data. This is made easier by the nature of the read operations in Map. 683 * For example, no operation can reveal that the table has grown but the threshold has not yet been updated, so there are no atomicity requirements for this 684 * with respect to reads.</li> 685 * </ul> 686 * <p> 687 * As a guide, all critical volatile reads and writes to the count field are marked in code comments. 688 * </p> 689 * 690 * @param <K> The type of keys maintained by this Segment. 691 * @param <V> The type of mapped values. 692 */ 693 private static final class Segment<K, V> extends ReentrantLock { 694 695 private static final long serialVersionUID = 1L; 696 697 @SuppressWarnings("unchecked") 698 static <K, V> Segment<K, V>[] newArray(final int i) { 699 return new Segment[i]; 700 } 701 702 /** 703 * The number of elements in this segment's region. 704 */ 705 // @SuppressFBWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification = 706 // "I trust Doug Lea's technical decision") 707 private transient volatile int count; 708 709 /** 710 * Number of updates that alter the size of the table. This is used during bulk-read methods to make sure they see a consistent snapshot: If modCounts 711 * change during a traversal of segments computing size or checking containsValue, then we might have an inconsistent view of state so (usually) we must 712 * retry. 713 */ 714 // @SuppressFBWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification = 715 // "I trust Doug Lea's technical decision") 716 private transient int modCount; 717 718 /** 719 * The table is rehashed when its size exceeds this threshold. (The value of this field is always <code>(int)(capacity * 720 * loadFactor)</code>.) 721 */ 722 private transient int threshold; 723 724 /** 725 * The per-segment table. 726 */ 727 private transient volatile HashEntry<K, V>[] table; 728 729 /** 730 * The load factor for the hash table. Even though this value is same for all segments, it is replicated to avoid needing links to outer object. 731 */ 732 private final float loadFactor; 733 734 /** 735 * The collected weak-key reference queue for this segment. This should be (re)initialized whenever table is assigned, 736 */ 737 private transient volatile ReferenceQueue<Object> refQueue; 738 739 private final ReferenceType keyType; 740 741 private final ReferenceType valueType; 742 743 private final boolean identityComparisons; 744 745 Segment(final int initialCapacity, final float loadFactor, final ReferenceType keyType, final ReferenceType valueType, 746 final boolean identityComparisons) { 747 this.loadFactor = loadFactor; 748 this.keyType = keyType; 749 this.valueType = valueType; 750 this.identityComparisons = identityComparisons; 751 setTable(HashEntry.<K, V>newArray(initialCapacity)); 752 } 753 754 V apply(final K key, final int hash, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 755 lock(); 756 try { 757 final V oldValue = get(key, hash); 758 final V newValue = remappingFunction.apply(key, oldValue); 759 760 if (newValue == null) { 761 // delete mapping 762 if (oldValue != null) { 763 // something to remove 764 removeInternal(key, hash, oldValue, false); 765 } 766 return null; 767 } 768 // add or replace old mapping 769 putInternal(key, hash, newValue, null, false); 770 return newValue; 771 } finally { 772 unlock(); 773 } 774 } 775 776 V applyIfPresent(final K key, final int hash, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 777 lock(); 778 try { 779 final V oldValue = get(key, hash); 780 if (oldValue == null) { 781 return null; 782 } 783 784 final V newValue = remappingFunction.apply(key, oldValue); 785 786 if (newValue == null) { 787 removeInternal(key, hash, oldValue, false); 788 return null; 789 } 790 putInternal(key, hash, newValue, null, false); 791 return newValue; 792 } finally { 793 unlock(); 794 } 795 } 796 797 void clear() { 798 if (count != 0) { 799 lock(); 800 try { 801 final HashEntry<K, V>[] tab = table; 802 Arrays.fill(tab, null); 803 ++modCount; 804 // replace the reference queue to avoid unnecessary stale cleanups 805 refQueue = new ReferenceQueue<>(); 806 // write-volatile 807 count = 0; 808 } finally { 809 unlock(); 810 } 811 } 812 } 813 814 boolean containsKey(final Object key, final int hash) { 815 // read-volatile 816 if (count != 0) { 817 HashEntry<K, V> e = getFirst(hash); 818 while (e != null) { 819 if (e.hash == hash && keyEq(key, e.key())) { 820 return true; 821 } 822 e = e.next; 823 } 824 } 825 return false; 826 } 827 828 boolean containsValue(final Object value) { 829 // read-volatile 830 if (count != 0) { 831 final HashEntry<K, V>[] tab = table; 832 final int len = tab.length; 833 for (int i = 0; i < len; i++) { 834 for (HashEntry<K, V> e = tab[i]; e != null; e = e.next) { 835 final Object opaque = e.valueRef; 836 final V v; 837 if (opaque == null) { 838 // recheck 839 v = readValueUnderLock(e); 840 } else { 841 v = e.dereferenceValue(opaque); 842 } 843 if (Objects.equals(value, v)) { 844 return true; 845 } 846 } 847 } 848 } 849 return false; 850 } 851 852 /* Specialized implementations of map methods */ 853 V get(final Object key, final int hash) { 854 // read-volatile 855 if (count != 0) { 856 HashEntry<K, V> e = getFirst(hash); 857 while (e != null) { 858 if (e.hash == hash && keyEq(key, e.key())) { 859 final Object opaque = e.valueRef; 860 if (opaque != null) { 861 return e.dereferenceValue(opaque); 862 } 863 // recheck 864 return readValueUnderLock(e); 865 } 866 e = e.next; 867 } 868 } 869 return null; 870 } 871 872 /** 873 * Gets properly casted first entry of bin for given hash. 874 */ 875 HashEntry<K, V> getFirst(final int hash) { 876 final HashEntry<K, V>[] tab = table; 877 return tab[hash & tab.length - 1]; 878 } 879 880 V getValue(final K key, final V value, final Function<? super K, ? extends V> function) { 881 return value != null ? value : function.apply(key); 882 } 883 884 private boolean keyEq(final Object src, final Object dest) { 885 return identityComparisons ? src == dest : Objects.equals(src, dest); 886 } 887 888 HashEntry<K, V> newHashEntry(final K key, final int hash, final HashEntry<K, V> next, final V value) { 889 return new HashEntry<>(key, hash, next, value, keyType, valueType, refQueue); 890 } 891 892 /** 893 * This method must be called with exactly one of {@code value} and {@code function} non-null. 894 **/ 895 V put(final K key, final int hash, final V value, final Function<? super K, ? extends V> function, final boolean onlyIfAbsent) { 896 lock(); 897 try { 898 return putInternal(key, hash, value, function, onlyIfAbsent); 899 } finally { 900 unlock(); 901 } 902 } 903 904 private V putInternal(final K key, final int hash, final V value, final Function<? super K, ? extends V> function, final boolean onlyIfAbsent) { 905 removeStale(); 906 int c = count; 907 // ensure capacity 908 if (c++ > threshold) { 909 final int reduced = rehash(); 910 // adjust from possible weak cleanups 911 if (reduced > 0) { 912 // write-volatile 913 count = (c -= reduced) - 1; 914 } 915 } 916 final HashEntry<K, V>[] tab = table; 917 final int index = hash & tab.length - 1; 918 final HashEntry<K, V> first = tab[index]; 919 HashEntry<K, V> e = first; 920 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) { 921 e = e.next; 922 } 923 final V resultValue; 924 if (e != null) { 925 resultValue = e.value(); 926 if (!onlyIfAbsent) { 927 e.setValue(getValue(key, value, function), valueType, refQueue); 928 } 929 } else { 930 final V v = getValue(key, value, function); 931 resultValue = function != null ? v : null; 932 933 if (v != null) { 934 ++modCount; 935 tab[index] = newHashEntry(key, hash, first, v); 936 // write-volatile 937 count = c; 938 } 939 } 940 return resultValue; 941 } 942 943 /** 944 * Reads value field of an entry under lock. Called if value field ever appears to be null. This is possible only if a compiler happens to reorder a 945 * HashEntry initialization with its table assignment, which is legal under memory model but is not known to ever occur. 946 */ 947 V readValueUnderLock(final HashEntry<K, V> e) { 948 lock(); 949 try { 950 removeStale(); 951 return e.value(); 952 } finally { 953 unlock(); 954 } 955 } 956 957 int rehash() { 958 final HashEntry<K, V>[] oldTable = table; 959 final int oldCapacity = oldTable.length; 960 if (oldCapacity >= MAXIMUM_CAPACITY) { 961 return 0; 962 } 963 // 964 // Reclassify nodes in each list to new Map. Because we are using power-of-two expansion, the elements from each bin must either stay at the same 965 // index, or move with a power of two offset. We eliminate unnecessary node creation by catching cases where old nodes can be reused because their 966 // next fields won't change. Statistically, at the default threshold, only about one-sixth of them need cloning when a table doubles. The nodes they 967 // replace will be garbage collectable as soon as they are no longer referenced by any reader thread that may be in the midst of traversing table 968 // right now. 969 // 970 final HashEntry<K, V>[] newTable = HashEntry.newArray(oldCapacity << 1); 971 threshold = (int) (newTable.length * loadFactor); 972 final int sizeMask = newTable.length - 1; 973 int reduce = 0; 974 for (int i = 0; i < oldCapacity; i++) { 975 // We need to guarantee that any existing reads of old Map can 976 // proceed. So we cannot yet null out each bin. 977 final HashEntry<K, V> e = oldTable[i]; 978 if (e != null) { 979 final HashEntry<K, V> next = e.next; 980 final int idx = e.hash & sizeMask; 981 // Single node on list 982 if (next == null) { 983 newTable[idx] = e; 984 } else { 985 // Reuse trailing consecutive sequence at same slot 986 HashEntry<K, V> lastRun = e; 987 int lastIdx = idx; 988 for (HashEntry<K, V> last = next; last != null; last = last.next) { 989 final int k = last.hash & sizeMask; 990 if (k != lastIdx) { 991 lastIdx = k; 992 lastRun = last; 993 } 994 } 995 newTable[lastIdx] = lastRun; 996 // Clone all remaining nodes 997 for (HashEntry<K, V> p = e; p != lastRun; p = p.next) { 998 // Skip GC'd weak refs 999 final K key = p.key(); 1000 if (key == null) { 1001 reduce++; 1002 continue; 1003 } 1004 final int k = p.hash & sizeMask; 1005 final HashEntry<K, V> n = newTable[k]; 1006 newTable[k] = newHashEntry(key, p.hash, n, p.value()); 1007 } 1008 } 1009 } 1010 } 1011 table = newTable; 1012 return reduce; 1013 } 1014 1015 /** 1016 * Removes match on key only if value is null, else match both. 1017 */ 1018 V remove(final Object key, final int hash, final Object value, final boolean refRemove) { 1019 lock(); 1020 try { 1021 return removeInternal(key, hash, value, refRemove); 1022 } finally { 1023 unlock(); 1024 } 1025 } 1026 1027 private V removeInternal(final Object key, final int hash, final Object value, final boolean refRemove) { 1028 if (!refRemove) { 1029 removeStale(); 1030 } 1031 int c = count - 1; 1032 final HashEntry<K, V>[] tab = table; 1033 final int index = hash & tab.length - 1; 1034 final HashEntry<K, V> first = tab[index]; 1035 HashEntry<K, V> e = first; 1036 // a ref remove operation compares the Reference instance 1037 while (e != null && key != e.keyRef && (refRemove || hash != e.hash || !keyEq(key, e.key()))) { 1038 e = e.next; 1039 } 1040 1041 V oldValue = null; 1042 if (e != null) { 1043 final V v = e.value(); 1044 if (value == null || value.equals(v)) { 1045 oldValue = v; 1046 // All entries following removed node can stay 1047 // in list, but all preceding ones need to be 1048 // cloned. 1049 ++modCount; 1050 HashEntry<K, V> newFirst = e.next; 1051 for (HashEntry<K, V> p = first; p != e; p = p.next) { 1052 final K pKey = p.key(); 1053 // Skip GC'd keys 1054 if (pKey == null) { 1055 c--; 1056 continue; 1057 } 1058 newFirst = newHashEntry(pKey, p.hash, newFirst, p.value()); 1059 } 1060 tab[index] = newFirst; 1061 // write-volatile 1062 count = c; 1063 } 1064 } 1065 return oldValue; 1066 } 1067 1068 void removeStale() { 1069 KeyReference ref; 1070 while ((ref = (KeyReference) refQueue.poll()) != null) { 1071 remove(ref.keyRef(), ref.keyHash(), null, true); 1072 } 1073 } 1074 1075 V replace(final K key, final int hash, final V newValue) { 1076 lock(); 1077 try { 1078 return replaceInternal(key, hash, newValue); 1079 } finally { 1080 unlock(); 1081 } 1082 } 1083 1084 boolean replace(final K key, final int hash, final V oldValue, final V newValue) { 1085 lock(); 1086 try { 1087 return replaceInternal2(key, hash, oldValue, newValue); 1088 } finally { 1089 unlock(); 1090 } 1091 } 1092 1093 private V replaceInternal(final K key, final int hash, final V newValue) { 1094 removeStale(); 1095 HashEntry<K, V> e = getFirst(hash); 1096 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) { 1097 e = e.next; 1098 } 1099 V oldValue = null; 1100 if (e != null) { 1101 oldValue = e.value(); 1102 e.setValue(newValue, valueType, refQueue); 1103 } 1104 return oldValue; 1105 } 1106 1107 private boolean replaceInternal2(final K key, final int hash, final V oldValue, final V newValue) { 1108 removeStale(); 1109 HashEntry<K, V> e = getFirst(hash); 1110 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) { 1111 e = e.next; 1112 } 1113 boolean replaced = false; 1114 if (e != null && Objects.equals(oldValue, e.value())) { 1115 replaced = true; 1116 e.setValue(newValue, valueType, refQueue); 1117 } 1118 return replaced; 1119 } 1120 1121 /** 1122 * Sets table to new HashEntry array. Call only while holding lock or in constructor. 1123 */ 1124 void setTable(final HashEntry<K, V>[] newTable) { 1125 threshold = (int) (newTable.length * loadFactor); 1126 table = newTable; 1127 refQueue = new ReferenceQueue<>(); 1128 } 1129 } 1130 1131 private static class SimpleEntry<K, V> implements Entry<K, V> { 1132 1133 private static boolean eq(final Object o1, final Object o2) { 1134 return Objects.equals(o1, o2); 1135 } 1136 1137 private final K key; 1138 1139 private V value; 1140 1141 SimpleEntry(final K key, final V value) { 1142 this.key = key; 1143 this.value = value; 1144 } 1145 1146 @Override 1147 public boolean equals(final Object o) { 1148 if (!(o instanceof Map.Entry)) { 1149 return false; 1150 } 1151 final Entry<?, ?> e = (Entry<?, ?>) o; 1152 return eq(key, e.getKey()) && eq(value, e.getValue()); 1153 } 1154 1155 @Override 1156 public K getKey() { 1157 return key; 1158 } 1159 1160 @Override 1161 public V getValue() { 1162 return value; 1163 } 1164 1165 @Override 1166 public int hashCode() { 1167 return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); 1168 } 1169 1170 @Override 1171 public V setValue(final V value) { 1172 final V oldValue = this.value; 1173 this.value = value; 1174 return oldValue; 1175 } 1176 1177 @Override 1178 public String toString() { 1179 return key + "=" + value; 1180 } 1181 } 1182 1183 /** 1184 * A soft-key reference which stores the key hash needed for reclamation. 1185 */ 1186 private static final class SoftKeyReference<K> extends SoftReference<K> implements KeyReference { 1187 1188 private final int hash; 1189 1190 SoftKeyReference(final K key, final int hash, final ReferenceQueue<Object> refQueue) { 1191 super(key, refQueue); 1192 this.hash = hash; 1193 } 1194 1195 @Override 1196 public int keyHash() { 1197 return hash; 1198 } 1199 1200 @Override 1201 public Object keyRef() { 1202 return this; 1203 } 1204 } 1205 1206 private static final class SoftValueReference<V> extends SoftReference<V> implements KeyReference { 1207 private final Object keyRef; 1208 private final int hash; 1209 1210 SoftValueReference(final V value, final Object keyRef, final int hash, final ReferenceQueue<Object> refQueue) { 1211 super(value, refQueue); 1212 this.keyRef = keyRef; 1213 this.hash = hash; 1214 } 1215 1216 @Override 1217 public int keyHash() { 1218 return hash; 1219 } 1220 1221 @Override 1222 public Object keyRef() { 1223 return keyRef; 1224 } 1225 } 1226 1227 private final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> { 1228 @Override 1229 public V next() { 1230 return super.nextEntry().value(); 1231 } 1232 1233 @Override 1234 public V nextElement() { 1235 return super.nextEntry().value(); 1236 } 1237 } 1238 1239 private final class Values extends AbstractCollection<V> { 1240 @Override 1241 public void clear() { 1242 ConcurrentReferenceHashMap.this.clear(); 1243 } 1244 1245 @Override 1246 public boolean contains(final Object o) { 1247 return ConcurrentReferenceHashMap.this.containsValue(o); 1248 } 1249 1250 @Override 1251 public boolean isEmpty() { 1252 return ConcurrentReferenceHashMap.this.isEmpty(); 1253 } 1254 1255 @Override 1256 public Iterator<V> iterator() { 1257 return new ValueIterator(); 1258 } 1259 1260 @Override 1261 public int size() { 1262 return ConcurrentReferenceHashMap.this.size(); 1263 } 1264 } 1265 1266 /** 1267 * A weak-key reference which stores the key hash needed for reclamation. 1268 */ 1269 private static final class WeakKeyReference<K> extends WeakReference<K> implements KeyReference { 1270 private final int hash; 1271 1272 WeakKeyReference(final K key, final int hash, final ReferenceQueue<Object> refQueue) { 1273 super(key, refQueue); 1274 this.hash = hash; 1275 } 1276 1277 @Override 1278 public int keyHash() { 1279 return hash; 1280 } 1281 1282 @Override 1283 public Object keyRef() { 1284 return this; 1285 } 1286 } 1287 1288 private static final class WeakValueReference<V> extends WeakReference<V> implements KeyReference { 1289 private final Object keyRef; 1290 private final int hash; 1291 1292 WeakValueReference(final V value, final Object keyRef, final int hash, final ReferenceQueue<Object> refQueue) { 1293 super(value, refQueue); 1294 this.keyRef = keyRef; 1295 this.hash = hash; 1296 } 1297 1298 @Override 1299 public int keyHash() { 1300 return hash; 1301 } 1302 1303 @Override 1304 public Object keyRef() { 1305 return keyRef; 1306 } 1307 } 1308 1309 /** 1310 * Custom Entry class used by EntryIterator.next(), that relays setValue changes to the underlying map. 1311 */ 1312 private final class WriteThroughEntry extends SimpleEntry<K, V> { 1313 1314 private WriteThroughEntry(final K k, final V v) { 1315 super(k, v); 1316 } 1317 1318 /** 1319 * Set our entry's value and writes it through to the map. The value to return is somewhat arbitrary: since a WriteThroughEntry does not necessarily 1320 * track asynchronous changes, the most recent "previous" value could be different from what we return (or could even have been removed in which case 1321 * the put will re-establish). We do not and cannot guarantee more. 1322 */ 1323 @Override 1324 public V setValue(final V value) { 1325 Objects.requireNonNull(value, "value"); 1326 final V v = super.setValue(value); 1327 ConcurrentReferenceHashMap.this.put(getKey(), value); 1328 return v; 1329 } 1330 } 1331 1332 static final ReferenceType DEFAULT_KEY_TYPE = ReferenceType.WEAK; 1333 1334 static final ReferenceType DEFAULT_VALUE_TYPE = ReferenceType.STRONG; 1335 1336 static final EnumSet<Option> DEFAULT_OPTIONS = null; 1337 1338 /** 1339 * The default initial capacity for this table, used when not otherwise specified in a constructor. 1340 */ 1341 static final int DEFAULT_INITIAL_CAPACITY = 16; 1342 1343 /** 1344 * The default load factor for this table, used when not otherwise specified in a constructor. 1345 */ 1346 static final float DEFAULT_LOAD_FACTOR = 0.75f; 1347 1348 /** 1349 * The default concurrency level for this table, used when not otherwise specified in a constructor. 1350 */ 1351 static final int DEFAULT_CONCURRENCY_LEVEL = 16; 1352 1353 /** 1354 * The maximum capacity, used if a higher value is implicitly specified by either of the constructors with arguments. MUST be a power of two <= 1355 * 1<<30 to ensure that entries are indexable using ints. 1356 */ 1357 private static final int MAXIMUM_CAPACITY = 1 << 30; 1358 1359 /** 1360 * The maximum number of segments to allow; used to bound constructor arguments. 1361 */ 1362 private static final int MAX_SEGMENTS = 1 << 16; 1363 1364 /** 1365 * Number of unsynchronized retries in size and containsValue methods before resorting to locking. This is used to avoid unbounded retries if tables undergo 1366 * continuous modification which would make it impossible to obtain an accurate result. 1367 */ 1368 private static final int RETRIES_BEFORE_LOCK = 2; 1369 1370 /** 1371 * Creates a new Builder. 1372 * <p> 1373 * By default, keys are weak, and values are strong. 1374 * </p> 1375 * <p> 1376 * The default values are: 1377 * </p> 1378 * <ul> 1379 * <li>concurrency level: {@value #DEFAULT_CONCURRENCY_LEVEL}</li> 1380 * <li>initial capacity: {@value #DEFAULT_INITIAL_CAPACITY}</li> 1381 * <li>key reference type: {@link ReferenceType#WEAK}</li> 1382 * <li>load factor: {@value #DEFAULT_LOAD_FACTOR}</li> 1383 * <li>options: {@code null}</li> 1384 * <li>source map: {@code null}</li> 1385 * <li>value reference type: {@link ReferenceType#STRONG}</li> 1386 * </ul> 1387 * 1388 * @param <K> The type of keys. 1389 * @param <V> The type of values. 1390 * @return A new Builder. 1391 */ 1392 public static <K, V> Builder<K, V> builder() { 1393 return new Builder<>(); 1394 } 1395 1396 /** 1397 * Applies a supplemental hash function to a given hashCode, which defends against poor quality hash functions. This is critical because 1398 * ConcurrentReferenceHashMap uses power-of-two length hash tables, that otherwise encounter collisions for hashCodes that do not differ in lower or upper 1399 * bits. 1400 */ 1401 private static int hash(int h) { 1402 // Spread bits to regularize both segment and index locations, 1403 // using variant of single-word Wang/Jenkins hash. 1404 h += h << 15 ^ 0xffffcd7d; 1405 h ^= h >>> 10; 1406 h += h << 3; 1407 h ^= h >>> 6; 1408 h += (h << 2) + (h << 14); 1409 return h ^ h >>> 16; 1410 } 1411 1412 /** 1413 * Mask value for indexing into segments. The upper bits of a key's hash code are used to choose the segment. 1414 */ 1415 private final int segmentMask; 1416 1417 /** 1418 * Shift value for indexing within segments. 1419 */ 1420 private final int segmentShift; 1421 1422 /** 1423 * The segments, each of which is a specialized hash table 1424 */ 1425 private final Segment<K, V>[] segments; 1426 1427 private final boolean identityComparisons; 1428 1429 private transient Set<K> keySet; 1430 1431 private transient Set<Entry<K, V>> entrySet; 1432 1433 private transient Collection<V> values; 1434 1435 /** 1436 * Creates a new, empty map with the specified initial capacity, reference types, load factor, and concurrency level. 1437 * <p> 1438 * Behavioral changing options such as {@link Option#IDENTITY_COMPARISONS} can also be specified. 1439 * </p> 1440 * 1441 * @param initialCapacity The initial capacity. The implementation performs internal sizing to accommodate this many elements. 1442 * @param loadFactor The load factor threshold, used to control resizing. Resizing may be performed when the average number of elements per bin 1443 * exceeds this threshold. 1444 * @param concurrencyLevel The estimated number of concurrently updating threads. The implementation performs internal sizing to try to accommodate this 1445 * many threads. 1446 * @param keyType The reference type to use for keys. 1447 * @param valueType The reference type to use for values. 1448 * @param options The behavioral options. 1449 * @throws IllegalArgumentException if the initial capacity is negative or the load factor or concurrencyLevel are nonpositive. 1450 */ 1451 private ConcurrentReferenceHashMap(int initialCapacity, final float loadFactor, int concurrencyLevel, final ReferenceType keyType, 1452 final ReferenceType valueType, final EnumSet<Option> options) { 1453 if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) { 1454 throw new IllegalArgumentException(); 1455 } 1456 if (concurrencyLevel > MAX_SEGMENTS) { 1457 concurrencyLevel = MAX_SEGMENTS; 1458 } 1459 // Find power-of-two sizes best matching arguments 1460 int sshift = 0; 1461 int ssize = 1; 1462 while (ssize < concurrencyLevel) { 1463 ++sshift; 1464 ssize <<= 1; 1465 } 1466 segmentShift = 32 - sshift; 1467 segmentMask = ssize - 1; 1468 this.segments = Segment.newArray(ssize); 1469 if (initialCapacity > MAXIMUM_CAPACITY) { 1470 initialCapacity = MAXIMUM_CAPACITY; 1471 } 1472 int c = initialCapacity / ssize; 1473 if (c * ssize < initialCapacity) { 1474 ++c; 1475 } 1476 int cap = 1; 1477 while (cap < c) { 1478 cap <<= 1; 1479 } 1480 identityComparisons = options != null && options.contains(Option.IDENTITY_COMPARISONS); 1481 for (int i = 0; i < this.segments.length; ++i) { 1482 this.segments[i] = new Segment<>(cap, loadFactor, keyType, valueType, identityComparisons); 1483 } 1484 } 1485 1486 /** 1487 * Removes all of the mappings from this map. 1488 */ 1489 @Override 1490 public void clear() { 1491 for (final Segment<K, V> segment : segments) { 1492 segment.clear(); 1493 } 1494 } 1495 1496 @Override 1497 public V compute(final K key, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 1498 Objects.requireNonNull(key, "key"); 1499 Objects.requireNonNull(remappingFunction, "remappingFunction"); 1500 final int hash = hashOf(key); 1501 final Segment<K, V> segment = segmentFor(hash); 1502 return segment.apply(key, hash, remappingFunction); 1503 } 1504 1505 /** 1506 * The default implementation is equivalent to the following steps for this {@code map}, then returning the current value or {@code null} if now absent: 1507 * 1508 * <pre>{@code 1509 * if (map.get(key) == null) { 1510 * V newValue = mappingFunction.apply(key); 1511 * if (newValue != null) 1512 * return map.putIfAbsent(key, newValue); 1513 * } 1514 * }</pre> 1515 * <p> 1516 * The default implementation may retry these steps when multiple threads attempt updates including potentially calling the mapping function multiple times. 1517 * </p> 1518 * <p> 1519 * This implementation assumes that the ConcurrentMap cannot contain null values and {@code get()} returning null unambiguously means the key is absent. 1520 * Implementations which support null values <strong>must</strong> override this default implementation. 1521 * </p> 1522 */ 1523 @Override 1524 public V computeIfAbsent(final K key, final Function<? super K, ? extends V> mappingFunction) { 1525 Objects.requireNonNull(key, "key"); 1526 Objects.requireNonNull(mappingFunction, "mappingFunction"); 1527 final int hash = hashOf(key); 1528 final Segment<K, V> segment = segmentFor(hash); 1529 final V v = segment.get(key, hash); 1530 return v == null ? segment.put(key, hash, null, mappingFunction, true) : v; 1531 } 1532 1533 @Override 1534 public V computeIfPresent(final K key, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 1535 Objects.requireNonNull(key, "key"); 1536 Objects.requireNonNull(remappingFunction, "remappingFunction"); 1537 final int hash = hashOf(key); 1538 final Segment<K, V> segment = segmentFor(hash); 1539 final V v = segment.get(key, hash); 1540 if (v == null) { 1541 return null; 1542 } 1543 return segmentFor(hash).applyIfPresent(key, hash, remappingFunction); 1544 } 1545 1546 /** 1547 * Tests if the specified object is a key in this table. 1548 * 1549 * @param key possible key 1550 * @return {@code true} if and only if the specified object is a key in this table, as determined by the {@code equals} method; {@code false} otherwise. 1551 * @throws NullPointerException if the specified key is null 1552 */ 1553 @Override 1554 public boolean containsKey(final Object key) { 1555 final int hash = hashOf(key); 1556 return segmentFor(hash).containsKey(key, hash); 1557 } 1558 1559 /** 1560 * Returns {@code true} if this map maps one or more keys to the specified value. Note: This method requires a full internal traversal of the hash table, 1561 * therefore it is much slower than the method {@code containsKey}. 1562 * 1563 * @param value value whose presence in this map is to be tested 1564 * @return {@code true} if this map maps one or more keys to the specified value 1565 * @throws NullPointerException if the specified value is null 1566 */ 1567 @Override 1568 public boolean containsValue(final Object value) { 1569 Objects.requireNonNull(value, "value"); 1570 // See explanation of modCount use above 1571 final Segment<K, V>[] segments = this.segments; 1572 final int[] mc = new int[segments.length]; 1573 // Try a few times without locking 1574 for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) { 1575 // final int sum = 0; 1576 int mcsum = 0; 1577 for (int i = 0; i < segments.length; ++i) { 1578 // final int c = segments[i].count; 1579 mcsum += mc[i] = segments[i].modCount; 1580 if (segments[i].containsValue(value)) { 1581 return true; 1582 } 1583 } 1584 boolean cleanSweep = true; 1585 if (mcsum != 0) { 1586 for (int i = 0; i < segments.length; ++i) { 1587 // final int c = segments[i].count; 1588 if (mc[i] != segments[i].modCount) { 1589 cleanSweep = false; 1590 break; 1591 } 1592 } 1593 } 1594 if (cleanSweep) { 1595 return false; 1596 } 1597 } 1598 // Resort to locking all segments 1599 for (final Segment<K, V> segment : segments) { 1600 segment.lock(); 1601 } 1602 boolean found = false; 1603 try { 1604 for (final Segment<K, V> segment : segments) { 1605 if (segment.containsValue(value)) { 1606 found = true; 1607 break; 1608 } 1609 } 1610 } finally { 1611 for (final Segment<K, V> segment : segments) { 1612 segment.unlock(); 1613 } 1614 } 1615 return found; 1616 } 1617 1618 /** 1619 * Returns a {@link Set} view of the mappings contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and 1620 * vice-versa. The set supports element removal, which removes the corresponding mapping from the map, via the {@code Iterator.remove}, {@code Set.remove}, 1621 * {@code removeAll}, {@code retainAll}, and {@code clear} operations. It does not support the {@code add} or {@code addAll} operations. 1622 * <p> 1623 * The view's {@code iterator} is a "weakly consistent" iterator that will never throw {@link ConcurrentModificationException}, and is guaranteed to 1624 * traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to 1625 * construction. 1626 * </p> 1627 */ 1628 @Override 1629 public Set<Entry<K, V>> entrySet() { 1630 final Set<Entry<K, V>> es = entrySet; 1631 return es != null ? es : (entrySet = new EntrySet(false)); 1632 } 1633 1634 /** 1635 * Gets the value to which the specified key is mapped, or {@code null} if this map contains no mapping for the key. 1636 * <p> 1637 * If this map contains a mapping from a key {@code k} to a value {@code v} such that {@code key.equals(k)}, then this method returns {@code v}; otherwise 1638 * it returns {@code null}. (There can be at most one such mapping.) 1639 * </p> 1640 * 1641 * @throws NullPointerException if the specified key is null 1642 */ 1643 @Override 1644 public V get(final Object key) { 1645 final int hash = hashOf(key); 1646 return segmentFor(hash).get(key, hash); 1647 } 1648 1649 /** 1650 * Returns the hash code of the given key, which is either the result of calling {@code hashCode} or {@code System.identityHashCode} depending on 1651 * {@code identityComparisons}. 1652 * 1653 * @param key The key to hash. 1654 * @return The hash code of the given key. 1655 * @throws NullPointerException if the specified key is null. 1656 */ 1657 private int hashOf(final Object key) { 1658 Objects.requireNonNull(key, "key"); 1659 return hash(identityComparisons ? System.identityHashCode(key) : key.hashCode()); 1660 } 1661 1662 /** 1663 * Returns {@code true} if this map contains no key-value mappings. 1664 * 1665 * @return {@code true} if this map contains no key-value mappings 1666 */ 1667 @Override 1668 public boolean isEmpty() { 1669 final Segment<K, V>[] segments = this.segments; 1670 // 1671 // We keep track of per-segment modCounts to avoid ABA problems in which an element in one segment was added and in another removed during traversal, in 1672 // which case the table was never actually empty at any point. Note the similar use of modCounts in the size() and containsValue() methods, which are 1673 // the only other methods also susceptible to ABA problems. 1674 // 1675 final int[] mc = new int[segments.length]; 1676 int mcsum = 0; 1677 for (int i = 0; i < segments.length; ++i) { 1678 if (segments[i].count != 0) { 1679 return false; 1680 } 1681 mcsum += mc[i] = segments[i].modCount; 1682 } 1683 // If mcsum happens to be zero, then we know we got a snapshot 1684 // before any modifications at all were made. This is 1685 // probably common enough to bother tracking. 1686 if (mcsum != 0) { 1687 for (int i = 0; i < segments.length; ++i) { 1688 if (segments[i].count != 0 || mc[i] != segments[i].modCount) { 1689 return false; 1690 } 1691 } 1692 } 1693 return true; 1694 } 1695 1696 /** 1697 * Returns a {@link Set} view of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and 1698 * vice-versa. The set supports element removal, which removes the corresponding mapping from this map, via the {@code Iterator.remove}, {@code Set.remove}, 1699 * {@code removeAll}, {@code retainAll}, and {@code clear} operations. It does not support the {@code add} or {@code addAll} operations. 1700 * <p> 1701 * The view's {@code iterator} is a "weakly consistent" iterator that will never throw {@link ConcurrentModificationException}, and guarantees to traverse 1702 * elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction. 1703 * </p> 1704 */ 1705 @Override 1706 public Set<K> keySet() { 1707 final Set<K> ks = keySet; 1708 return ks != null ? ks : (keySet = new KeySet()); 1709 } 1710 1711 /** 1712 * Removes any stale entries whose keys have been finalized. Use of this method is normally not necessary since stale entries are automatically removed 1713 * lazily, when blocking operations are required. However, there are some cases where this operation should be performed eagerly, such as cleaning up old 1714 * references to a ClassLoader in a multi-classloader environment. 1715 * <p> 1716 * Note: this method will acquire locks one at a time across all segments of this table, so this method should be used sparingly. 1717 * </p> 1718 */ 1719 public void purgeStaleEntries() { 1720 for (final Segment<K, V> segment : segments) { 1721 segment.removeStale(); 1722 } 1723 } 1724 1725 /** 1726 * Maps the specified key to the specified value in this table. Neither the key nor the value can be null. 1727 * <p> 1728 * The value can be retrieved by calling the {@code get} method with a key that is equal to the original key. 1729 * </p> 1730 * 1731 * @param key key with which the specified value is to be associated 1732 * @param value value to be associated with the specified key 1733 * @return The previous value associated with {@code key}, or {@code null} if there was no mapping for {@code key} 1734 * @throws NullPointerException if the specified key or value is null 1735 */ 1736 @Override 1737 public V put(final K key, final V value) { 1738 Objects.requireNonNull(key, "key"); 1739 Objects.requireNonNull(value, "value"); 1740 final int hash = hashOf(key); 1741 return segmentFor(hash).put(key, hash, value, null, false); 1742 } 1743 1744 /** 1745 * Copies all of the mappings from the specified map to this one. These mappings replace any mappings that this map had for any of the keys currently in the 1746 * specified map. 1747 * 1748 * @param m mappings to be stored in this map 1749 */ 1750 @Override 1751 public void putAll(final Map<? extends K, ? extends V> m) { 1752 for (final Entry<? extends K, ? extends V> e : m.entrySet()) { 1753 put(e.getKey(), e.getValue()); 1754 } 1755 } 1756 1757 /** 1758 * {@inheritDoc} 1759 * 1760 * @return The previous value associated with the specified key, or {@code null} if there was no mapping for the key 1761 * @throws NullPointerException if the specified key or value is null 1762 */ 1763 @Override 1764 public V putIfAbsent(final K key, final V value) { 1765 Objects.requireNonNull(value, "value"); 1766 final int hash = hashOf(key); 1767 return segmentFor(hash).put(key, hash, value, null, true); 1768 } 1769 1770 /** 1771 * Removes the key (and its corresponding value) from this map. This method does nothing if the key is not in the map. 1772 * 1773 * @param key The key that needs to be removed 1774 * @return The previous value associated with {@code key}, or {@code null} if there was no mapping for {@code key} 1775 * @throws NullPointerException if the specified key is null 1776 */ 1777 @Override 1778 public V remove(final Object key) { 1779 final int hash = hashOf(key); 1780 return segmentFor(hash).remove(key, hash, null, false); 1781 } 1782 1783 /** 1784 * {@inheritDoc} 1785 * 1786 * @throws NullPointerException if the specified key is null 1787 */ 1788 @Override 1789 public boolean remove(final Object key, final Object value) { 1790 final int hash = hashOf(key); 1791 if (value == null) { 1792 return false; 1793 } 1794 return segmentFor(hash).remove(key, hash, value, false) != null; 1795 } 1796 1797 /** 1798 * {@inheritDoc} 1799 * 1800 * @return The previous value associated with the specified key, or {@code null} if there was no mapping for the key 1801 * @throws NullPointerException if the specified key or value is null 1802 */ 1803 @Override 1804 public V replace(final K key, final V value) { 1805 Objects.requireNonNull(value, "value"); 1806 final int hash = hashOf(key); 1807 return segmentFor(hash).replace(key, hash, value); 1808 } 1809 1810 /** 1811 * {@inheritDoc} 1812 * 1813 * @throws NullPointerException if any of the arguments are null 1814 */ 1815 @Override 1816 public boolean replace(final K key, final V oldValue, final V newValue) { 1817 Objects.requireNonNull(oldValue, "oldValue"); 1818 Objects.requireNonNull(newValue, "newValue"); 1819 final int hash = hashOf(key); 1820 return segmentFor(hash).replace(key, hash, oldValue, newValue); 1821 } 1822 1823 /** 1824 * Returns the segment that should be used for key with given hash 1825 * 1826 * @param hash The hash code for the key 1827 * @return The segment 1828 */ 1829 private Segment<K, V> segmentFor(final int hash) { 1830 return segments[hash >>> segmentShift & segmentMask]; 1831 } 1832 1833 /** 1834 * Returns the number of key-value mappings in this map. If the map contains more than {@code Integer.MAX_VALUE} elements, returns 1835 * {@code Integer.MAX_VALUE}. 1836 * 1837 * @return The number of key-value mappings in this map 1838 */ 1839 @Override 1840 public int size() { 1841 final Segment<K, V>[] segments = this.segments; 1842 long sum = 0; 1843 long check = 0; 1844 final int[] mc = new int[segments.length]; 1845 // Try a few times to get accurate count. On failure due to 1846 // continuous async changes in table, resort to locking. 1847 for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) { 1848 check = 0; 1849 sum = 0; 1850 int mcsum = 0; 1851 for (int i = 0; i < segments.length; ++i) { 1852 sum += segments[i].count; 1853 mcsum += mc[i] = segments[i].modCount; 1854 } 1855 if (mcsum != 0) { 1856 for (int i = 0; i < segments.length; ++i) { 1857 check += segments[i].count; 1858 if (mc[i] != segments[i].modCount) { 1859 // force retry 1860 check = -1; 1861 break; 1862 } 1863 } 1864 } 1865 if (check == sum) { 1866 break; 1867 } 1868 } 1869 if (check != sum) { 1870 // Resort to locking all segments 1871 sum = 0; 1872 for (final Segment<K, V> segment : segments) { 1873 segment.lock(); 1874 } 1875 for (final Segment<K, V> segment : segments) { 1876 sum += segment.count; 1877 } 1878 for (final Segment<K, V> segment : segments) { 1879 segment.unlock(); 1880 } 1881 } 1882 return sum > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) sum; 1883 } 1884 1885 /** 1886 * Returns a {@link Collection} view of the values contained in this map. The collection is backed by the map, so changes to the map are reflected in the 1887 * collection, and vice-versa. The collection supports element removal, which removes the corresponding mapping from this map, via the 1888 * {@code Iterator.remove}, {@code Collection.remove}, {@code removeAll}, {@code retainAll}, and {@code clear} operations. It does not support the 1889 * {@code add} or {@code addAll} operations. 1890 * <p> 1891 * The view's {@code iterator} is a "weakly consistent" iterator that will never throw {@link ConcurrentModificationException}, and guarantees to traverse 1892 * elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction. 1893 * </p> 1894 */ 1895 @Override 1896 public Collection<V> values() { 1897 final Collection<V> vs = values; 1898 return vs != null ? vs : (values = new Values()); 1899 } 1900 1901}