1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at 4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/ 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent; 875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 975a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.io.ObjectStreamField; 107365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.io.Serializable; 1175a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.lang.reflect.ParameterizedType; 1275a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.lang.reflect.Type; 13edf43d27e240d82106f39ae91404963c23987234Narayan Kamathimport java.util.AbstractMap; 1475a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.Arrays; 1575a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.Collection; 1675a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.ConcurrentModificationException; 1775a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.Enumeration; 1875a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.HashMap; 1975a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.Hashtable; 2075a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.Iterator; 2175a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.Map; 2275a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.NoSuchElementException; 2375a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.Set; 2475a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.concurrent.ConcurrentMap; 2575a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.concurrent.atomic.AtomicInteger; 2675a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.concurrent.locks.LockSupport; 2775a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.concurrent.locks.ReentrantLock; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-note 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// removed link to collections framework docs 3175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle// removed links to hidden api 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-note 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A hash table supporting full concurrency of retrievals and 3675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * high expected concurrency for updates. This class obeys the 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * same functional specification as {@link java.util.Hashtable}, and 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * includes versions of methods corresponding to each method of 3975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code Hashtable}. However, even though all operations are 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thread-safe, retrieval operations do <em>not</em> entail locking, 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and there is <em>not</em> any support for locking the entire table 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in a way that prevents all access. This class is fully 4375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * interoperable with {@code Hashtable} in programs that rely on its 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thread safety but not on its synchronization details. 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>Retrieval operations (including {@code get}) generally do not 4775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * block, so may overlap with update operations (including {@code put} 4875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * and {@code remove}). Retrievals reflect the results of the most 4975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * recently <em>completed</em> update operations holding upon their 5075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * onset. (More formally, an update operation for a given key bears a 5175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <em>happens-before</em> relation with any (non-null) retrieval for 5275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * that key reporting the updated value.) For aggregate operations 5375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * such as {@code putAll} and {@code clear}, concurrent retrievals may 5475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * reflect insertion or removal of only some entries. Similarly, 5575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Iterators and Enumerations return elements reflecting the state of 5675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the hash table at some point at or since the creation of the 5775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * iterator/enumeration. They do <em>not</em> throw {@link 5875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * ConcurrentModificationException}. However, iterators are designed 5975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to be used by only one thread at a time. Bear in mind that the 6075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * results of aggregate status methods including {@code size}, {@code 6175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * isEmpty}, and {@code containsValue} are typically useful only when 6275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * a map is not undergoing concurrent updates in other threads. 6375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Otherwise the results of these methods reflect transient states 6475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * that may be adequate for monitoring or estimation purposes, but not 6575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * for program control. 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 6775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>The table is dynamically expanded when there are too many 6875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * collisions (i.e., keys that have distinct hash codes but fall into 6975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the same slot modulo the table size), with the expected average 7075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * effect of maintaining roughly two bins per mapping (corresponding 7175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to a 0.75 load factor threshold for resizing). There may be much 7275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * variance around this average as mappings are added and removed, but 7375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * overall, this maintains a commonly accepted time/space tradeoff for 7475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * hash tables. However, resizing this or any other kind of hash 7575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * table may be a relatively slow operation. When possible, it is a 7675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * good idea to provide a size estimate as an optional {@code 7775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * initialCapacity} constructor argument. An additional optional 7875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code loadFactor} constructor argument provides a further means of 7975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * customizing initial table capacity by specifying the table density 8075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to be used in calculating the amount of space to allocate for the 8175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * given number of elements. Also, for compatibility with previous 8275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * versions of this class, constructors may optionally specify an 8375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * expected {@code concurrencyLevel} as an additional hint for 8475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * internal sizing. Note that using many keys with exactly the same 8575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code hashCode()} is a sure way to slow down performance of any 8675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * hash table. To ameliorate impact, when keys are {@link Comparable}, 8775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * this class may use comparison order among keys to help break ties. 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>This class and its views and iterators implement all of the 90bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <em>optional</em> methods of the {@link Map} and {@link Iterator} 91bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * interfaces. 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>Like {@link Hashtable} but unlike {@link HashMap}, this class 9475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * does <em>not</em> allow {@code null} to be used as a key or value. 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <K> the type of keys maintained by this map 99bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param <V> the type of mapped values 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 101edf43d27e240d82106f39ae91404963c23987234Narayan Kamath// android-note: removed documentation about hidden newKeySet and newKeySet(int) APIs. 102edf43d27e240d82106f39ae91404963c23987234Narayan Kamath// android-note: Added "extends AbstractMap<K, V>. 103edf43d27e240d82106f39ae91404963c23987234Narayan Kamathpublic class ConcurrentHashMap<K,V> extends AbstractMap<K, V> 10475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements ConcurrentMap<K,V>, Serializable { 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 7249069246763182397L; 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 10875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Overview: 10975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 11075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The primary design goal of this hash table is to maintain 11175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * concurrent readability (typically method get(), but also 11275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * iterators and related methods) while minimizing update 11375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * contention. Secondary goals are to keep space consumption about 11475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the same or better than java.util.HashMap, and to support high 11575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * initial insertion rates on an empty table by many threads. 11675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 11775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * This map usually acts as a binned (bucketed) hash table. Each 11875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * key-value mapping is held in a Node. Most nodes are instances 11975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of the basic Node class with hash, key, value, and next 12075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * fields. However, various subclasses exist: TreeNodes are 12175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * arranged in balanced trees, not lists. TreeBins hold the roots 12275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of sets of TreeNodes. ForwardingNodes are placed at the heads 12375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of bins during resizing. ReservationNodes are used as 12475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * placeholders while establishing values in computeIfAbsent and 12575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * related methods. The types TreeBin, ForwardingNode, and 12675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * ReservationNode do not hold normal user keys, values, or 12775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * hashes, and are readily distinguishable during search etc 12875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * because they have negative hash fields and null key and value 12975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * fields. (These special nodes are either uncommon or transient, 13075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * so the impact of carrying around some unused fields is 13175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * insignificant.) 13275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 13375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The table is lazily initialized to a power-of-two size upon the 13475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * first insertion. Each bin in the table normally contains a 13575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * list of Nodes (most often, the list has only zero or one Node). 13675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Table accesses require volatile/atomic reads, writes, and 13775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * CASes. Because there is no other way to arrange this without 13875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * adding further indirections, we use intrinsics 13975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (sun.misc.Unsafe) operations. 14075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 14175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * We use the top (sign) bit of Node hash fields for control 14275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * purposes -- it is available anyway because of addressing 14375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * constraints. Nodes with negative hash fields are specially 14475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * handled or ignored in map methods. 14575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 14675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Insertion (via put or its variants) of the first node in an 14775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * empty bin is performed by just CASing it to the bin. This is 14875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * by far the most common case for put operations under most 14975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * key/hash distributions. Other update operations (insert, 15075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * delete, and replace) require locks. We do not want to waste 15175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the space required to associate a distinct lock object with 15275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * each bin, so instead use the first node of a bin list itself as 15375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * a lock. Locking support for these locks relies on builtin 15475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * "synchronized" monitors. 15575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 15675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Using the first node of a list as a lock does not by itself 15775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * suffice though: When a node is locked, any update must first 15875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * validate that it is still the first node after locking it, and 15975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * retry if not. Because new nodes are always appended to lists, 16075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * once a node is first in a bin, it remains first until deleted 16175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * or the bin becomes invalidated (upon resizing). 16275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 16375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The main disadvantage of per-bin locks is that other update 16475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * operations on other nodes in a bin list protected by the same 16575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * lock can stall, for example when user equals() or mapping 16675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * functions take a long time. However, statistically, under 16775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * random hash codes, this is not a common problem. Ideally, the 16875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * frequency of nodes in bins follows a Poisson distribution 16975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (http://en.wikipedia.org/wiki/Poisson_distribution) with a 17075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * parameter of about 0.5 on average, given the resizing threshold 17175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of 0.75, although with a large variance because of resizing 17275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * granularity. Ignoring variance, the expected occurrences of 17375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The 17475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * first values are: 17575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 17675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 0: 0.60653066 17775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 1: 0.30326533 17875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 2: 0.07581633 17975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 3: 0.01263606 18075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 4: 0.00157952 18175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 5: 0.00015795 18275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 6: 0.00001316 18375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 7: 0.00000094 18475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 8: 0.00000006 18575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * more: less than 1 in ten million 18675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 18775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Lock contention probability for two threads accessing distinct 18875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * elements is roughly 1 / (8 * #elements) under random hashes. 18975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 19075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Actual hash code distributions encountered in practice 19175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * sometimes deviate significantly from uniform randomness. This 19275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * includes the case when N > (1<<30), so some keys MUST collide. 19375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Similarly for dumb or hostile usages in which multiple keys are 19475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * designed to have identical hash codes or ones that differs only 19575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * in masked-out high bits. So we use a secondary strategy that 19675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * applies when the number of nodes in a bin exceeds a 19775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * threshold. These TreeBins use a balanced tree to hold nodes (a 19875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * specialized form of red-black trees), bounding search time to 19975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * O(log N). Each search step in a TreeBin is at least twice as 20075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * slow as in a regular list, but given that N cannot exceed 20175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (1<<64) (before running out of addresses) this bounds search 20275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * steps, lock hold times, etc, to reasonable constants (roughly 20375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 100 nodes inspected per operation worst case) so long as keys 20475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * are Comparable (which is very common -- String, Long, etc). 20575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * TreeBin nodes (TreeNodes) also maintain the same "next" 20675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * traversal pointers as regular nodes, so can be traversed in 20775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * iterators in the same way. 20875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 20975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The table is resized when occupancy exceeds a percentage 21075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * threshold (nominally, 0.75, but see below). Any thread 21175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * noticing an overfull bin may assist in resizing after the 212edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * initiating thread allocates and sets up the replacement array. 213edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * However, rather than stalling, these other threads may proceed 214edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * with insertions etc. The use of TreeBins shields us from the 215edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * worst case effects of overfilling while resizes are in 21675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * progress. Resizing proceeds by transferring bins, one by one, 217edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * from the table to the next table. However, threads claim small 218edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * blocks of indices to transfer (via field transferIndex) before 219edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * doing so, reducing contention. A generation stamp in field 220edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * sizeCtl ensures that resizings do not overlap. Because we are 22175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * using power-of-two expansion, the elements from each bin must 22275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * either stay at same index, or move with a power of two 22375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * offset. We eliminate unnecessary node creation by catching 22475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * cases where old nodes can be reused because their next fields 22575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * won't change. On average, only about one-sixth of them need 22675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * cloning when a table doubles. The nodes they replace will be 22775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * garbage collectable as soon as they are no longer referenced by 22875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * any reader thread that may be in the midst of concurrently 22975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * traversing table. Upon transfer, the old table bin contains 23075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * only a special forwarding node (with hash field "MOVED") that 23175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * contains the next table as its key. On encountering a 23275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * forwarding node, access and update operations restart, using 23375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the new table. 23475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 23575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Each bin transfer requires its bin lock, which can stall 23675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * waiting for locks while resizing. However, because other 23775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * threads can join in and help resize rather than contend for 23875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * locks, average aggregate waits become shorter as resizing 23975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * progresses. The transfer operation must also ensure that all 24075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * accessible bins in both the old and new table are usable by any 241edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * traversal. This is arranged in part by proceeding from the 242edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * last bin (table.length - 1) up towards the first. Upon seeing 243edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * a forwarding node, traversals (see class Traverser) arrange to 244edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * move to the new table without revisiting nodes. To ensure that 245edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * no intervening nodes are skipped even when moved out of order, 246edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * a stack (see class TableStack) is created on first encounter of 247edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * a forwarding node during a traversal, to maintain its place if 248edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * later processing the current table. The need for these 249edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * save/restore mechanics is relatively rare, but when one 250edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * forwarding node is encountered, typically many more will be. 251edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * So Traversers use a simple caching scheme to avoid creating so 252edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * many new TableStack nodes. (Thanks to Peter Levart for 253edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * suggesting use of a stack here.) 25475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 25575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The traversal scheme also applies to partial traversals of 25675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * ranges of bins (via an alternate Traverser constructor) 25775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to support partitioned aggregate operations. Also, read-only 25875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * operations give up if ever forwarded to a null table, which 25975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * provides support for shutdown-style clearing, which is also not 26075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * currently implemented. 26175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 26275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Lazy table initialization minimizes footprint until first use, 26375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * and also avoids resizings when the first operation is from a 26475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * putAll, constructor with map argument, or deserialization. 26575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * These cases attempt to override the initial capacity settings, 26675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * but harmlessly fail to take effect in cases of races. 26775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 26875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The element count is maintained using a specialization of 26975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * LongAdder. We need to incorporate a specialization rather than 27075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * just use a LongAdder in order to access implicit 27175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * contention-sensing that leads to creation of multiple 27275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * CounterCells. The counter mechanics avoid contention on 27375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * updates but can encounter cache thrashing if read too 27475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * frequently during concurrent access. To avoid reading so often, 27575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * resizing under contention is attempted only upon adding to a 27675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bin already holding two or more nodes. Under uniform hash 27775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * distributions, the probability of this occurring at threshold 27875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * is around 13%, meaning that only about 1 in 8 puts check 27975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * threshold (and after resizing, many fewer do so). 28075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 28175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * TreeBins use a special form of comparison for search and 28275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * related operations (which is the main reason we cannot use 28375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * existing collections such as TreeMaps). TreeBins contain 28475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Comparable elements, but may contain others, as well as 285edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * elements that are Comparable but not necessarily Comparable for 286edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * the same T, so we cannot invoke compareTo among them. To handle 287edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * this, the tree is ordered primarily by hash value, then by 288edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Comparable.compareTo order if applicable. On lookup at a node, 289edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * if elements are not comparable or compare as 0 then both left 290edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * and right children may need to be searched in the case of tied 291edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * hash values. (This corresponds to the full list search that 292edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * would be necessary if all elements were non-Comparable and had 293edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * tied hashes.) On insertion, to keep a total ordering (or as 294edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * close as is required here) across rebalancings, we compare 295edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * classes and identityHashCodes as tie-breakers. The red-black 296edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * balancing code is updated from pre-jdk-collections 29775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) 29875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * based in turn on Cormen, Leiserson, and Rivest "Introduction to 29975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Algorithms" (CLR). 30075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 30175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * TreeBins also require an additional locking mechanism. While 30275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * list traversal is always possible by readers even during 30375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * updates, tree traversal is not, mainly because of tree-rotations 30475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * that may change the root node and/or its linkages. TreeBins 30575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * include a simple read-write lock mechanism parasitic on the 30675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * main bin-synchronization strategy: Structural adjustments 30775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * associated with an insertion or removal are already bin-locked 30875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (and so cannot conflict with other writers) but must wait for 30975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * ongoing readers to finish. Since there can be only one such 31075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * waiter, we use a simple scheme using a single "waiter" field to 31175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * block writers. However, readers need never block. If the root 31275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * lock is held, they proceed along the slow traversal path (via 31375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * next-pointers) until the lock becomes available or the list is 31475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * exhausted, whichever comes first. These cases are not fast, but 31575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * maximize aggregate expected throughput. 31675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 31775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Maintaining API and serialization compatibility with previous 31875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * versions of this class introduces several oddities. Mainly: We 31975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * leave untouched but unused constructor arguments refering to 32075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * concurrencyLevel. We accept a loadFactor constructor argument, 32175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * but apply it only to initial table capacity (which is the only 32275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * time that we can guarantee to honor it.) We also declare an 32375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * unused "Segment" class that is instantiated in minimal form 32475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * only when serializing. 32575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 326edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Also, solely for compatibility with previous versions of this 327edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * class, it extends AbstractMap, even though all of its methods 328edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * are overridden, so it is just useless baggage. 329edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * 33075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * This file is organized to make things a little easier to follow 33175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * while reading than they might otherwise: First the main static 33275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * declarations and utilities, then fields, then main public 33375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * methods (with a few factorings of multiple public methods into 33475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * internal ones), then sizing methods, trees, traversers, and 33575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bulk operations. 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 338edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* ---------------- Constants -------------- */ 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 34275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The largest possible table capacity. This value must be 34375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * exactly 1<<30 to stay within Java array allocation and indexing 34475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bounds for power of two table sizes, and is further required 34575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * because the top two bits of 32bit hash fields are used for 34675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * control purposes. 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 34875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int MAXIMUM_CAPACITY = 1 << 30; 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 35175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The default initial table capacity. Must be a power of 2 35275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (i.e., at least 1) and at most MAXIMUM_CAPACITY. 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 35475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int DEFAULT_CAPACITY = 16; 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 35775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The largest possible (non-power of two) array size. 35875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Needed by toArray and related methods. 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 36075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 36375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The default concurrency level for this table. Unused but 36475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * defined for compatibility with previous versions of this class. 365bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 36675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int DEFAULT_CONCURRENCY_LEVEL = 16; 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 36975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The load factor for this table. Overrides of this value in 37075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * constructors affect only the initial table capacity. The 37175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * actual floating point value isn't normally used -- it is 37275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * simpler to use expressions such as {@code n - (n >>> 2)} for 37375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the associated resizing threshold. 374a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 37575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final float LOAD_FACTOR = 0.75f; 376a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 377a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 37875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The bin count threshold for using a tree rather than list for a 37975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bin. Bins are converted to trees when adding an element to a 38075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bin with at least this many nodes. The value must be greater 38175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * than 2, and should be at least 8 to mesh with assumptions in 38275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * tree removal about conversion back to plain bins upon 38375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * shrinkage. 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 38575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int TREEIFY_THRESHOLD = 8; 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 387bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 38875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The bin count threshold for untreeifying a (split) bin during a 38975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * resize operation. Should be less than TREEIFY_THRESHOLD, and at 39075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * most 6 to mesh with shrinkage detection under removal. 391bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 39275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int UNTREEIFY_THRESHOLD = 6; 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 39575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The smallest table capacity for which bins may be treeified. 39675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (Otherwise the table is resized if too many nodes in a bin.) 39775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The value should be at least 4 * TREEIFY_THRESHOLD to avoid 39875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * conflicts between resizing and treeification thresholds. 399bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 40075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int MIN_TREEIFY_CAPACITY = 64; 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 40375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Minimum number of rebinnings per transfer step. Ranges are 40475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * subdivided to allow multiple resizer threads. This value 40575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * serves as a lower bound to avoid resizers encountering 40675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * excessive memory contention. The value should be at least 40775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * DEFAULT_CAPACITY. 408bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 40975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int MIN_TRANSFER_STRIDE = 16; 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 411edf43d27e240d82106f39ae91404963c23987234Narayan Kamath /** 412edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * The number of bits used for generation stamp in sizeCtl. 413edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Must be at least 6 for 32bit arrays. 414edf43d27e240d82106f39ae91404963c23987234Narayan Kamath */ 415edf43d27e240d82106f39ae91404963c23987234Narayan Kamath private static int RESIZE_STAMP_BITS = 16; 416edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 417edf43d27e240d82106f39ae91404963c23987234Narayan Kamath /** 418edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * The maximum number of threads that can help resize. 419edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Must fit in 32 - RESIZE_STAMP_BITS bits. 420edf43d27e240d82106f39ae91404963c23987234Narayan Kamath */ 421edf43d27e240d82106f39ae91404963c23987234Narayan Kamath private static final int MAX_RESIZERS = (1 << (32 - RESIZE_STAMP_BITS)) - 1; 422edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 423edf43d27e240d82106f39ae91404963c23987234Narayan Kamath /** 424edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * The bit shift for recording size stamp in sizeCtl. 425edf43d27e240d82106f39ae91404963c23987234Narayan Kamath */ 426edf43d27e240d82106f39ae91404963c23987234Narayan Kamath private static final int RESIZE_STAMP_SHIFT = 32 - RESIZE_STAMP_BITS; 427edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 42875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* 42975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Encodings for Node hash fields. See above for explanation. 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 43175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int MOVED = 0x8fffffff; // (-1) hash for forwarding nodes 43275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int TREEBIN = 0x80000000; // hash for roots of trees 43375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int RESERVED = 0x80000001; // hash for transient reservations 43475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 43675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** Number of CPUS, to place bounds on some sizings */ 43775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int NCPU = Runtime.getRuntime().availableProcessors(); 43875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 43975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** For serialization compatibility. */ 44075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final ObjectStreamField[] serialPersistentFields = { 44175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new ObjectStreamField("segments", Segment[].class), 44275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new ObjectStreamField("segmentMask", Integer.TYPE), 44375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new ObjectStreamField("segmentShift", Integer.TYPE) 44475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle }; 44575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 44675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Nodes -------------- */ 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 448a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 44975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Key-value entry. This class is never exported out as a 45075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * user-mutable Map.Entry (i.e., one supporting setValue; see 45175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * MapEntry below), but can be used for read-only traversals used 45275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * in bulk tasks. Subclasses of Node with a negative hash field 45375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * are special, and contain null keys and values (but are never 45475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * exported). Otherwise, keys and vals are never null. 455a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 45675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static class Node<K,V> implements Map.Entry<K,V> { 457a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson final int hash; 458a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson final K key; 45975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile V val; 46075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> next; 461a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 46275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node(int hash, K key, V val, Node<K,V> next) { 463a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson this.hash = hash; 464a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson this.key = key; 46575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.val = val; 466a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson this.next = next; 467a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 468a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 46975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final K getKey() { return key; } 47075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final V getValue() { return val; } 47175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final int hashCode() { return key.hashCode() ^ val.hashCode(); } 47275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final String toString(){ return key + "=" + val; } 47375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final V setValue(V value) { 47475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new UnsupportedOperationException(); 475a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 476a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 47775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean equals(Object o) { 47875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object k, v, u; Map.Entry<?,?> e; 47975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Map.Entry) && 48075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 48175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v = e.getValue()) != null && 48275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k == key || k.equals(key)) && 48375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v == (u = val) || v.equals(u))); 48475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 48575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 48675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 48775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Virtualized support for map.get(); overridden in subclasses. 48875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 48975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> find(int h, Object k) { 49075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> e = this; 49175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (k != null) { 49275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle do { 49375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K ek; 49475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e.hash == h && 49575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == k || (ek != null && k.equals(ek)))) 49675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e; 49775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } while ((e = e.next) != null); 498a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 49975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 500a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 501a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 502a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 50375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Static utilities -------------- */ 50475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 505a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 50675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Spreads (XORs) higher bits of hash to lower and also forces top 50775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bit to 0. Because the table uses power-of-two masking, sets of 50875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * hashes that vary only in bits above the current mask will 50975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * always collide. (Among known examples are sets of Float keys 51075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * holding consecutive whole numbers in small tables.) So we 51175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * apply a transform that spreads the impact of higher bits 51275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * downward. There is a tradeoff between speed, utility, and 51375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * quality of bit-spreading. Because many common sets of hashes 51475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * are already reasonably distributed (so don't benefit from 51575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * spreading), and because we use trees to handle large sets of 51675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * collisions in bins, we just XOR some shifted bits in the 51775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * cheapest possible way to reduce systematic lossage, as well as 51875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to incorporate impact of the highest bits that would otherwise 51975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * never be used in index calculations because of table bounds. 520a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 52175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int spread(int h) { 52275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (h ^ (h >>> 16)) & HASH_BITS; 523a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 524a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 525a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 52675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a power of two table size for the given desired capacity. 52775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * See Hackers Delight, sec 3.2 528a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 52975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int tableSizeFor(int c) { 53075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n = c - 1; 53175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n |= n >>> 1; 53275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n |= n >>> 2; 53375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n |= n >>> 4; 53475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n |= n >>> 8; 53575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n |= n >>> 16; 53675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; 537a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 54075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns x's Class if it is of the form "class C implements 54175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Comparable<C>", else null. 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 54375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static Class<?> comparableClassFor(Object x) { 54475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (x instanceof Comparable) { 54575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> c; Type[] ts, as; Type t; ParameterizedType p; 54675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((c = x.getClass()) == String.class) // bypass checks 54775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return c; 54875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((ts = c.getGenericInterfaces()) != null) { 54975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int i = 0; i < ts.length; ++i) { 55075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (((t = ts[i]) instanceof ParameterizedType) && 55175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((p = (ParameterizedType)t).getRawType() == 55275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Comparable.class) && 55375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (as = p.getActualTypeArguments()) != null && 55475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle as.length == 1 && as[0] == c) // type arg is c 55575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return c; 55675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 55775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 55875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 55975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 56375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns k.compareTo(x) if x matches kc (k's screened comparable 56475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * class), else 0. 565bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 56675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings({"rawtypes","unchecked"}) // for cast to Comparable 56775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static int compareComparables(Class<?> kc, Object k, Object x) { 56875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (x == null || x.getClass() != kc ? 0 : 56975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((Comparable)k).compareTo(x)); 57075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 57275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Table element access -------------- */ 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 57475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* 57575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Volatile access methods are used for table elements as well as 57675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * elements of in-progress next table while resizing. All uses of 57775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the tab arguments must be null checked by callers. All callers 57875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * also paranoically precheck that tab's length is not zero (or an 57975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * equivalent check), thus ensuring that any index argument taking 58075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the form of a hash value anded with (length - 1) is a valid 58175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * index. Note that, to be correct wrt arbitrary concurrency 58275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * errors by users, these checks must operate on local variables, 58375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * which accounts for some odd-looking inline assignments below. 58475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Note that calls to setTabAt always occur within locked regions, 58575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * and so do not need full volatile semantics, but still require 58675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * ordering to maintain concurrent readability. 58775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 588a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 58975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings("unchecked") 59075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) { 59175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE); 59275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 59475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i, 59575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> c, Node<K,V> v) { 59675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v); 59775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 598a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 59975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) { 60075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.putOrderedObject(tab, ((long)i << ASHIFT) + ABASE, v); 60175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 60375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Fields -------------- */ 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 60575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 60675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The array of bins. Lazily initialized upon first insertion. 60775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Size is always a power of two. Accessed directly by iterators. 60875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 60975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transient volatile Node<K,V>[] table; 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 61175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 61275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The next table to use; non-null only while resizing. 61375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 61475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile Node<K,V>[] nextTable; 615bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 61675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 61775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Base counter value, used mainly when there is no contention, 61875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * but also as a fallback during table initialization 61975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * races. Updated via CAS. 62075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 62175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile long baseCount; 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 62375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 62475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Table initialization and resizing control. When negative, the 62575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * table is being initialized or resized: -1 for initialization, 62675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * else -(1 + the number of active resizing threads). Otherwise, 62775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * when table is null, holds the initial table size to use upon 62875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * creation, or 0 for default. After initialization, holds the 62975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * next element count value upon which to resize the table. 63075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 63175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile int sizeCtl; 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 63375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 63475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The next table index (plus one) to split while resizing. 63575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 63675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile int transferIndex; 637a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 63875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 63975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Spinlock (locked via CAS) used when resizing and/or creating CounterCells. 64075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 64175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile int cellsBusy; 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 64375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 64475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Table of counter cells. When non-null, size is a power of 2. 64575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 64675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile CounterCell[] counterCells; 647a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 64875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // views 64975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient KeySetView<K,V> keySet; 65075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient ValuesView<K,V> values; 65175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient EntrySetView<K,V> entrySet; 652a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 653a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 65475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Public operations -------------- */ 655a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 656a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 65775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new, empty map with the default initial table size (16). 658a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 65975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public ConcurrentHashMap() { 660a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 662a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 66375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new, empty map with an initial table size 66475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * accommodating the specified number of elements without the need 66575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to dynamically resize. 666a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 66775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param initialCapacity The implementation performs internal 66875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * sizing to accommodate this many elements. 66975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws IllegalArgumentException if the initial capacity of 67075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * elements is negative 671a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 67275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public ConcurrentHashMap(int initialCapacity) { 67375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (initialCapacity < 0) 67475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new IllegalArgumentException(); 67575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ? 67675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle MAXIMUM_CAPACITY : 67775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1)); 67875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.sizeCtl = cap; 679a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 680a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 681a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 68275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new map with the same mappings as the given map. 68375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 68475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param m the map 685a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 68675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public ConcurrentHashMap(Map<? extends K, ? extends V> m) { 68775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.sizeCtl = DEFAULT_CAPACITY; 68875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle putAll(m); 689a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 69275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new, empty map with an initial table size based on 69375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the given number of elements ({@code initialCapacity}) and 69475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * initial table density ({@code loadFactor}). 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param initialCapacity the initial capacity. The implementation 69775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * performs internal sizing to accommodate this many elements, 69875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * given the specified load factor. 69975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param loadFactor the load factor (table density) for 70075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * establishing the initial table size 7016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalArgumentException if the initial capacity of 7026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * elements is negative or the load factor is nonpositive 7036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 7046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @since 1.6 7056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 7066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public ConcurrentHashMap(int initialCapacity, float loadFactor) { 70775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this(initialCapacity, loadFactor, 1); 7086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 7106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 71175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new, empty map with an initial table size based on 71275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the given number of elements ({@code initialCapacity}), table 71375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * density ({@code loadFactor}), and number of concurrently 71475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * updating threads ({@code concurrencyLevel}). 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 716bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param initialCapacity the initial capacity. The implementation 71775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * performs internal sizing to accommodate this many elements, 71875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * given the specified load factor. 71975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param loadFactor the load factor (table density) for 72075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * establishing the initial table size 72175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param concurrencyLevel the estimated number of concurrently 72275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * updating threads. The implementation may use this value as 72375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * a sizing hint. 72475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws IllegalArgumentException if the initial capacity is 72575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * negative or the load factor or concurrencyLevel are 72675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * nonpositive 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 72875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public ConcurrentHashMap(int initialCapacity, 72975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle float loadFactor, int concurrencyLevel) { 73075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) 73175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new IllegalArgumentException(); 73275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (initialCapacity < concurrencyLevel) // Use at least as many bins 73375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle initialCapacity = concurrencyLevel; // as estimated threads 73475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long size = (long)(1.0 + (long)initialCapacity / loadFactor); 73575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int cap = (size >= (long)MAXIMUM_CAPACITY) ? 73675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle MAXIMUM_CAPACITY : tableSizeFor((int)size); 73775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.sizeCtl = cap; 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 74075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // Original (since JDK1.2) Map methods 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 74375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 74575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public int size() { 74675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long n = sumCount(); 74775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((n < 0L) ? 0 : 74875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : 74975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (int)n); 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 752bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 75375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 754bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isEmpty() { 75675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return sumCount() <= 0L; // ignore transient negative values 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 760bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns the value to which the specified key is mapped, 761bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * or {@code null} if this map contains no mapping for the key. 762bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 763bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>More formally, if this map contains a mapping from a key 764bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@code k} to a value {@code v} such that {@code key.equals(k)}, 765bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * then this method returns {@code v}; otherwise it returns 766bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@code null}. (There can be at most one such mapping.) 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 768bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified key is null 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V get(Object key) { 77175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek; 77275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = spread(key.hashCode()); 77375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((tab = table) != null && (n = tab.length) > 0 && 77475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (e = tabAt(tab, (n - 1) & h)) != null) { 77575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((eh = e.hash) == h) { 77675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((ek = e.key) == key || (ek != null && key.equals(ek))) 77775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e.val; 77875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 77975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (eh < 0) 78075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (p = e.find(h, key)) != null ? p.val : null; 78175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while ((e = e.next) != null) { 78275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e.hash == h && 78375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == key || (ek != null && key.equals(ek)))) 78475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e.val; 785a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 786a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 787a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson return null; 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Tests if the specified object is a key in this table. 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 79375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param key possible key 79475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if and only if the specified object 795bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * is a key in this table, as determined by the 79675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code equals} method; {@code false} otherwise 797bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified key is null 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean containsKey(Object key) { 80075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return get(key) != null; 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 80475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns {@code true} if this map maps one or more keys to the 80575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * specified value. Note: This method may require a full traversal 80675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of the map, and is much slower than method {@code containsKey}. 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 808bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param value value whose presence in this map is to be tested 80975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if this map maps one or more keys to the 810bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * specified value 811bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified value is null 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean containsValue(Object value) { 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value == null) 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 81675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 81775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((t = table) != null) { 81875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 81975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p; (p = it.advance()) != null; ) { 82075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v; 82175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((v = p.val) == value || (v != null && value.equals(v))) 82275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 823bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 824bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 82575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 829bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Maps the specified key to the specified value in this table. 830bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Neither the key nor the value can be null. 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 83275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>The value can be retrieved by calling the {@code get} method 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with a key that is equal to the original key. 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 835bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param key key with which the specified value is to be associated 836bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param value value to be associated with the specified key 83775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the previous value associated with {@code key}, or 83875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code null} if there was no mapping for {@code key} 839bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified key or value is null 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V put(K key, V value) { 84275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return putVal(key, value, false); 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 84575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** Implementation for put and putIfAbsent */ 84675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final V putVal(K key, V value, boolean onlyIfAbsent) { 84775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (key == null || value == null) throw new NullPointerException(); 84875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int hash = spread(key.hashCode()); 84975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int binCount = 0; 85075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V>[] tab = table;;) { 85175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> f; int n, i, fh; 85275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tab == null || (n = tab.length) == 0) 85375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tab = initTable(); 85475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { 85575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (casTabAt(tab, i, null, 85675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new Node<K,V>(hash, key, value, null))) 85775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; // no lock when adding to empty bin 85875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 85975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((fh = f.hash) == MOVED) 86075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tab = helpTransfer(tab, f); 86175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 86275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V oldVal = null; 86375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle synchronized (f) { 86475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tabAt(tab, i) == f) { 86575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (fh >= 0) { 86675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle binCount = 1; 86775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> e = f;; ++binCount) { 86875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K ek; 86975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e.hash == hash && 87075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == key || 87175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (ek != null && key.equals(ek)))) { 87275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle oldVal = e.val; 87375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!onlyIfAbsent) 87475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e.val = value; 87575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 87675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 87775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> pred = e; 87875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((e = e.next) == null) { 87975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pred.next = new Node<K,V>(hash, key, 88075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle value, null); 88175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 88275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 88375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 88475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 88575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (f instanceof TreeBin) { 88675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 88775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle binCount = 2; 88875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key, 88975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle value)) != null) { 89075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle oldVal = p.val; 89175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!onlyIfAbsent) 89275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.val = value; 89375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 89475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 89575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 89675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 89775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (binCount != 0) { 89875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (binCount >= TREEIFY_THRESHOLD) 89975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle treeifyBin(tab, i); 90075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (oldVal != null) 90175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return oldVal; 90275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 90375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 90475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 90575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 90675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle addCount(1L, binCount); 90775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copies all of the mappings from the specified map to this one. 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * These mappings replace any mappings that this map had for any of the 913bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * keys currently in the specified map. 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 915bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param m mappings to be stored in this map 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 917bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public void putAll(Map<? extends K, ? extends V> m) { 91875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tryPresize(m.size()); 919bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) 92075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle putVal(e.getKey(), e.getValue(), false); 921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 924bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Removes the key (and its corresponding value) from this map. 925bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * This method does nothing if the key is not in the map. 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 927bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param key the key that needs to be removed 92875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the previous value associated with {@code key}, or 92975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code null} if there was no mapping for {@code key} 930bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified key is null 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V remove(Object key) { 93375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return replaceNode(key, null, null); 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 93775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Implementation for the four public remove/replace methods: 93875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Replaces node value with v, conditional upon match of cv if 93975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * non-null. If resulting value is null, delete. 940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 94175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final V replaceNode(Object key, V value, Object cv) { 94275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int hash = spread(key.hashCode()); 94375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V>[] tab = table;;) { 94475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> f; int n, i, fh; 94575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tab == null || (n = tab.length) == 0 || 94675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (f = tabAt(tab, i = (n - 1) & hash)) == null) 94775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 94875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((fh = f.hash) == MOVED) 94975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tab = helpTransfer(tab, f); 95075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 95175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V oldVal = null; 95275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean validated = false; 95375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle synchronized (f) { 95475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tabAt(tab, i) == f) { 95575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (fh >= 0) { 95675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle validated = true; 95775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> e = f, pred = null;;) { 95875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K ek; 95975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e.hash == hash && 96075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == key || 96175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (ek != null && key.equals(ek)))) { 96275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V ev = e.val; 96375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (cv == null || cv == ev || 96475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (ev != null && cv.equals(ev))) { 96575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle oldVal = ev; 96675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (value != null) 96775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e.val = value; 96875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pred != null) 96975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pred.next = e.next; 97075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 97175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, i, e.next); 97275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 97375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 97475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 97575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pred = e; 97675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((e = e.next) == null) 97775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 97875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 97975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 98075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (f instanceof TreeBin) { 98175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle validated = true; 98275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeBin<K,V> t = (TreeBin<K,V>)f; 98375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> r, p; 98475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((r = t.root) != null && 98575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (p = r.findTreeNode(hash, key, null)) != null) { 98675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V pv = p.val; 98775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (cv == null || cv == pv || 98875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (pv != null && cv.equals(pv))) { 98975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle oldVal = pv; 99075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (value != null) 99175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.val = value; 99275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (t.removeTreeNode(p)) 99375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, i, untreeify(t.first)); 99475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 99575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 99675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 99775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 99875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 99975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (validated) { 100075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (oldVal != null) { 100175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (value == null) 100275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle addCount(-1L, -1); 100375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return oldVal; 100475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 100575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 100675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 100775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 100875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 100975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1013bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Removes all of the mappings from this map. 1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() { 101675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long delta = 0L; // negative number of deletions 101775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int i = 0; 101875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab = table; 101975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (tab != null && i < tab.length) { 102075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int fh; 102175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> f = tabAt(tab, i); 102275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (f == null) 102375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++i; 102475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((fh = f.hash) == MOVED) { 102575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tab = helpTransfer(tab, f); 102675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle i = 0; // restart 102775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 102875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 102975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle synchronized (f) { 103075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tabAt(tab, i) == f) { 103175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p = (fh >= 0 ? f : 103275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (f instanceof TreeBin) ? 103375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((TreeBin<K,V>)f).first : null); 103475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (p != null) { 103575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle --delta; 103675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = p.next; 103775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 103875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, i++, null); 103975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 104075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 104175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1042a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 104375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (delta != 0L) 104475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle addCount(delta, -1); 1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1048bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns a {@link Set} view of the keys contained in this map. 1049bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The set is backed by the map, so changes to the map are 105075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * reflected in the set, and vice-versa. The set supports element 1051bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * removal, which removes the corresponding mapping from this map, 105275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * via the {@code Iterator.remove}, {@code Set.remove}, 105375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code removeAll}, {@code retainAll}, and {@code clear} 105475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * operations. It does not support the {@code add} or 105575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code addAll} operations. 1056bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 105775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>The view's {@code iterator} is a "weakly consistent" iterator 1058bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * that will never throw {@link ConcurrentModificationException}, 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and guarantees to traverse elements as they existed upon 1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * construction of the iterator, and may (but is not guaranteed to) 1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reflect any modifications subsequent to construction. 106275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 106375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the set view 1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1065edf43d27e240d82106f39ae91404963c23987234Narayan Kamath // android-note : changed KeySetView<K,V> to Set<K> to maintain API compatibility. 1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set<K> keySet() { 106775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle KeySetView<K,V> ks; 106875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null)); 1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1072bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns a {@link Collection} view of the values contained in this map. 1073bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The collection is backed by the map, so changes to the map are 1074bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * reflected in the collection, and vice-versa. The collection 1075bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * supports element removal, which removes the corresponding 107675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * mapping from this map, via the {@code Iterator.remove}, 107775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code Collection.remove}, {@code removeAll}, 107875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code retainAll}, and {@code clear} operations. It does not 107975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * support the {@code add} or {@code addAll} operations. 1080bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 108175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>The view's {@code iterator} is a "weakly consistent" iterator 1082bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * that will never throw {@link ConcurrentModificationException}, 1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and guarantees to traverse elements as they existed upon 1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * construction of the iterator, and may (but is not guaranteed to) 1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reflect any modifications subsequent to construction. 108675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 108775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the collection view 1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Collection<V> values() { 109075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ValuesView<K,V> vs; 109175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (vs = values) != null ? vs : (values = new ValuesView<K,V>(this)); 1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1095bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns a {@link Set} view of the mappings contained in this map. 1096bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The set is backed by the map, so changes to the map are 1097bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * reflected in the set, and vice-versa. The set supports element 1098bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * removal, which removes the corresponding mapping from the map, 109975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * via the {@code Iterator.remove}, {@code Set.remove}, 110075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code removeAll}, {@code retainAll}, and {@code clear} 110175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * operations. 1102bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 110375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>The view's {@code iterator} is a "weakly consistent" iterator 1104bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * that will never throw {@link ConcurrentModificationException}, 1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and guarantees to traverse elements as they existed upon 1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * construction of the iterator, and may (but is not guaranteed to) 1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reflect any modifications subsequent to construction. 110875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 110975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the set view 1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set<Map.Entry<K,V>> entrySet() { 111275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle EntrySetView<K,V> es; 111375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (es = entrySet) != null ? es : (entrySet = new EntrySetView<K,V>(this)); 1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 111775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the hash code value for this {@link Map}, i.e., 111875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the sum of, for each key-value pair in the map, 111975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code key.hashCode() ^ value.hashCode()}. 1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 112175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the hash code value for this map 1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 112375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public int hashCode() { 112475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = 0; 112575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 112675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((t = table) != null) { 112775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 112875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p; (p = it.advance()) != null; ) 112975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h += p.key.hashCode() ^ p.val.hashCode(); 113075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 113175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return h; 1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 113575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a string representation of this map. The string 113675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * representation consists of a list of key-value mappings (in no 113775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * particular order) enclosed in braces ("{@code {}}"). Adjacent 113875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * mappings are separated by the characters {@code ", "} (comma 113975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * and space). Each key-value mapping is rendered as the key 114075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * followed by an equals sign ("{@code =}") followed by the 114175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * associated value. 1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 114375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return a string representation of this map 1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 114575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public String toString() { 114675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 114775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = table) == null ? 0 : t.length; 114875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, f, 0, f); 114975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle StringBuilder sb = new StringBuilder(); 115075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append('{'); 115175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 115275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = it.advance()) != null) { 1153a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson for (;;) { 115475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K k = p.key; 115575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v = p.val; 115675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append(k == this ? "(this Map)" : k); 115775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append('='); 115875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append(v == this ? "(this Map)" : v); 115975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = it.advance()) == null) 1160a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson break; 116175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append(',').append(' '); 1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 116475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return sb.append('}').toString(); 1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 116875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Compares the specified object with this map for equality. 116975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns {@code true} if the given object is a map with the same 117075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * mappings as this map. This operation may return misleading 117175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * results if either map is concurrently modified during execution 117275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of this method. 117375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 117475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param o object to be compared for equality with this map 117575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if the specified object is equal to this map 1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 117775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean equals(Object o) { 117875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (o != this) { 117975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!(o instanceof Map)) 1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 118175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Map<?,?> m = (Map<?,?>) o; 118275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 118375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = table) == null ? 0 : t.length; 118475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, f, 0, f); 118575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p; (p = it.advance()) != null; ) { 118675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V val = p.val; 118775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object v = m.get(p.key); 118875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (v == null || (v != val && !v.equals(val))) 118975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 119075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 119175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Map.Entry<?,?> e : m.entrySet()) { 119275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object mk, mv, v; 119375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((mk = e.getKey()) == null || 119475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (mv = e.getValue()) == null || 119575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v = get(mk)) == null || 119675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (mv != v && !mv.equals(v))) 119775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 119875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 120075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 120375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 120475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Stripped-down version of helper class used in previous version, 120575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * declared for the sake of serialization compatibility 120675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 120775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static class Segment<K,V> extends ReentrantLock implements Serializable { 120875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long serialVersionUID = 2249069246763182397L; 120975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final float loadFactor; 121075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Segment(float lf) { this.loadFactor = lf; } 121175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 121475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Saves the state of the {@code ConcurrentHashMap} instance to a 1215a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * stream (i.e., serializes it). 1216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param s the stream 1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @serialData 1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the key (Object) and value (Object) 1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for each key-value mapping, followed by a null pair. 1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The key-value mappings are emitted in no particular order. 1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1222a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson private void writeObject(java.io.ObjectOutputStream s) 122375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throws java.io.IOException { 122475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // For serialization compatibility 122575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // Emulate segment calculation from previous version of this class 122675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int sshift = 0; 122775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int ssize = 1; 122875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (ssize < DEFAULT_CONCURRENCY_LEVEL) { 122975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++sshift; 123075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ssize <<= 1; 123175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 123275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int segmentShift = 32 - sshift; 123375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int segmentMask = ssize - 1; 123475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings("unchecked") Segment<K,V>[] segments = (Segment<K,V>[]) 123575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL]; 123675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int i = 0; i < segments.length; ++i) 123775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle segments[i] = new Segment<K,V>(LOAD_FACTOR); 1238edf43d27e240d82106f39ae91404963c23987234Narayan Kamath java.io.ObjectOutputStream.PutField streamFields = s.putFields(); 1239edf43d27e240d82106f39ae91404963c23987234Narayan Kamath streamFields.put("segments", segments); 1240edf43d27e240d82106f39ae91404963c23987234Narayan Kamath streamFields.put("segmentShift", segmentShift); 1241edf43d27e240d82106f39ae91404963c23987234Narayan Kamath streamFields.put("segmentMask", segmentMask); 124275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s.writeFields(); 124375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 124475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 124575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((t = table) != null) { 124675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 124775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p; (p = it.advance()) != null; ) { 124875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s.writeObject(p.key); 124975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s.writeObject(p.val); 1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.writeObject(null); 1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.writeObject(null); 125475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle segments = null; // throw away 1255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 125875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Reconstitutes the instance from a stream (that is, deserializes it). 1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param s the stream 1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void readObject(java.io.ObjectInputStream s) 126275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throws java.io.IOException, ClassNotFoundException { 126375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* 126475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * To improve performance in typical cases, we create nodes 126575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * while reading, then place in table once size is known. 126675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * However, we must also validate uniqueness and deal with 126775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * overpopulated bins while doing so, which requires 126875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * specialized versions of putVal mechanics. 126975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 127075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = -1; // force exclusion for table construction 1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.defaultReadObject(); 127275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long size = 0L; 127375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p = null; 127475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (;;) { 127575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings("unchecked") K k = (K) s.readObject(); 127675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings("unchecked") V v = (V) s.readObject(); 127775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (k != null && v != null) { 127875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = new Node<K,V>(spread(k.hashCode()), k, v, p); 127975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++size; 128075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 128175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 128275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 128375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 128475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (size == 0L) 128575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = 0; 128675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 128775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n; 128875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (size >= (long)(MAXIMUM_CAPACITY >>> 1)) 128975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n = MAXIMUM_CAPACITY; 129075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 129175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int sz = (int)size; 129275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n = tableSizeFor(sz + (sz >>> 1) + 1); 129375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1294edf43d27e240d82106f39ae91404963c23987234Narayan Kamath @SuppressWarnings("unchecked") 1295edf43d27e240d82106f39ae91404963c23987234Narayan Kamath Node<K,V>[] tab = (Node<K,V>[])new Node<?,?>[n]; 129675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int mask = n - 1; 129775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long added = 0L; 129875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (p != null) { 129975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean insertAtFront; 130075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> next = p.next, first; 130175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = p.hash, j = h & mask; 130275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((first = tabAt(tab, j)) == null) 130375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle insertAtFront = true; 130475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 130575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K k = p.key; 130675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (first.hash < 0) { 130775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeBin<K,V> t = (TreeBin<K,V>)first; 130875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (t.putTreeVal(h, k, p.val) == null) 130975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++added; 131075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle insertAtFront = false; 131175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 131275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 131375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int binCount = 0; 131475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle insertAtFront = true; 131575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> q; K qk; 131675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (q = first; q != null; q = q.next) { 131775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (q.hash == h && 131875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((qk = q.key) == k || 131975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (qk != null && k.equals(qk)))) { 132075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle insertAtFront = false; 132175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 132275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 132375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++binCount; 132475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 132575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (insertAtFront && binCount >= TREEIFY_THRESHOLD) { 132675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle insertAtFront = false; 132775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++added; 132875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.next = first; 132975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> hd = null, tl = null; 133075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (q = p; q != null; q = q.next) { 133175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> t = new TreeNode<K,V> 133275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (q.hash, q.key, q.val, null, null); 133375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((t.prev = tl) == null) 133475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hd = t; 133575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 133675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl.next = t; 133775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl = t; 133875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 133975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, j, new TreeBin<K,V>(hd)); 134075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 134175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 134275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 134375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (insertAtFront) { 134475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++added; 134575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.next = first; 134675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, j, p); 134775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 134875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = next; 1349a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 135075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle table = tab; 135175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = n - (n >>> 2); 135275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle baseCount = added; 1353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 135475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 135675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // ConcurrentMap methods 135775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 135875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 135975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 136075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 136175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the previous value associated with the specified key, 136275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * or {@code null} if there was no mapping for the key 136375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key or value is null 136475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 136575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public V putIfAbsent(K key, V value) { 136675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return putVal(key, value, true); 136775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 136875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 136975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 137075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 137175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 137275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key is null 137375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 137475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean remove(Object key, Object value) { 137575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (key == null) 137675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NullPointerException(); 137775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return value != null && replaceNode(key, null, value) != null; 137875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 137975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 138075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 138175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 138275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 138375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if any of the arguments are null 138475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 138575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean replace(K key, V oldValue, V newValue) { 138675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (key == null || oldValue == null || newValue == null) 138775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NullPointerException(); 138875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return replaceNode(key, newValue, oldValue) != null; 138975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 139075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 139175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 139275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 139375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 139475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the previous value associated with the specified key, 139575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * or {@code null} if there was no mapping for the key 139675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key or value is null 139775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 139875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public V replace(K key, V value) { 139975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (key == null || value == null) 140075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NullPointerException(); 140175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return replaceNode(key, value, null); 140275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 140375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // Hashtable legacy methods 140475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 140575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 140675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Legacy method testing if some key maps into the specified value 1407edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * in this table. 1408edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * 1409edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * This method is identical in functionality to 141075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@link #containsValue(Object)}, and exists solely to ensure 1411edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * full compatibility with class {@link java.util.Hashtable}, 1412edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * which supported this method prior to introduction of the 1413edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Java Collections framework. 141475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 141575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param value a value to search for 141675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if and only if some key maps to the 141775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code value} argument in this table as 141875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * determined by the {@code equals} method; 141975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code false} otherwise 142075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified value is null 142175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 1422edf43d27e240d82106f39ae91404963c23987234Narayan Kamath // android-note : removed @deprecated tag from javadoc. 142375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean contains(Object value) { 142475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // BEGIN android-note 142575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // removed deprecation 142675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // END android-note 142775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return containsValue(value); 142875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 142975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 143075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 143175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns an enumeration of the keys in this table. 143275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 143375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return an enumeration of the keys in this table 143475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @see #keySet() 143575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 143675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public Enumeration<K> keys() { 143775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 143875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = table) == null ? 0 : t.length; 143975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new KeyIterator<K,V>(t, f, 0, f, this); 144075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 144175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 144275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 144375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns an enumeration of the values in this table. 144475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 144575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return an enumeration of the values in this table 144675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @see #values() 144775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 144875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public Enumeration<V> elements() { 144975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 145075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = table) == null ? 0 : t.length; 145175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new ValueIterator<K,V>(t, f, 0, f, this); 145275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 145375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 145475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // ConcurrentHashMap-only methods 145575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 145675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 145775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the number of mappings. This method should be used 145875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * instead of {@link #size} because a ConcurrentHashMap may 145975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * contain more mappings than can be represented as an int. The 146075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * value returned is an estimate; the actual count may differ if 146175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * there are concurrent insertions or removals. 146275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 146375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the number of mappings 146475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @since 1.8 146575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 146675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @hide 146775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 146875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public long mappingCount() { 146975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long n = sumCount(); 147075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (n < 0L) ? 0L : n; // ignore transient negative values 147175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 147275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 147375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 147475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new {@link Set} backed by a ConcurrentHashMap 147575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * from the given type to {@code Boolean.TRUE}. 147675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 1477edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * @param <K> the element type of the returned set 147875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the new set 147975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @since 1.8 148075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 148175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @hide 148275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 148375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public static <K> KeySetView<K,Boolean> newKeySet() { 148475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new KeySetView<K,Boolean> 148575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (new ConcurrentHashMap<K,Boolean>(), Boolean.TRUE); 148675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 148775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 148875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 148975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new {@link Set} backed by a ConcurrentHashMap 149075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * from the given type to {@code Boolean.TRUE}. 149175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 149275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param initialCapacity The implementation performs internal 149375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * sizing to accommodate this many elements. 1494edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * @param <K> the element type of the returned set 1495edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * @return the new set 149675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws IllegalArgumentException if the initial capacity of 149775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * elements is negative 149875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @since 1.8 149975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 150075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @hide 150175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 150275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) { 150375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new KeySetView<K,Boolean> 150475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (new ConcurrentHashMap<K,Boolean>(initialCapacity), Boolean.TRUE); 150575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 150675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 150775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 150875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a {@link Set} view of the keys in this map, using the 150975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * given common mapped value for any additions (i.e., {@link 151075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Collection#add} and {@link Collection#addAll(Collection)}). 151175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * This is of course only appropriate if it is acceptable to use 151275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the same value for all additions from this view. 151375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 151475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param mappedValue the mapped value to use for any additions 151575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the set view 151675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the mappedValue is null 151775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 151875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @hide 151975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 1520edf43d27e240d82106f39ae91404963c23987234Narayan Kamath public KeySetView<K,V> keySet(V mappedValue) { 152175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (mappedValue == null) 152275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NullPointerException(); 152375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new KeySetView<K,V>(this, mappedValue); 152475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 152575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 152675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Special Nodes -------------- */ 152775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 152875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 152975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * A node inserted at head of bins during transfer operations. 153075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 153175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class ForwardingNode<K,V> extends Node<K,V> { 153275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final Node<K,V>[] nextTable; 153375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ForwardingNode(Node<K,V>[] tab) { 153475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(MOVED, null, null, null); 153575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.nextTable = tab; 153675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 153775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 153875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> find(int h, Object k) { 153975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> e; int n; 154075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab = nextTable; 154175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (k != null && tab != null && (n = tab.length) > 0 && 154275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (e = tabAt(tab, (n - 1) & h)) != null) { 154375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle do { 154475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int eh; K ek; 154575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((eh = e.hash) == h && 154675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == k || (ek != null && k.equals(ek)))) 154775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e; 154875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (eh < 0) 154975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e.find(h, k); 155075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } while ((e = e.next) != null); 155175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 155275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 155375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 155475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 155575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 155675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 155775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * A place-holder node used in computeIfAbsent and compute 155875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 155975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class ReservationNode<K,V> extends Node<K,V> { 156075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ReservationNode() { 156175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(RESERVED, null, null, null); 156275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 156375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 156475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> find(int h, Object k) { 156575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 156675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 156775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 156875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 156975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Table Initialization and Resizing -------------- */ 157075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 157175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 1572edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Returns the stamp bits for resizing a table of size n. 1573edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Must be negative when shifted left by RESIZE_STAMP_SHIFT. 1574edf43d27e240d82106f39ae91404963c23987234Narayan Kamath */ 1575edf43d27e240d82106f39ae91404963c23987234Narayan Kamath static final int resizeStamp(int n) { 1576edf43d27e240d82106f39ae91404963c23987234Narayan Kamath return Integer.numberOfLeadingZeros(n) | (1 << (RESIZE_STAMP_BITS - 1)); 1577edf43d27e240d82106f39ae91404963c23987234Narayan Kamath } 1578edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 1579edf43d27e240d82106f39ae91404963c23987234Narayan Kamath /** 158075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Initializes table, using the size recorded in sizeCtl. 158175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 158275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final Node<K,V>[] initTable() { 158375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab; int sc; 158475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while ((tab = table) == null || tab.length == 0) { 158575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((sc = sizeCtl) < 0) 158675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Thread.yield(); // lost initialization race; just spin 158775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) { 158875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 158975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((tab = table) == null || tab.length == 0) { 159075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n = (sc > 0) ? sc : DEFAULT_CAPACITY; 1591edf43d27e240d82106f39ae91404963c23987234Narayan Kamath @SuppressWarnings("unchecked") 1592edf43d27e240d82106f39ae91404963c23987234Narayan Kamath Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n]; 159375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle table = tab = nt; 159475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sc = n - (n >>> 2); 159575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 159675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 159775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = sc; 159875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 159975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 160075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 160175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 160275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return tab; 160375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 160475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 160575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 160675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Adds to count, and if table is too small and not already 160775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * resizing, initiates transfer. If already resizing, helps 160875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * perform transfer if work is available. Rechecks occupancy 160975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * after a transfer to see if another resize is already needed 161075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * because resizings are lagging additions. 161175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 161275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param x the count to add 161375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param check if <0, don't check resize, if <= 1 only check if uncontended 161475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 161575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void addCount(long x, int check) { 161675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] as; long b, s; 161775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((as = counterCells) != null || 161875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) { 161975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterHashCode hc; CounterCell a; long v; int m; 162075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean uncontended = true; 162175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((hc = threadCounterHashCode.get()) == null || 162275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle as == null || (m = as.length - 1) < 0 || 162375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (a = as[m & hc.code]) == null || 162475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle !(uncontended = 162575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) { 162675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle fullAddCount(x, hc, uncontended); 162775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return; 162875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 162975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (check <= 1) 163075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return; 163175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s = sumCount(); 163275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 163375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (check >= 0) { 1634edf43d27e240d82106f39ae91404963c23987234Narayan Kamath Node<K,V>[] tab, nt; int n, sc; 163575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (s >= (long)(sc = sizeCtl) && (tab = table) != null && 1636edf43d27e240d82106f39ae91404963c23987234Narayan Kamath (n = tab.length) < MAXIMUM_CAPACITY) { 1637edf43d27e240d82106f39ae91404963c23987234Narayan Kamath int rs = resizeStamp(n); 163875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sc < 0) { 1639edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || 1640edf43d27e240d82106f39ae91404963c23987234Narayan Kamath sc == rs + MAX_RESIZERS || (nt = nextTable) == null || 1641edf43d27e240d82106f39ae91404963c23987234Narayan Kamath transferIndex <= 0) 164275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 1643edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) 164475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transfer(tab, nt); 164575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1646edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if (U.compareAndSwapInt(this, SIZECTL, sc, 1647edf43d27e240d82106f39ae91404963c23987234Narayan Kamath (rs << RESIZE_STAMP_SHIFT) + 2)) 164875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transfer(tab, null); 164975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s = sumCount(); 165075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 165175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 165275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 165375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 165475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 165575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Helps transfer if a resize is in progress. 165675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 165775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) { 165875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] nextTab; int sc; 1659edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (tab != null && (f instanceof ForwardingNode) && 166075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) { 1661edf43d27e240d82106f39ae91404963c23987234Narayan Kamath int rs = resizeStamp(tab.length); 1662edf43d27e240d82106f39ae91404963c23987234Narayan Kamath while (nextTab == nextTable && table == tab && 1663edf43d27e240d82106f39ae91404963c23987234Narayan Kamath (sc = sizeCtl) < 0) { 1664edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || 1665edf43d27e240d82106f39ae91404963c23987234Narayan Kamath sc == rs + MAX_RESIZERS || transferIndex <= 0) 1666edf43d27e240d82106f39ae91404963c23987234Narayan Kamath break; 1667edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) { 1668edf43d27e240d82106f39ae91404963c23987234Narayan Kamath transfer(tab, nextTab); 1669edf43d27e240d82106f39ae91404963c23987234Narayan Kamath break; 1670edf43d27e240d82106f39ae91404963c23987234Narayan Kamath } 1671edf43d27e240d82106f39ae91404963c23987234Narayan Kamath } 167275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return nextTab; 167375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 167475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return table; 167575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 167675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 167775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 167875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Tries to presize table to accommodate the given number of elements. 167975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 168075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param size number of elements (doesn't need to be perfectly accurate) 168175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 168275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void tryPresize(int size) { 168375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY : 168475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tableSizeFor(size + (size >>> 1) + 1); 168575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int sc; 168675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while ((sc = sizeCtl) >= 0) { 168775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab = table; int n; 168875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tab == null || (n = tab.length) == 0) { 168975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n = (sc > c) ? sc : c; 169075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) { 169175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 169275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (table == tab) { 1693edf43d27e240d82106f39ae91404963c23987234Narayan Kamath @SuppressWarnings("unchecked") 1694edf43d27e240d82106f39ae91404963c23987234Narayan Kamath Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n]; 169575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle table = nt; 169675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sc = n - (n >>> 2); 169775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 169875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 169975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = sc; 170075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 170175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 170275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 170375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (c <= sc || n >= MAXIMUM_CAPACITY) 170475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 1705edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if (tab == table) { 1706edf43d27e240d82106f39ae91404963c23987234Narayan Kamath int rs = resizeStamp(n); 1707edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (sc < 0) { 1708edf43d27e240d82106f39ae91404963c23987234Narayan Kamath Node<K,V>[] nt; 1709edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || 1710edf43d27e240d82106f39ae91404963c23987234Narayan Kamath sc == rs + MAX_RESIZERS || (nt = nextTable) == null || 1711edf43d27e240d82106f39ae91404963c23987234Narayan Kamath transferIndex <= 0) 1712edf43d27e240d82106f39ae91404963c23987234Narayan Kamath break; 1713edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) 1714edf43d27e240d82106f39ae91404963c23987234Narayan Kamath transfer(tab, nt); 1715edf43d27e240d82106f39ae91404963c23987234Narayan Kamath } 1716edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if (U.compareAndSwapInt(this, SIZECTL, sc, 1717edf43d27e240d82106f39ae91404963c23987234Narayan Kamath (rs << RESIZE_STAMP_SHIFT) + 2)) 1718edf43d27e240d82106f39ae91404963c23987234Narayan Kamath transfer(tab, null); 1719edf43d27e240d82106f39ae91404963c23987234Narayan Kamath } 172075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 172175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 172275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 172375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 172475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Moves and/or copies the nodes in each bin to new table. See 172575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * above for explanation. 172675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 172775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) { 172875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n = tab.length, stride; 172975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE) 173075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle stride = MIN_TRANSFER_STRIDE; // subdivide range 173175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (nextTab == null) { // initiating 173275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 1733edf43d27e240d82106f39ae91404963c23987234Narayan Kamath @SuppressWarnings("unchecked") 1734edf43d27e240d82106f39ae91404963c23987234Narayan Kamath Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1]; 173575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle nextTab = nt; 173675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } catch (Throwable ex) { // try to cope with OOME 173775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = Integer.MAX_VALUE; 173875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return; 173975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 174075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle nextTable = nextTab; 174175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transferIndex = n; 174275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 174375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int nextn = nextTab.length; 174475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab); 174575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean advance = true; 1746edf43d27e240d82106f39ae91404963c23987234Narayan Kamath boolean finishing = false; // to ensure sweep before committing nextTab 174775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int i = 0, bound = 0;;) { 1748edf43d27e240d82106f39ae91404963c23987234Narayan Kamath Node<K,V> f; int fh; 174975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (advance) { 1750edf43d27e240d82106f39ae91404963c23987234Narayan Kamath int nextIndex, nextBound; 1751edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (--i >= bound || finishing) 175275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance = false; 1753edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if ((nextIndex = transferIndex) <= 0) { 175475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle i = -1; 175575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance = false; 175675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 175775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (U.compareAndSwapInt 175875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (this, TRANSFERINDEX, nextIndex, 175975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle nextBound = (nextIndex > stride ? 176075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle nextIndex - stride : 0))) { 176175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle bound = nextBound; 176275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle i = nextIndex - 1; 176375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance = false; 176475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 176575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 176675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (i < 0 || i >= n || i + n >= nextn) { 1767edf43d27e240d82106f39ae91404963c23987234Narayan Kamath int sc; 1768edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (finishing) { 1769edf43d27e240d82106f39ae91404963c23987234Narayan Kamath nextTable = null; 1770edf43d27e240d82106f39ae91404963c23987234Narayan Kamath table = nextTab; 1771edf43d27e240d82106f39ae91404963c23987234Narayan Kamath sizeCtl = (n << 1) - (n >>> 1); 1772edf43d27e240d82106f39ae91404963c23987234Narayan Kamath return; 177375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1774edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, sc - 1)) { 1775edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if ((sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT) 1776edf43d27e240d82106f39ae91404963c23987234Narayan Kamath return; 1777edf43d27e240d82106f39ae91404963c23987234Narayan Kamath finishing = advance = true; 1778edf43d27e240d82106f39ae91404963c23987234Narayan Kamath i = n; // recheck before commit 177975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 178075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1781edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if ((f = tabAt(tab, i)) == null) 1782edf43d27e240d82106f39ae91404963c23987234Narayan Kamath advance = casTabAt(tab, i, null, fwd); 178375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((fh = f.hash) == MOVED) 178475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance = true; // already processed 178575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 178675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle synchronized (f) { 178775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tabAt(tab, i) == f) { 178875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> ln, hn; 178975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (fh >= 0) { 179075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int runBit = fh & n; 179175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> lastRun = f; 179275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p = f.next; p != null; p = p.next) { 179375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int b = p.hash & n; 179475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (b != runBit) { 179575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle runBit = b; 179675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lastRun = p; 179775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 179875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 179975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (runBit == 0) { 180075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ln = lastRun; 180175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hn = null; 180275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 180375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 180475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hn = lastRun; 180575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ln = null; 180675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 180775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p = f; p != lastRun; p = p.next) { 180875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int ph = p.hash; K pk = p.key; V pv = p.val; 180975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((ph & n) == 0) 181075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ln = new Node<K,V>(ph, pk, pv, ln); 181175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 181275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hn = new Node<K,V>(ph, pk, pv, hn); 181375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1814edf43d27e240d82106f39ae91404963c23987234Narayan Kamath setTabAt(nextTab, i, ln); 1815edf43d27e240d82106f39ae91404963c23987234Narayan Kamath setTabAt(nextTab, i + n, hn); 1816edf43d27e240d82106f39ae91404963c23987234Narayan Kamath setTabAt(tab, i, fwd); 1817edf43d27e240d82106f39ae91404963c23987234Narayan Kamath advance = true; 181875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 181975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (f instanceof TreeBin) { 182075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeBin<K,V> t = (TreeBin<K,V>)f; 182175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> lo = null, loTail = null; 182275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> hi = null, hiTail = null; 182375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int lc = 0, hc = 0; 182475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> e = t.first; e != null; e = e.next) { 182575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = e.hash; 182675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> p = new TreeNode<K,V> 182775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (h, e.key, e.val, null, null); 182875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((h & n) == 0) { 182975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p.prev = loTail) == null) 183075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lo = p; 183175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 183275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle loTail.next = p; 183375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle loTail = p; 183475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++lc; 183575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 183675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 183775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p.prev = hiTail) == null) 183875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hi = p; 183975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 184075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hiTail.next = p; 184175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hiTail = p; 184275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++hc; 184375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 184475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 184575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ln = (lc <= UNTREEIFY_THRESHOLD) ? untreeify(lo) : 184675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (hc != 0) ? new TreeBin<K,V>(lo) : t; 184775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hn = (hc <= UNTREEIFY_THRESHOLD) ? untreeify(hi) : 184875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (lc != 0) ? new TreeBin<K,V>(hi) : t; 1849edf43d27e240d82106f39ae91404963c23987234Narayan Kamath setTabAt(nextTab, i, ln); 1850edf43d27e240d82106f39ae91404963c23987234Narayan Kamath setTabAt(nextTab, i + n, hn); 1851edf43d27e240d82106f39ae91404963c23987234Narayan Kamath setTabAt(tab, i, fwd); 1852edf43d27e240d82106f39ae91404963c23987234Narayan Kamath advance = true; 185375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 185475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 185575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 185675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 185775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 185875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 185975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 186075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Conversion from/to TreeBins -------------- */ 186175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 186275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 186375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Replaces all linked nodes in bin at given index unless table is 186475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * too small, in which case resizes instead. 186575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 186675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void treeifyBin(Node<K,V>[] tab, int index) { 186775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> b; int n, sc; 186875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tab != null) { 1869edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if ((n = tab.length) < MIN_TREEIFY_CAPACITY) 1870edf43d27e240d82106f39ae91404963c23987234Narayan Kamath tryPresize(n << 1); 1871edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if ((b = tabAt(tab, index)) != null && b.hash >= 0) { 187275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle synchronized (b) { 187375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tabAt(tab, index) == b) { 187475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> hd = null, tl = null; 187575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> e = b; e != null; e = e.next) { 187675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> p = 187775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new TreeNode<K,V>(e.hash, e.key, e.val, 187875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle null, null); 187975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p.prev = tl) == null) 188075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hd = p; 188175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 188275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl.next = p; 188375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl = p; 188475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 188575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, index, new TreeBin<K,V>(hd)); 188675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 188775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 188875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 188975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 189075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 189175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 189275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 189375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a list on non-TreeNodes replacing those in given list. 189475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 189575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> Node<K,V> untreeify(Node<K,V> b) { 189675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> hd = null, tl = null; 189775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> q = b; q != null; q = q.next) { 189875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p = new Node<K,V>(q.hash, q.key, q.val, null); 189975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tl == null) 190075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hd = p; 190175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 190275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl.next = p; 190375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl = p; 190475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 190575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return hd; 190675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 190775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 190875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- TreeNodes -------------- */ 190975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 191075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 191175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Nodes for use in TreeBins 191275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 191375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class TreeNode<K,V> extends Node<K,V> { 191475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> parent; // red-black tree links 191575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> left; 191675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> right; 191775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> prev; // needed to unlink next upon deletion 191875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean red; 191975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 192075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode(int hash, K key, V val, Node<K,V> next, 192175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> parent) { 192275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(hash, key, val, next); 192375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.parent = parent; 192475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 192575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 192675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> find(int h, Object k) { 192775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return findTreeNode(h, k, null); 192875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 192975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 193075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 193175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the TreeNode (or null if not found) for the given key 193275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * starting at given root. 193375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 193475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final TreeNode<K,V> findTreeNode(int h, Object k, Class<?> kc) { 193575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (k != null) { 193675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> p = this; 1937edf43d27e240d82106f39ae91404963c23987234Narayan Kamath do { 193875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int ph, dir; K pk; TreeNode<K,V> q; 193975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pl = p.left, pr = p.right; 194075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((ph = p.hash) > h) 194175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = pl; 194275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (ph < h) 194375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = pr; 194475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((pk = p.key) == k || (pk != null && k.equals(pk))) 194575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return p; 1946edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if (pl == null) 1947edf43d27e240d82106f39ae91404963c23987234Narayan Kamath p = pr; 1948edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if (pr == null) 1949edf43d27e240d82106f39ae91404963c23987234Narayan Kamath p = pl; 195075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((kc != null || 195175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (kc = comparableClassFor(k)) != null) && 195275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (dir = compareComparables(kc, k, pk)) != 0) 195375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = (dir < 0) ? pl : pr; 1954edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if ((q = pr.findTreeNode(h, k, kc)) != null) 195575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return q; 1956edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else 1957edf43d27e240d82106f39ae91404963c23987234Narayan Kamath p = pl; 195875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } while (p != null); 195975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 196075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 196175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 196275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 196375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 1964edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 196575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- TreeBins -------------- */ 196675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 196775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 196875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * TreeNodes used at the heads of bins. TreeBins do not hold user 196975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * keys or values, but instead point to list of TreeNodes and 197075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * their root. They also maintain a parasitic read-write lock 197175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * forcing writers (who hold bin lock) to wait for readers (who do 197275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * not) to complete before tree restructuring operations. 197375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 197475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class TreeBin<K,V> extends Node<K,V> { 197575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> root; 197675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile TreeNode<K,V> first; 197775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile Thread waiter; 197875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile int lockState; 197975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // values for lockState 198075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int WRITER = 1; // set while holding write lock 198175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int WAITER = 2; // set when waiting for write lock 198275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int READER = 4; // increment value for setting read lock 198375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 198475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 1985edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Tie-breaking utility for ordering insertions when equal 1986edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * hashCodes and non-comparable. We don't require a total 1987edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * order, just a consistent insertion rule to maintain 1988edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * equivalence across rebalancings. Tie-breaking further than 1989edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * necessary simplifies testing a bit. 1990edf43d27e240d82106f39ae91404963c23987234Narayan Kamath */ 1991edf43d27e240d82106f39ae91404963c23987234Narayan Kamath static int tieBreakOrder(Object a, Object b) { 1992edf43d27e240d82106f39ae91404963c23987234Narayan Kamath int d; 1993edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (a == null || b == null || 1994edf43d27e240d82106f39ae91404963c23987234Narayan Kamath (d = a.getClass().getName(). 1995edf43d27e240d82106f39ae91404963c23987234Narayan Kamath compareTo(b.getClass().getName())) == 0) 1996edf43d27e240d82106f39ae91404963c23987234Narayan Kamath d = (System.identityHashCode(a) <= System.identityHashCode(b) ? 1997edf43d27e240d82106f39ae91404963c23987234Narayan Kamath -1 : 1); 1998edf43d27e240d82106f39ae91404963c23987234Narayan Kamath return d; 1999edf43d27e240d82106f39ae91404963c23987234Narayan Kamath } 2000edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 2001edf43d27e240d82106f39ae91404963c23987234Narayan Kamath /** 200275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates bin with initial set of nodes headed by b. 200375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 200475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeBin(TreeNode<K,V> b) { 200575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(TREEBIN, null, null, null); 200675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.first = b; 200775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> r = null; 200875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (TreeNode<K,V> x = b, next; x != null; x = next) { 200975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle next = (TreeNode<K,V>)x.next; 201075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.left = x.right = null; 201175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (r == null) { 201275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.parent = null; 201375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = false; 201475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = x; 201575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 201675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 2017edf43d27e240d82106f39ae91404963c23987234Narayan Kamath K k = x.key; 2018edf43d27e240d82106f39ae91404963c23987234Narayan Kamath int h = x.hash; 201975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> kc = null; 202075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (TreeNode<K,V> p = r;;) { 202175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int dir, ph; 2022edf43d27e240d82106f39ae91404963c23987234Narayan Kamath K pk = p.key; 2023edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if ((ph = p.hash) > h) 202475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = -1; 2025edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if (ph < h) 202675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = 1; 2027edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if ((kc == null && 2028edf43d27e240d82106f39ae91404963c23987234Narayan Kamath (kc = comparableClassFor(k)) == null) || 2029edf43d27e240d82106f39ae91404963c23987234Narayan Kamath (dir = compareComparables(kc, k, pk)) == 0) 2030edf43d27e240d82106f39ae91404963c23987234Narayan Kamath dir = tieBreakOrder(k, pk); 2031edf43d27e240d82106f39ae91404963c23987234Narayan Kamath TreeNode<K,V> xp = p; 203275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = (dir <= 0) ? p.left : p.right) == null) { 203375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.parent = xp; 203475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (dir <= 0) 203575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.left = x; 203675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 203775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.right = x; 203875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = balanceInsertion(r, x); 203975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 204075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 204175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 204275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 204375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 204475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.root = r; 2045edf43d27e240d82106f39ae91404963c23987234Narayan Kamath assert checkInvariants(root); 204675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 204775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 204875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 204975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Acquires write lock for tree restructuring. 205075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 205175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void lockRoot() { 205275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!U.compareAndSwapInt(this, LOCKSTATE, 0, WRITER)) 205375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle contendedLock(); // offload to separate method 205475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 205575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 205675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 205775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Releases write lock for tree restructuring. 205875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 205975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void unlockRoot() { 206075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lockState = 0; 206175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 206275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 206375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 206475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Possibly blocks awaiting root lock. 206575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 206675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void contendedLock() { 206775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean waiting = false; 206875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int s;;) { 2069edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (((s = lockState) & ~WAITER) == 0) { 207075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (U.compareAndSwapInt(this, LOCKSTATE, s, WRITER)) { 207175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (waiting) 207275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle waiter = null; 207375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return; 207475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 207575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 20764d75d062fa8392cb914829394f8bc76822fbc741You Kim else if ((s & WAITER) == 0) { 207775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (U.compareAndSwapInt(this, LOCKSTATE, s, s | WAITER)) { 207875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle waiting = true; 207975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle waiter = Thread.currentThread(); 208075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 208175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 208275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (waiting) 208375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle LockSupport.park(this); 208475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 208575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 208675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 208775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 208875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns matching node or null if none. Tries to search 208975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * using tree comparisons from root, but continues linear 209075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * search when lock not available. 209175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 209275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final Node<K,V> find(int h, Object k) { 209375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (k != null) { 2094edf43d27e240d82106f39ae91404963c23987234Narayan Kamath for (Node<K,V> e = first; e != null; ) { 209575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int s; K ek; 209675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (((s = lockState) & (WAITER|WRITER)) != 0) { 209775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e.hash == h && 209875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == k || (ek != null && k.equals(ek)))) 209975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e; 2100edf43d27e240d82106f39ae91404963c23987234Narayan Kamath e = e.next; 210175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 210275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (U.compareAndSwapInt(this, LOCKSTATE, s, 210375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s + READER)) { 210475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> r, p; 210575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 210675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = ((r = root) == null ? null : 210775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r.findTreeNode(h, k, null)); 210875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 210975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 211075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Thread w; 211175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int ls; 211275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle do {} while (!U.compareAndSwapInt 211375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (this, LOCKSTATE, 211475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ls = lockState, ls - READER)); 211575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (ls == (READER|WAITER) && (w = waiter) != null) 211675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle LockSupport.unpark(w); 211775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 211875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return p; 211975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 212075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 212175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 212275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 212375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 212475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 212575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 212675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Finds or adds a node. 212775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return null if added 212875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 2129edf43d27e240d82106f39ae91404963c23987234Narayan Kamath /** 2130edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Finds or adds a node. 2131edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * @return null if added 2132edf43d27e240d82106f39ae91404963c23987234Narayan Kamath */ 213375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final TreeNode<K,V> putTreeVal(int h, K k, V v) { 213475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> kc = null; 2135edf43d27e240d82106f39ae91404963c23987234Narayan Kamath boolean searched = false; 213675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (TreeNode<K,V> p = root;;) { 2137edf43d27e240d82106f39ae91404963c23987234Narayan Kamath int dir, ph; K pk; 213875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (p == null) { 213975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle first = root = new TreeNode<K,V>(h, k, v, null, null); 214075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 214175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 214275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((ph = p.hash) > h) 214375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = -1; 214475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (ph < h) 214575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = 1; 214675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((pk = p.key) == k || (pk != null && k.equals(pk))) 214775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return p; 214875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((kc == null && 214975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (kc = comparableClassFor(k)) == null) || 215075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (dir = compareComparables(kc, k, pk)) == 0) { 2151edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (!searched) { 2152edf43d27e240d82106f39ae91404963c23987234Narayan Kamath TreeNode<K,V> q, ch; 2153edf43d27e240d82106f39ae91404963c23987234Narayan Kamath searched = true; 2154edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (((ch = p.left) != null && 2155edf43d27e240d82106f39ae91404963c23987234Narayan Kamath (q = ch.findTreeNode(h, k, kc)) != null) || 2156edf43d27e240d82106f39ae91404963c23987234Narayan Kamath ((ch = p.right) != null && 2157edf43d27e240d82106f39ae91404963c23987234Narayan Kamath (q = ch.findTreeNode(h, k, kc)) != null)) 2158edf43d27e240d82106f39ae91404963c23987234Narayan Kamath return q; 2159edf43d27e240d82106f39ae91404963c23987234Narayan Kamath } 2160edf43d27e240d82106f39ae91404963c23987234Narayan Kamath dir = tieBreakOrder(k, pk); 216175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 2162edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 216375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> xp = p; 2164edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if ((p = (dir <= 0) ? p.left : p.right) == null) { 216575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> x, f = first; 216675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle first = x = new TreeNode<K,V>(h, k, v, f, xp); 216775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (f != null) 216875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle f.prev = x; 2169edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (dir <= 0) 217075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.left = x; 217175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 217275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.right = x; 217375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!xp.red) 217475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = true; 217575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 217675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lockRoot(); 217775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 217875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = balanceInsertion(root, x); 217975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 218075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle unlockRoot(); 218175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 218275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 218375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 218475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 218575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 218675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle assert checkInvariants(root); 218775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 218875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 218975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 219075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 219175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Removes the given node, that must be present before this 219275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * call. This is messier than typical red-black deletion code 219375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * because we cannot swap the contents of an interior node 219475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * with a leaf successor that is pinned by "next" pointers 219575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * that are accessible independently of lock. So instead we 219675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * swap the tree linkages. 219775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 219875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return true if now too small, so should be untreeified 219975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 220075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final boolean removeTreeNode(TreeNode<K,V> p) { 220175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> next = (TreeNode<K,V>)p.next; 220275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pred = p.prev; // unlink traversal pointers 220375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> r, rl; 220475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (pred == null) 220575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle first = next; 220675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 220775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pred.next = next; 220875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (next != null) 220975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle next.prev = pred; 221075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (first == null) { 221175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = null; 221275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 221375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 221475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((r = root) == null || r.right == null || // too small 221575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (rl = r.left) == null || rl.left == null) 221675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 221775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lockRoot(); 221875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 221975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> replacement; 222075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pl = p.left; 222175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pr = p.right; 222275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (pl != null && pr != null) { 222375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> s = pr, sl; 222475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while ((sl = s.left) != null) // find successor 222575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s = sl; 222675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean c = s.red; s.red = p.red; p.red = c; // swap colors 222775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> sr = s.right; 222875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pp = p.parent; 222975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (s == pr) { // p was s's direct parent 223075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.parent = s; 223175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s.right = p; 223275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 223375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 223475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> sp = s.parent; 223575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p.parent = sp) != null) { 223675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (s == sp.left) 223775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sp.left = p; 223875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 223975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sp.right = p; 224075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 224175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((s.right = pr) != null) 224275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pr.parent = s; 224375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 224475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.left = null; 224575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p.right = sr) != null) 224675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sr.parent = p; 224775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((s.left = pl) != null) 224875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pl.parent = s; 224975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((s.parent = pp) == null) 225075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = s; 225175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (p == pp.left) 225275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.left = s; 225375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 225475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.right = s; 225575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sr != null) 225675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle replacement = sr; 225775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 225875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle replacement = p; 225975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 226075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pl != null) 226175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle replacement = pl; 226275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pr != null) 226375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle replacement = pr; 226475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 226575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle replacement = p; 226675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (replacement != p) { 226775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pp = replacement.parent = p.parent; 226875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (pp == null) 226975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = replacement; 227075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (p == pp.left) 227175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.left = replacement; 227275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 227375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.right = replacement; 227475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.left = p.right = p.parent = null; 227575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 227675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 227775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = (p.red) ? r : balanceDeletion(r, replacement); 227875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 227975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (p == replacement) { // detach pointers 228075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pp; 228175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((pp = p.parent) != null) { 228275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (p == pp.left) 228375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.left = null; 228475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (p == pp.right) 228575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.right = null; 228675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.parent = null; 228775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 228875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 228975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 229075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle unlockRoot(); 229175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 229275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle assert checkInvariants(root); 229375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 229475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 229575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 229675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ------------------------------------------------------------ */ 229775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // Red-black tree methods, all adapted from CLR 229875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 229975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root, 230075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> p) { 230175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> r, pp, rl; 230275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (p != null && (r = p.right) != null) { 230375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((rl = p.right = r.left) != null) 230475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle rl.parent = p; 230575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((pp = r.parent = p.parent) == null) 230675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (root = r).red = false; 230775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pp.left == p) 230875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.left = r; 230975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 231075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.right = r; 231175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r.left = p; 231275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.parent = r; 231375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 231475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return root; 231575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 231675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 231775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root, 231875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> p) { 231975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> l, pp, lr; 232075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (p != null && (l = p.left) != null) { 232175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((lr = p.left = l.right) != null) 232275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lr.parent = p; 232375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((pp = l.parent = p.parent) == null) 232475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (root = l).red = false; 232575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pp.right == p) 232675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.right = l; 232775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 232875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.left = l; 232975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle l.right = p; 233075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.parent = l; 233175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 233275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return root; 233375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 233475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 233575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root, 233675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> x) { 233775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = true; 233875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (TreeNode<K,V> xp, xpp, xppl, xppr;;) { 233975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((xp = x.parent) == null) { 234075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = false; 234175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return x; 234275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 234375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (!xp.red || (xpp = xp.parent) == null) 234475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return root; 234575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xp == (xppl = xpp.left)) { 234675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((xppr = xpp.right) != null && xppr.red) { 234775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xppr.red = false; 234875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 234975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp.red = true; 235075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xpp; 235175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 235275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 235375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (x == xp.right) { 235475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateLeft(root, x = xp); 235575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp = (xp = x.parent) == null ? null : xp.parent; 235675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 235775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xp != null) { 235875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 235975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpp != null) { 236075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp.red = true; 236175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateRight(root, xpp); 236275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 236375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 236475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 236575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 236675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 236775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xppl != null && xppl.red) { 236875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xppl.red = false; 236975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 237075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp.red = true; 237175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xpp; 237275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 237375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 237475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (x == xp.left) { 237575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateRight(root, x = xp); 237675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp = (xp = x.parent) == null ? null : xp.parent; 237775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 237875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xp != null) { 237975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 238075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpp != null) { 238175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp.red = true; 238275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateLeft(root, xpp); 238375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 238475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 238575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 238675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 238775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 238875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 238975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 239075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root, 239175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> x) { 2392edf43d27e240d82106f39ae91404963c23987234Narayan Kamath for (TreeNode<K,V> xp, xpl, xpr;;) { 239375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (x == null || x == root) 239475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return root; 239575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((xp = x.parent) == null) { 239675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = false; 239775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return x; 239875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 239975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (x.red) { 240075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = false; 240175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return root; 240275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 240375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((xpl = xp.left) == x) { 240475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((xpr = xp.right) != null && xpr.red) { 240575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr.red = false; 240675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = true; 240775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateLeft(root, xp); 240875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr = (xp = x.parent) == null ? null : xp.right; 240975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 241075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpr == null) 241175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xp; 241275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 241375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> sl = xpr.left, sr = xpr.right; 241475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((sr == null || !sr.red) && 241575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (sl == null || !sl.red)) { 241675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr.red = true; 241775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xp; 241875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 241975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 242075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sr == null || !sr.red) { 242175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sl != null) 242275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sl.red = false; 242375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr.red = true; 242475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateRight(root, xpr); 242575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr = (xp = x.parent) == null ? 242675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle null : xp.right; 242775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 242875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpr != null) { 242975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr.red = (xp == null) ? false : xp.red; 243075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((sr = xpr.right) != null) 243175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sr.red = false; 243275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 243375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xp != null) { 243475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 243575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateLeft(root, xp); 243675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 243775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = root; 243875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 243975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 244075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 244175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { // symmetric 244275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpl != null && xpl.red) { 244375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl.red = false; 244475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = true; 244575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateRight(root, xp); 244675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl = (xp = x.parent) == null ? null : xp.left; 244775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 244875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpl == null) 244975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xp; 245075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 245175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> sl = xpl.left, sr = xpl.right; 245275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((sl == null || !sl.red) && 245375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (sr == null || !sr.red)) { 245475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl.red = true; 245575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xp; 245675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 245775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 245875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sl == null || !sl.red) { 245975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sr != null) 246075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sr.red = false; 246175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl.red = true; 246275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateLeft(root, xpl); 246375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl = (xp = x.parent) == null ? 246475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle null : xp.left; 246575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 246675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpl != null) { 246775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl.red = (xp == null) ? false : xp.red; 246875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((sl = xpl.left) != null) 246975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sl.red = false; 247075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 247175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xp != null) { 247275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 247375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateRight(root, xp); 247475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 247575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = root; 247675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 247775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 247875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 247975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 248075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 248175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 248275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 248375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Recursive invariant check 248475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 248575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> boolean checkInvariants(TreeNode<K,V> t) { 248675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right, 248775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tb = t.prev, tn = (TreeNode<K,V>)t.next; 248875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tb != null && tb.next != t) 248975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 249075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tn != null && tn.prev != t) 249175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 249275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tp != null && t != tp.left && t != tp.right) 249375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 249475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tl != null && (tl.parent != t || tl.hash > t.hash)) 249575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 249675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tr != null && (tr.parent != t || tr.hash < t.hash)) 249775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 249875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (t.red && tl != null && tl.red && tr != null && tr.red) 249975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 250075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tl != null && !checkInvariants(tl)) 250175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 250275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tr != null && !checkInvariants(tr)) 250375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 250475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 250575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 250675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 250775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final sun.misc.Unsafe U; 250875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long LOCKSTATE; 250975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static { 251075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 251175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U = sun.misc.Unsafe.getUnsafe(); 251275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> k = TreeBin.class; 251375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle LOCKSTATE = U.objectFieldOffset 251475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k.getDeclaredField("lockState")); 251575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } catch (Exception e) { 251675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new Error(e); 251775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 251875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 251975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 252075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 252175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ----------------Table Traversal -------------- */ 252275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 252375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 2524edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Records the table, its length, and current traversal index for a 2525edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * traverser that must process a region of a forwarded table before 2526edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * proceeding with current table. 2527edf43d27e240d82106f39ae91404963c23987234Narayan Kamath */ 2528edf43d27e240d82106f39ae91404963c23987234Narayan Kamath static final class TableStack<K,V> { 2529edf43d27e240d82106f39ae91404963c23987234Narayan Kamath int length; 2530edf43d27e240d82106f39ae91404963c23987234Narayan Kamath int index; 2531edf43d27e240d82106f39ae91404963c23987234Narayan Kamath Node<K,V>[] tab; 2532edf43d27e240d82106f39ae91404963c23987234Narayan Kamath TableStack<K,V> next; 2533edf43d27e240d82106f39ae91404963c23987234Narayan Kamath } 2534edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 2535edf43d27e240d82106f39ae91404963c23987234Narayan Kamath /** 253675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Encapsulates traversal for methods such as containsValue; also 2537edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * serves as a base class for other iterators and spliterators. 253875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 253975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Method advance visits once each still-valid node that was 254075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * reachable upon iterator construction. It might miss some that 254175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * were added to a bin after the bin was visited, which is OK wrt 254275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * consistency guarantees. Maintaining this property in the face 254375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of possible ongoing resizes requires a fair amount of 254475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bookkeeping state that is difficult to optimize away amidst 254575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * volatile accesses. Even so, traversal maintains reasonable 254675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * throughput. 254775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 254875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Normally, iteration proceeds bin-by-bin traversing lists. 254975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * However, if the table has been resized, then all future steps 255075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * must traverse both the bin at the current index as well as at 255175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (index + baseSize); and so on for further resizings. To 255275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * paranoically cope with potential sharing by users of iterators 255375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * across threads, iteration terminates if a bounds checks fails 255475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * for a table read. 255575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 255675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static class Traverser<K,V> { 255775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab; // current table; updated if resized 255875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> next; // the next entry to use 2559edf43d27e240d82106f39ae91404963c23987234Narayan Kamath TableStack<K,V> stack, spare; // to save/restore on ForwardingNodes 256075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int index; // index of bin to use next 256175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int baseIndex; // current index of initial table 256275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int baseLimit; // index bound for initial table 256375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final int baseSize; // initial table size 256475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 256575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser(Node<K,V>[] tab, int size, int index, int limit) { 256675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.tab = tab; 256775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.baseSize = size; 256875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.baseIndex = this.index = index; 256975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.baseLimit = limit; 257075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.next = null; 257175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 257275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 257375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 257475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Advances if possible, returning next valid node, or null if none. 257575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 257675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final Node<K,V> advance() { 257775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> e; 257875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((e = next) != null) 257975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e = e.next; 258075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (;;) { 2581edf43d27e240d82106f39ae91404963c23987234Narayan Kamath Node<K,V>[] t; int i, n; // must use locals in checks 258275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e != null) 258375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return next = e; 258475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (baseIndex >= baseLimit || (t = tab) == null || 258575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (n = t.length) <= (i = index) || i < 0) 258675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return next = null; 2587edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if ((e = tabAt(t, i)) != null && e.hash < 0) { 258875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e instanceof ForwardingNode) { 258975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tab = ((ForwardingNode<K,V>)e).nextTable; 259075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e = null; 2591edf43d27e240d82106f39ae91404963c23987234Narayan Kamath pushState(t, i, n); 259275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle continue; 259375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 259475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (e instanceof TreeBin) 259575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e = ((TreeBin<K,V>)e).first; 259675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 259775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e = null; 259875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 2599edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (stack != null) 2600edf43d27e240d82106f39ae91404963c23987234Narayan Kamath recoverState(n); 2601edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else if ((index = i + baseSize) >= n) 2602edf43d27e240d82106f39ae91404963c23987234Narayan Kamath index = ++baseIndex; // visit upper slots if present 2603edf43d27e240d82106f39ae91404963c23987234Narayan Kamath } 2604edf43d27e240d82106f39ae91404963c23987234Narayan Kamath } 2605edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 2606edf43d27e240d82106f39ae91404963c23987234Narayan Kamath /** 2607edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Saves traversal state upon encountering a forwarding node. 2608edf43d27e240d82106f39ae91404963c23987234Narayan Kamath */ 2609edf43d27e240d82106f39ae91404963c23987234Narayan Kamath private void pushState(Node<K,V>[] t, int i, int n) { 2610edf43d27e240d82106f39ae91404963c23987234Narayan Kamath TableStack<K,V> s = spare; // reuse if possible 2611edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (s != null) 2612edf43d27e240d82106f39ae91404963c23987234Narayan Kamath spare = s.next; 2613edf43d27e240d82106f39ae91404963c23987234Narayan Kamath else 2614edf43d27e240d82106f39ae91404963c23987234Narayan Kamath s = new TableStack<K,V>(); 2615edf43d27e240d82106f39ae91404963c23987234Narayan Kamath s.tab = t; 2616edf43d27e240d82106f39ae91404963c23987234Narayan Kamath s.length = n; 2617edf43d27e240d82106f39ae91404963c23987234Narayan Kamath s.index = i; 2618edf43d27e240d82106f39ae91404963c23987234Narayan Kamath s.next = stack; 2619edf43d27e240d82106f39ae91404963c23987234Narayan Kamath stack = s; 2620edf43d27e240d82106f39ae91404963c23987234Narayan Kamath } 2621edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 2622edf43d27e240d82106f39ae91404963c23987234Narayan Kamath /** 2623edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * Possibly pops traversal state. 2624edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * 2625edf43d27e240d82106f39ae91404963c23987234Narayan Kamath * @param n length of current table 2626edf43d27e240d82106f39ae91404963c23987234Narayan Kamath */ 2627edf43d27e240d82106f39ae91404963c23987234Narayan Kamath private void recoverState(int n) { 2628edf43d27e240d82106f39ae91404963c23987234Narayan Kamath TableStack<K,V> s; int len; 2629edf43d27e240d82106f39ae91404963c23987234Narayan Kamath while ((s = stack) != null && (index += (len = s.length)) >= n) { 2630edf43d27e240d82106f39ae91404963c23987234Narayan Kamath n = len; 2631edf43d27e240d82106f39ae91404963c23987234Narayan Kamath index = s.index; 2632edf43d27e240d82106f39ae91404963c23987234Narayan Kamath tab = s.tab; 2633edf43d27e240d82106f39ae91404963c23987234Narayan Kamath s.tab = null; 2634edf43d27e240d82106f39ae91404963c23987234Narayan Kamath TableStack<K,V> next = s.next; 2635edf43d27e240d82106f39ae91404963c23987234Narayan Kamath s.next = spare; // save for reuse 2636edf43d27e240d82106f39ae91404963c23987234Narayan Kamath stack = next; 2637edf43d27e240d82106f39ae91404963c23987234Narayan Kamath spare = s; 263875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 2639edf43d27e240d82106f39ae91404963c23987234Narayan Kamath if (s == null && (index += baseSize) >= n) 2640edf43d27e240d82106f39ae91404963c23987234Narayan Kamath index = ++baseIndex; 264175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 264275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 264375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 264475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 264575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Base of key, value, and entry Iterators. Adds fields to 264675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Traverser to support iterator.remove. 264775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 264875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static class BaseIterator<K,V> extends Traverser<K,V> { 264975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final ConcurrentHashMap<K,V> map; 265075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> lastReturned; 265175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle BaseIterator(Node<K,V>[] tab, int size, int index, int limit, 265275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> map) { 265375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(tab, size, index, limit); 265475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.map = map; 265575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance(); 265675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 265775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 265875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean hasNext() { return next != null; } 265975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean hasMoreElements() { return next != null; } 266075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 266175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final void remove() { 266275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 266375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = lastReturned) == null) 266475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new IllegalStateException(); 266575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lastReturned = null; 266675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle map.replaceNode(p.key, null, null); 266775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 266875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 266975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 267075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class KeyIterator<K,V> extends BaseIterator<K,V> 267175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Iterator<K>, Enumeration<K> { 267275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle KeyIterator(Node<K,V>[] tab, int index, int size, int limit, 267375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> map) { 267475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(tab, index, size, limit, map); 267575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 267675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 267775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final K next() { 267875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 267975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = next) == null) 268075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NoSuchElementException(); 268175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K k = p.key; 268275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lastReturned = p; 268375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance(); 268475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return k; 268575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 268675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 268775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final K nextElement() { return next(); } 268875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 268975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 269075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class ValueIterator<K,V> extends BaseIterator<K,V> 269175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Iterator<V>, Enumeration<V> { 269275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ValueIterator(Node<K,V>[] tab, int index, int size, int limit, 269375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> map) { 269475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(tab, index, size, limit, map); 269575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 269675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 269775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final V next() { 269875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 269975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = next) == null) 270075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NoSuchElementException(); 270175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v = p.val; 270275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lastReturned = p; 270375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance(); 270475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return v; 270575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 270675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 270775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final V nextElement() { return next(); } 270875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 270975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 271075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class EntryIterator<K,V> extends BaseIterator<K,V> 271175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Iterator<Map.Entry<K,V>> { 271275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle EntryIterator(Node<K,V>[] tab, int index, int size, int limit, 271375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> map) { 271475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(tab, index, size, limit, map); 271575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 271675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 271775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final Map.Entry<K,V> next() { 271875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 271975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = next) == null) 272075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NoSuchElementException(); 272175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K k = p.key; 272275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v = p.val; 272375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lastReturned = p; 272475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance(); 272575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new MapEntry<K,V>(k, v, map); 272675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 272775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 272875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 272975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 273075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Exported Entry for EntryIterator 273175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 273275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class MapEntry<K,V> implements Map.Entry<K,V> { 273375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final K key; // non-null 273475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V val; // non-null 273575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final ConcurrentHashMap<K,V> map; 273675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle MapEntry(K key, V val, ConcurrentHashMap<K,V> map) { 273775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.key = key; 273875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.val = val; 273975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.map = map; 274075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 274175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public K getKey() { return key; } 274275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public V getValue() { return val; } 274375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public int hashCode() { return key.hashCode() ^ val.hashCode(); } 274475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public String toString() { return key + "=" + val; } 274575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 274675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean equals(Object o) { 274775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object k, v; Map.Entry<?,?> e; 274875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Map.Entry) && 274975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 275075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v = e.getValue()) != null && 275175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k == key || k.equals(key)) && 275275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v == val || v.equals(val))); 275375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 275475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 275575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 275675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Sets our entry's value and writes through to the map. The 275775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * value to return is somewhat arbitrary here. Since we do not 275875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * necessarily track asynchronous changes, the most recent 275975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * "previous" value could be different from what we return (or 276075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * could even have been removed, in which case the put will 276175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * re-establish). We do not and cannot guarantee more. 276275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 276375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public V setValue(V value) { 276475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (value == null) throw new NullPointerException(); 276575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v = val; 276675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle val = value; 276775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle map.put(key, value); 276875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return v; 276975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 277075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 277175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 277275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ----------------Views -------------- */ 277375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 277475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 277575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Base class for views. 277675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 277775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle abstract static class CollectionView<K,V,E> 277875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Collection<E>, java.io.Serializable { 277975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long serialVersionUID = 7249069246763182397L; 278075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final ConcurrentHashMap<K,V> map; 278175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CollectionView(ConcurrentHashMap<K,V> map) { this.map = map; } 278275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 278375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 278475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the map backing this view. 278575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 278675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the map backing this view 278775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 278875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public ConcurrentHashMap<K,V> getMap() { return map; } 278975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 279075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 279175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Removes all of the elements from this view, by removing all 279275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the mappings from the map backing this view. 279375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 279475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final void clear() { map.clear(); } 279575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final int size() { return map.size(); } 279675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean isEmpty() { return map.isEmpty(); } 279775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 279875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // implementations below rely on concrete classes supplying these 279975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // abstract methods 280075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 280175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a "weakly consistent" iterator that will never 280275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * throw {@link ConcurrentModificationException}, and 280375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * guarantees to traverse elements as they existed upon 280475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * construction of the iterator, and may (but is not 280575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * guaranteed to) reflect any modifications subsequent to 280675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * construction. 280775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 280875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public abstract Iterator<E> iterator(); 280975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public abstract boolean contains(Object o); 281075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public abstract boolean remove(Object o); 281175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 281275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final String oomeMsg = "Required array size too large"; 281375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 281475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final Object[] toArray() { 281575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long sz = map.mappingCount(); 281675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sz > MAX_ARRAY_SIZE) 281775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new OutOfMemoryError(oomeMsg); 281875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n = (int)sz; 281975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object[] r = new Object[n]; 282075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int i = 0; 282175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (E e : this) { 282275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (i == n) { 282375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (n >= MAX_ARRAY_SIZE) 282475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new OutOfMemoryError(oomeMsg); 282575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) 282675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n = MAX_ARRAY_SIZE; 282775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 282875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n += (n >>> 1) + 1; 282975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = Arrays.copyOf(r, n); 283075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 283175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r[i++] = e; 283275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 283375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (i == n) ? r : Arrays.copyOf(r, i); 283475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 283575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 283675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings("unchecked") 283775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final <T> T[] toArray(T[] a) { 283875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long sz = map.mappingCount(); 283975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sz > MAX_ARRAY_SIZE) 284075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new OutOfMemoryError(oomeMsg); 284175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int m = (int)sz; 284275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle T[] r = (a.length >= m) ? a : 284375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (T[])java.lang.reflect.Array 284475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle .newInstance(a.getClass().getComponentType(), m); 284575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n = r.length; 284675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int i = 0; 284775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (E e : this) { 284875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (i == n) { 284975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (n >= MAX_ARRAY_SIZE) 285075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new OutOfMemoryError(oomeMsg); 285175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) 285275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n = MAX_ARRAY_SIZE; 285375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 285475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n += (n >>> 1) + 1; 285575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = Arrays.copyOf(r, n); 285675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 285775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r[i++] = (T)e; 285875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 285975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (a == r && i < n) { 286075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r[i] = null; // null-terminate 286175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return r; 286275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 286375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (i == n) ? r : Arrays.copyOf(r, i); 286475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 286575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 286675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 286775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a string representation of this collection. 286875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The string representation consists of the string representations 286975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of the collection's elements in the order they are returned by 287075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * its iterator, enclosed in square brackets ({@code "[]"}). 287175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Adjacent elements are separated by the characters {@code ", "} 287275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (comma and space). Elements are converted to strings as by 287375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@link String#valueOf(Object)}. 287475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 287575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return a string representation of this collection 287675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 287775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final String toString() { 287875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle StringBuilder sb = new StringBuilder(); 287975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append('['); 288075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Iterator<E> it = iterator(); 288175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (it.hasNext()) { 288275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (;;) { 288375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object e = it.next(); 288475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append(e == this ? "(this Collection)" : e); 288575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!it.hasNext()) 288675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 288775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append(',').append(' '); 288875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 288975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 289075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return sb.append(']').toString(); 289175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 289275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 289375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean containsAll(Collection<?> c) { 289475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (c != this) { 289575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Object e : c) { 289675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e == null || !contains(e)) 289775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 289875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 289975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 290075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 290175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 290275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 290375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean removeAll(Collection<?> c) { 290475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean modified = false; 290575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Iterator<E> it = iterator(); it.hasNext();) { 290675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (c.contains(it.next())) { 290775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle it.remove(); 290875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle modified = true; 290975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 291075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 291175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return modified; 291275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 291375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 291475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean retainAll(Collection<?> c) { 291575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean modified = false; 291675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Iterator<E> it = iterator(); it.hasNext();) { 291775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!c.contains(it.next())) { 291875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle it.remove(); 291975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle modified = true; 292075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 292175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 292275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return modified; 292375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 292475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 292575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 292675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 292775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 292875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * A view of a ConcurrentHashMap as a {@link Set} of keys, in 292975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * which additions may optionally be enabled by mapping to a 293075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * common value. This class cannot be directly instantiated. 293175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * See {@link #keySet() keySet()}, 293275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@link #keySet(Object) keySet(V)}, 293375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 293475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @since 1.8 293575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 293675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @hide 293775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 2938edf43d27e240d82106f39ae91404963c23987234Narayan Kamath // android-note: removed references to hidden APIs. 293975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public static class KeySetView<K,V> extends CollectionView<K,V,K> 294075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Set<K>, java.io.Serializable { 294175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long serialVersionUID = 7249069246763182397L; 294275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final V value; 294375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle KeySetView(ConcurrentHashMap<K,V> map, V value) { // non-public 294475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(map); 294575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.value = value; 294675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 294775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 294875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 294975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the default mapped value for additions, 295075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * or {@code null} if additions are not supported. 295175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 295275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the default mapped value for additions, or {@code null} 295375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * if not supported 295475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 295575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public V getMappedValue() { return value; } 295675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 295775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 295875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 295975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key is null 296075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 296175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean contains(Object o) { return map.containsKey(o); } 296275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 296375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 296475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Removes the key from this map view, by removing the key (and its 296575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * corresponding value) from the backing map. This method does 296675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * nothing if the key is not in the map. 296775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 296875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param o the key to be removed from the backing map 296975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if the backing map contained the specified key 297075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key is null 297175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 297275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean remove(Object o) { return map.remove(o) != null; } 297375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 297475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 297575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return an iterator over the keys of the backing map 297675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 297775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public Iterator<K> iterator() { 297875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 297975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> m = map; 298075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = m.table) == null ? 0 : t.length; 298175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new KeyIterator<K,V>(t, f, 0, f, m); 298275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 298375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 298475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 298575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Adds the specified key to this set view by mapping the key to 298675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the default mapped value in the backing map, if defined. 298775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 298875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param e key to be added 298975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if this set changed as a result of the call 299075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key is null 299175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws UnsupportedOperationException if no default mapped value 299275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * for additions was provided 299375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 299475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean add(K e) { 299575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v; 299675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((v = value) == null) 299775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new UnsupportedOperationException(); 299875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return map.putVal(e, v, true) == null; 299975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 300075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 300175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 300275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Adds all of the elements in the specified collection to this set, 300375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * as if by calling {@link #add} on each one. 300475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 300575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param c the elements to be inserted into this set 300675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if this set changed as a result of the call 300775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the collection or any of its 300875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * elements are {@code null} 300975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws UnsupportedOperationException if no default mapped value 301075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * for additions was provided 301175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 301275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean addAll(Collection<? extends K> c) { 301375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean added = false; 301475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v; 301575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((v = value) == null) 301675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new UnsupportedOperationException(); 301775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (K e : c) { 301875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (map.putVal(e, v, true) == null) 301975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle added = true; 302075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 302175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return added; 302275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 302375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 302475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public int hashCode() { 302575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = 0; 302675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (K e : this) 302775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h += e.hashCode(); 302875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return h; 302975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 303075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 303175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean equals(Object o) { 303275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Set<?> c; 303375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Set) && 303475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((c = (Set<?>)o) == this || 303575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (containsAll(c) && c.containsAll(this)))); 303675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 303775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 303875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 303975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 304075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 304175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * A view of a ConcurrentHashMap as a {@link Collection} of 304275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * values, in which additions are disabled. This class cannot be 304375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * directly instantiated. See {@link #values()}. 304475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 304575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class ValuesView<K,V> extends CollectionView<K,V,V> 304675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Collection<V>, java.io.Serializable { 304775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long serialVersionUID = 2249069246763182397L; 304875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ValuesView(ConcurrentHashMap<K,V> map) { super(map); } 304975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean contains(Object o) { 305075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return map.containsValue(o); 305175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 305275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 305375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean remove(Object o) { 305475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (o != null) { 305575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Iterator<V> it = iterator(); it.hasNext();) { 305675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (o.equals(it.next())) { 305775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle it.remove(); 305875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 305975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 306075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 306175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 306275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 306375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 306475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 306575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final Iterator<V> iterator() { 306675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> m = map; 306775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 306875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = m.table) == null ? 0 : t.length; 306975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new ValueIterator<K,V>(t, f, 0, f, m); 307075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 307175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 307275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean add(V e) { 307375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new UnsupportedOperationException(); 307475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 307575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean addAll(Collection<? extends V> c) { 307675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new UnsupportedOperationException(); 307775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 307875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 307975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 308075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 308175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 308275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * A view of a ConcurrentHashMap as a {@link Set} of (key, value) 308375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * entries. This class cannot be directly instantiated. See 308475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@link #entrySet()}. 308575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 308675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class EntrySetView<K,V> extends CollectionView<K,V,Map.Entry<K,V>> 308775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Set<Map.Entry<K,V>>, java.io.Serializable { 308875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long serialVersionUID = 2249069246763182397L; 308975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle EntrySetView(ConcurrentHashMap<K,V> map) { super(map); } 309075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 309175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean contains(Object o) { 309275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object k, v, r; Map.Entry<?,?> e; 309375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Map.Entry) && 309475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 309575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (r = map.get(k)) != null && 309675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v = e.getValue()) != null && 309775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v == r || v.equals(r))); 309875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 309975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 310075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean remove(Object o) { 310175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object k, v; Map.Entry<?,?> e; 310275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Map.Entry) && 310375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 310475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v = e.getValue()) != null && 310575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle map.remove(k, v)); 310675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 310775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 310875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 310975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return an iterator over the entries of the backing map 311075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 311175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public Iterator<Map.Entry<K,V>> iterator() { 311275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> m = map; 311375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 311475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = m.table) == null ? 0 : t.length; 311575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new EntryIterator<K,V>(t, f, 0, f, m); 311675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 311775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 311875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean add(Entry<K,V> e) { 311975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return map.putVal(e.getKey(), e.getValue(), false) == null; 312075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 312175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 312275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean addAll(Collection<? extends Entry<K,V>> c) { 312375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean added = false; 312475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Entry<K,V> e : c) { 312575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (add(e)) 312675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle added = true; 312775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 312875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return added; 312975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 313075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 313175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final int hashCode() { 313275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = 0; 313375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 313475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((t = map.table) != null) { 313575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 313675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p; (p = it.advance()) != null; ) { 313775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h += p.hashCode(); 313875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 313975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 314075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return h; 314175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 314275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 314375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean equals(Object o) { 314475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Set<?> c; 314575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Set) && 314675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((c = (Set<?>)o) == this || 314775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (containsAll(c) && c.containsAll(this)))); 314875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 314975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 315075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 315175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 315275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 315375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Counters -------------- */ 315475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 315575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // Adapted from LongAdder and Striped64. 315675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // See their internal docs for explanation. 315775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 315875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // A padded cell for distributing counts 315975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class CounterCell { 316075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile long p0, p1, p2, p3, p4, p5, p6; 316175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile long value; 316275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile long q0, q1, q2, q3, q4, q5, q6; 316375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell(long x) { value = x; } 316475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 316575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 316675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 316775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Holder for the thread-local hash code determining which 316875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * CounterCell to use. The code is initialized via the 316975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * counterHashCodeGenerator, but may be moved upon collisions. 317075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 317175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class CounterHashCode { 317275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int code; 317375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 317475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 317575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 317675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Generates initial value for per-thread CounterHashCodes. 317775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 317875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final AtomicInteger counterHashCodeGenerator = new AtomicInteger(); 317975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 318075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 318175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Increment for counterHashCodeGenerator. See class ThreadLocal 318275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * for explanation. 318375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 318475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int SEED_INCREMENT = 0x61c88647; 318575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 318675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 318775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Per-thread counter hash codes. Shared across all instances. 318875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 318975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final ThreadLocal<CounterHashCode> threadCounterHashCode = 319075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new ThreadLocal<CounterHashCode>(); 319175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 319275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final long sumCount() { 319375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] as = counterCells; CounterCell a; 319475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long sum = baseCount; 319575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (as != null) { 319675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int i = 0; i < as.length; ++i) { 319775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((a = as[i]) != null) 319875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sum += a.value; 319975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 320075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 320175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return sum; 320275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 320375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 320475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // See LongAdder version for explanation 320575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void fullAddCount(long x, CounterHashCode hc, 320675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean wasUncontended) { 320775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h; 320875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (hc == null) { 320975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hc = new CounterHashCode(); 321075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int s = counterHashCodeGenerator.addAndGet(SEED_INCREMENT); 321175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h = hc.code = (s == 0) ? 1 : s; // Avoid zero 321275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle threadCounterHashCode.set(hc); 321375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 321475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 321575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h = hc.code; 321675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean collide = false; // True if last slot nonempty 321775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (;;) { 321875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] as; CounterCell a; int n; long v; 321975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((as = counterCells) != null && (n = as.length) > 0) { 322075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((a = as[(n - 1) & h]) == null) { 322175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (cellsBusy == 0) { // Try to attach new Cell 322275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell r = new CounterCell(x); // Optimistic create 322375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (cellsBusy == 0 && 322475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) { 322575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean created = false; 322675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { // Recheck under lock 322775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] rs; int m, j; 322875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((rs = counterCells) != null && 322975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (m = rs.length) > 0 && 323075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle rs[j = (m - 1) & h] == null) { 323175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle rs[j] = r; 323275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle created = true; 323375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 323475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 323575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle cellsBusy = 0; 323675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 323775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (created) 323875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 323975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle continue; // Slot is now non-empty 324075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 324175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 324275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle collide = false; 324375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 324475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (!wasUncontended) // CAS already known to fail 324575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle wasUncontended = true; // Continue after rehash 324675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x)) 324775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 324875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (counterCells != as || n >= NCPU) 324975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle collide = false; // At max size or stale 325075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (!collide) 325175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle collide = true; 325275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (cellsBusy == 0 && 325375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) { 325475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 325575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (counterCells == as) {// Expand table unless stale 325675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] rs = new CounterCell[n << 1]; 325775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int i = 0; i < n; ++i) 325875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle rs[i] = as[i]; 325975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle counterCells = rs; 326075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 326175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 326275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle cellsBusy = 0; 326375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 326475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle collide = false; 326575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle continue; // Retry with expanded table 326675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 326775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h ^= h << 13; // Rehash 326875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h ^= h >>> 17; 326975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h ^= h << 5; 327075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 327175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (cellsBusy == 0 && counterCells == as && 327275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) { 327375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean init = false; 327475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { // Initialize table 327575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (counterCells == as) { 327675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] rs = new CounterCell[2]; 327775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle rs[h & 1] = new CounterCell(x); 327875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle counterCells = rs; 327975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle init = true; 328075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 328175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 328275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle cellsBusy = 0; 328375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 328475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (init) 328575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 328675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 328775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (U.compareAndSwapLong(this, BASECOUNT, v = baseCount, v + x)) 328875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; // Fall back on using base 3289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 329075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hc.code = h; // Record index for next time 3291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3292a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 3293a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson // Unsafe mechanics 329475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final sun.misc.Unsafe U; 329575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long SIZECTL; 329675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long TRANSFERINDEX; 329775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long BASECOUNT; 329875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long CELLSBUSY; 329975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long CELLVALUE; 330075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long ABASE; 330175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int ASHIFT; 3302a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 3303a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson static { 3304a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson try { 330575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U = sun.misc.Unsafe.getUnsafe(); 330675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> k = ConcurrentHashMap.class; 330775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle SIZECTL = U.objectFieldOffset 330875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k.getDeclaredField("sizeCtl")); 330975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TRANSFERINDEX = U.objectFieldOffset 331075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k.getDeclaredField("transferIndex")); 331175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle BASECOUNT = U.objectFieldOffset 331275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k.getDeclaredField("baseCount")); 331375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CELLSBUSY = U.objectFieldOffset 331475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k.getDeclaredField("cellsBusy")); 331575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> ck = CounterCell.class; 331675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CELLVALUE = U.objectFieldOffset 331775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (ck.getDeclaredField("value")); 331875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> ak = Node[].class; 331975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ABASE = U.arrayBaseOffset(ak); 332075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int scale = U.arrayIndexScale(ak); 332175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((scale & (scale - 1)) != 0) 332275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new Error("data type scale not a power of two"); 332375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ASHIFT = 31 - Integer.numberOfLeadingZeros(scale); 3324a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } catch (Exception e) { 3325a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson throw new Error(e); 3326a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 3327edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 3328edf43d27e240d82106f39ae91404963c23987234Narayan Kamath // Reduce the risk of rare disastrous classloading in first call to 3329edf43d27e240d82106f39ae91404963c23987234Narayan Kamath // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 3330edf43d27e240d82106f39ae91404963c23987234Narayan Kamath Class<?> ensureLoaded = LockSupport.class; 3331a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 3332a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 3333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 3334