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; 1375a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.Arrays; 1475a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.Collection; 1575a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.Comparator; 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.ForkJoinPool; 2675a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.concurrent.atomic.AtomicInteger; 2775a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.concurrent.locks.LockSupport; 2875a06e56a4cc4599946e21422513e4bafa759509Calin Juravleimport java.util.concurrent.locks.ReentrantLock; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-note 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// removed link to collections framework docs 3275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle// removed links to hidden api 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-note 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A hash table supporting full concurrency of retrievals and 3775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * high expected concurrency for updates. This class obeys the 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * same functional specification as {@link java.util.Hashtable}, and 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * includes versions of methods corresponding to each method of 4075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code Hashtable}. However, even though all operations are 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thread-safe, retrieval operations do <em>not</em> entail locking, 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and there is <em>not</em> any support for locking the entire table 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in a way that prevents all access. This class is fully 4475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * interoperable with {@code Hashtable} in programs that rely on its 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thread safety but not on its synchronization details. 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>Retrieval operations (including {@code get}) generally do not 4875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * block, so may overlap with update operations (including {@code put} 4975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * and {@code remove}). Retrievals reflect the results of the most 5075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * recently <em>completed</em> update operations holding upon their 5175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * onset. (More formally, an update operation for a given key bears a 5275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <em>happens-before</em> relation with any (non-null) retrieval for 5375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * that key reporting the updated value.) For aggregate operations 5475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * such as {@code putAll} and {@code clear}, concurrent retrievals may 5575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * reflect insertion or removal of only some entries. Similarly, 5675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Iterators and Enumerations return elements reflecting the state of 5775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the hash table at some point at or since the creation of the 5875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * iterator/enumeration. They do <em>not</em> throw {@link 5975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * ConcurrentModificationException}. However, iterators are designed 6075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to be used by only one thread at a time. Bear in mind that the 6175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * results of aggregate status methods including {@code size}, {@code 6275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * isEmpty}, and {@code containsValue} are typically useful only when 6375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * a map is not undergoing concurrent updates in other threads. 6475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Otherwise the results of these methods reflect transient states 6575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * that may be adequate for monitoring or estimation purposes, but not 6675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * for program control. 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 6875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>The table is dynamically expanded when there are too many 6975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * collisions (i.e., keys that have distinct hash codes but fall into 7075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the same slot modulo the table size), with the expected average 7175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * effect of maintaining roughly two bins per mapping (corresponding 7275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to a 0.75 load factor threshold for resizing). There may be much 7375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * variance around this average as mappings are added and removed, but 7475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * overall, this maintains a commonly accepted time/space tradeoff for 7575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * hash tables. However, resizing this or any other kind of hash 7675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * table may be a relatively slow operation. When possible, it is a 7775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * good idea to provide a size estimate as an optional {@code 7875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * initialCapacity} constructor argument. An additional optional 7975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code loadFactor} constructor argument provides a further means of 8075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * customizing initial table capacity by specifying the table density 8175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to be used in calculating the amount of space to allocate for the 8275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * given number of elements. Also, for compatibility with previous 8375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * versions of this class, constructors may optionally specify an 8475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * expected {@code concurrencyLevel} as an additional hint for 8575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * internal sizing. Note that using many keys with exactly the same 8675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code hashCode()} is a sure way to slow down performance of any 8775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * hash table. To ameliorate impact, when keys are {@link Comparable}, 8875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * this class may use comparison order among keys to help break ties. 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 90bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>This class and its views and iterators implement all of the 91bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <em>optional</em> methods of the {@link Map} and {@link Iterator} 92bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * interfaces. 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>Like {@link Hashtable} but unlike {@link HashMap}, this class 9575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * does <em>not</em> allow {@code null} to be used as a key or value. 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <K> the type of keys maintained by this map 100bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param <V> the type of mapped values 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 10275a06e56a4cc4599946e21422513e4bafa759509Calin Juravlepublic class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> 10375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements ConcurrentMap<K,V>, Serializable { 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 7249069246763182397L; 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 10775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Overview: 10875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 10975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The primary design goal of this hash table is to maintain 11075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * concurrent readability (typically method get(), but also 11175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * iterators and related methods) while minimizing update 11275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * contention. Secondary goals are to keep space consumption about 11375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the same or better than java.util.HashMap, and to support high 11475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * initial insertion rates on an empty table by many threads. 11575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 11675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * This map usually acts as a binned (bucketed) hash table. Each 11775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * key-value mapping is held in a Node. Most nodes are instances 11875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of the basic Node class with hash, key, value, and next 11975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * fields. However, various subclasses exist: TreeNodes are 12075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * arranged in balanced trees, not lists. TreeBins hold the roots 12175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of sets of TreeNodes. ForwardingNodes are placed at the heads 12275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of bins during resizing. ReservationNodes are used as 12375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * placeholders while establishing values in computeIfAbsent and 12475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * related methods. The types TreeBin, ForwardingNode, and 12575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * ReservationNode do not hold normal user keys, values, or 12675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * hashes, and are readily distinguishable during search etc 12775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * because they have negative hash fields and null key and value 12875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * fields. (These special nodes are either uncommon or transient, 12975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * so the impact of carrying around some unused fields is 13075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * insignificant.) 13175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 13275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The table is lazily initialized to a power-of-two size upon the 13375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * first insertion. Each bin in the table normally contains a 13475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * list of Nodes (most often, the list has only zero or one Node). 13575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Table accesses require volatile/atomic reads, writes, and 13675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * CASes. Because there is no other way to arrange this without 13775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * adding further indirections, we use intrinsics 13875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (sun.misc.Unsafe) operations. 13975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 14075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * We use the top (sign) bit of Node hash fields for control 14175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * purposes -- it is available anyway because of addressing 14275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * constraints. Nodes with negative hash fields are specially 14375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * handled or ignored in map methods. 14475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 14575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Insertion (via put or its variants) of the first node in an 14675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * empty bin is performed by just CASing it to the bin. This is 14775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * by far the most common case for put operations under most 14875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * key/hash distributions. Other update operations (insert, 14975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * delete, and replace) require locks. We do not want to waste 15075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the space required to associate a distinct lock object with 15175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * each bin, so instead use the first node of a bin list itself as 15275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * a lock. Locking support for these locks relies on builtin 15375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * "synchronized" monitors. 15475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 15575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Using the first node of a list as a lock does not by itself 15675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * suffice though: When a node is locked, any update must first 15775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * validate that it is still the first node after locking it, and 15875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * retry if not. Because new nodes are always appended to lists, 15975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * once a node is first in a bin, it remains first until deleted 16075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * or the bin becomes invalidated (upon resizing). 16175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 16275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The main disadvantage of per-bin locks is that other update 16375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * operations on other nodes in a bin list protected by the same 16475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * lock can stall, for example when user equals() or mapping 16575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * functions take a long time. However, statistically, under 16675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * random hash codes, this is not a common problem. Ideally, the 16775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * frequency of nodes in bins follows a Poisson distribution 16875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (http://en.wikipedia.org/wiki/Poisson_distribution) with a 16975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * parameter of about 0.5 on average, given the resizing threshold 17075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of 0.75, although with a large variance because of resizing 17175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * granularity. Ignoring variance, the expected occurrences of 17275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The 17375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * first values are: 17475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 17575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 0: 0.60653066 17675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 1: 0.30326533 17775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 2: 0.07581633 17875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 3: 0.01263606 17975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 4: 0.00157952 18075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 5: 0.00015795 18175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 6: 0.00001316 18275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 7: 0.00000094 18375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 8: 0.00000006 18475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * more: less than 1 in ten million 18575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 18675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Lock contention probability for two threads accessing distinct 18775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * elements is roughly 1 / (8 * #elements) under random hashes. 18875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 18975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Actual hash code distributions encountered in practice 19075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * sometimes deviate significantly from uniform randomness. This 19175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * includes the case when N > (1<<30), so some keys MUST collide. 19275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Similarly for dumb or hostile usages in which multiple keys are 19375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * designed to have identical hash codes or ones that differs only 19475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * in masked-out high bits. So we use a secondary strategy that 19575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * applies when the number of nodes in a bin exceeds a 19675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * threshold. These TreeBins use a balanced tree to hold nodes (a 19775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * specialized form of red-black trees), bounding search time to 19875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * O(log N). Each search step in a TreeBin is at least twice as 19975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * slow as in a regular list, but given that N cannot exceed 20075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (1<<64) (before running out of addresses) this bounds search 20175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * steps, lock hold times, etc, to reasonable constants (roughly 20275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 100 nodes inspected per operation worst case) so long as keys 20375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * are Comparable (which is very common -- String, Long, etc). 20475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * TreeBin nodes (TreeNodes) also maintain the same "next" 20575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * traversal pointers as regular nodes, so can be traversed in 20675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * iterators in the same way. 20775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 20875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The table is resized when occupancy exceeds a percentage 20975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * threshold (nominally, 0.75, but see below). Any thread 21075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * noticing an overfull bin may assist in resizing after the 21175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * initiating thread allocates and sets up the replacement 21275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * array. However, rather than stalling, these other threads may 21375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * proceed with insertions etc. The use of TreeBins shields us 21475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * from the worst case effects of overfilling while resizes are in 21575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * progress. Resizing proceeds by transferring bins, one by one, 21675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * from the table to the next table. To enable concurrency, the 21775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * next table must be (incrementally) prefilled with place-holders 21875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * serving as reverse forwarders to the old table. Because we are 21975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * using power-of-two expansion, the elements from each bin must 22075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * either stay at same index, or move with a power of two 22175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * offset. We eliminate unnecessary node creation by catching 22275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * cases where old nodes can be reused because their next fields 22375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * won't change. On average, only about one-sixth of them need 22475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * cloning when a table doubles. The nodes they replace will be 22575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * garbage collectable as soon as they are no longer referenced by 22675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * any reader thread that may be in the midst of concurrently 22775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * traversing table. Upon transfer, the old table bin contains 22875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * only a special forwarding node (with hash field "MOVED") that 22975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * contains the next table as its key. On encountering a 23075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * forwarding node, access and update operations restart, using 23175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the new table. 23275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 23375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Each bin transfer requires its bin lock, which can stall 23475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * waiting for locks while resizing. However, because other 23575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * threads can join in and help resize rather than contend for 23675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * locks, average aggregate waits become shorter as resizing 23775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * progresses. The transfer operation must also ensure that all 23875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * accessible bins in both the old and new table are usable by any 23975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * traversal. This is arranged by proceeding from the last bin 24075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (table.length - 1) up towards the first. Upon seeing a 24175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * forwarding node, traversals (see class Traverser) arrange to 24275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * move to the new table without revisiting nodes. However, to 24375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * ensure that no intervening nodes are skipped, bin splitting can 24475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * only begin after the associated reverse-forwarders are in 24575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * place. 24675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 24775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The traversal scheme also applies to partial traversals of 24875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * ranges of bins (via an alternate Traverser constructor) 24975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to support partitioned aggregate operations. Also, read-only 25075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * operations give up if ever forwarded to a null table, which 25175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * provides support for shutdown-style clearing, which is also not 25275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * currently implemented. 25375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 25475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Lazy table initialization minimizes footprint until first use, 25575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * and also avoids resizings when the first operation is from a 25675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * putAll, constructor with map argument, or deserialization. 25775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * These cases attempt to override the initial capacity settings, 25875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * but harmlessly fail to take effect in cases of races. 25975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 26075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The element count is maintained using a specialization of 26175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * LongAdder. We need to incorporate a specialization rather than 26275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * just use a LongAdder in order to access implicit 26375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * contention-sensing that leads to creation of multiple 26475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * CounterCells. The counter mechanics avoid contention on 26575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * updates but can encounter cache thrashing if read too 26675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * frequently during concurrent access. To avoid reading so often, 26775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * resizing under contention is attempted only upon adding to a 26875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bin already holding two or more nodes. Under uniform hash 26975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * distributions, the probability of this occurring at threshold 27075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * is around 13%, meaning that only about 1 in 8 puts check 27175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * threshold (and after resizing, many fewer do so). 27275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 27375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * TreeBins use a special form of comparison for search and 27475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * related operations (which is the main reason we cannot use 27575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * existing collections such as TreeMaps). TreeBins contain 27675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Comparable elements, but may contain others, as well as 27775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * elements that are Comparable but not necessarily Comparable 27875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * for the same T, so we cannot invoke compareTo among them. To 27975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * handle this, the tree is ordered primarily by hash value, then 28075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * by Comparable.compareTo order if applicable. On lookup at a 28175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * node, if elements are not comparable or compare as 0 then both 28275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * left and right children may need to be searched in the case of 28375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * tied hash values. (This corresponds to the full list search 28475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * that would be necessary if all elements were non-Comparable and 28575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * had tied hashes.) The red-black balancing code is updated from 28675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * pre-jdk-collections 28775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) 28875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * based in turn on Cormen, Leiserson, and Rivest "Introduction to 28975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Algorithms" (CLR). 29075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 29175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * TreeBins also require an additional locking mechanism. While 29275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * list traversal is always possible by readers even during 29375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * updates, tree traversal is not, mainly because of tree-rotations 29475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * that may change the root node and/or its linkages. TreeBins 29575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * include a simple read-write lock mechanism parasitic on the 29675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * main bin-synchronization strategy: Structural adjustments 29775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * associated with an insertion or removal are already bin-locked 29875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (and so cannot conflict with other writers) but must wait for 29975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * ongoing readers to finish. Since there can be only one such 30075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * waiter, we use a simple scheme using a single "waiter" field to 30175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * block writers. However, readers need never block. If the root 30275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * lock is held, they proceed along the slow traversal path (via 30375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * next-pointers) until the lock becomes available or the list is 30475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * exhausted, whichever comes first. These cases are not fast, but 30575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * maximize aggregate expected throughput. 30675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 30775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Maintaining API and serialization compatibility with previous 30875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * versions of this class introduces several oddities. Mainly: We 30975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * leave untouched but unused constructor arguments refering to 31075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * concurrencyLevel. We accept a loadFactor constructor argument, 31175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * but apply it only to initial table capacity (which is the only 31275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * time that we can guarantee to honor it.) We also declare an 31375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * unused "Segment" class that is instantiated in minimal form 31475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * only when serializing. 31575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 31675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * This file is organized to make things a little easier to follow 31775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * while reading than they might otherwise: First the main static 31875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * declarations and utilities, then fields, then main public 31975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * methods (with a few factorings of multiple public methods into 32075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * internal ones), then sizing methods, trees, traversers, and 32175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bulk operations. 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* ---------------- Constants -------------- */ 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 32775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The largest possible table capacity. This value must be 32875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * exactly 1<<30 to stay within Java array allocation and indexing 32975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bounds for power of two table sizes, and is further required 33075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * because the top two bits of 32bit hash fields are used for 33175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * control purposes. 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 33375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int MAXIMUM_CAPACITY = 1 << 30; 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 33675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The default initial table capacity. Must be a power of 2 33775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (i.e., at least 1) and at most MAXIMUM_CAPACITY. 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 33975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int DEFAULT_CAPACITY = 16; 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 34275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The largest possible (non-power of two) array size. 34375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Needed by toArray and related methods. 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 34575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 34875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The default concurrency level for this table. Unused but 34975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * defined for compatibility with previous versions of this class. 350bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 35175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int DEFAULT_CONCURRENCY_LEVEL = 16; 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 35475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The load factor for this table. Overrides of this value in 35575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * constructors affect only the initial table capacity. The 35675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * actual floating point value isn't normally used -- it is 35775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * simpler to use expressions such as {@code n - (n >>> 2)} for 35875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the associated resizing threshold. 359a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 36075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final float LOAD_FACTOR = 0.75f; 361a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 362a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 36375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The bin count threshold for using a tree rather than list for a 36475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bin. Bins are converted to trees when adding an element to a 36575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bin with at least this many nodes. The value must be greater 36675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * than 2, and should be at least 8 to mesh with assumptions in 36775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * tree removal about conversion back to plain bins upon 36875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * shrinkage. 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 37075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int TREEIFY_THRESHOLD = 8; 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 372bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 37375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The bin count threshold for untreeifying a (split) bin during a 37475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * resize operation. Should be less than TREEIFY_THRESHOLD, and at 37575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * most 6 to mesh with shrinkage detection under removal. 376bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 37775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int UNTREEIFY_THRESHOLD = 6; 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 38075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The smallest table capacity for which bins may be treeified. 38175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (Otherwise the table is resized if too many nodes in a bin.) 38275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The value should be at least 4 * TREEIFY_THRESHOLD to avoid 38375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * conflicts between resizing and treeification thresholds. 384bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 38575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int MIN_TREEIFY_CAPACITY = 64; 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 38875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Minimum number of rebinnings per transfer step. Ranges are 38975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * subdivided to allow multiple resizer threads. This value 39075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * serves as a lower bound to avoid resizers encountering 39175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * excessive memory contention. The value should be at least 39275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * DEFAULT_CAPACITY. 393bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 39475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int MIN_TRANSFER_STRIDE = 16; 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 39675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* 39775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Encodings for Node hash fields. See above for explanation. 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 39975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int MOVED = 0x8fffffff; // (-1) hash for forwarding nodes 40075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int TREEBIN = 0x80000000; // hash for roots of trees 40175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int RESERVED = 0x80000001; // hash for transient reservations 40275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 40475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** Number of CPUS, to place bounds on some sizings */ 40575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int NCPU = Runtime.getRuntime().availableProcessors(); 40675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 40775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** For serialization compatibility. */ 40875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final ObjectStreamField[] serialPersistentFields = { 40975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new ObjectStreamField("segments", Segment[].class), 41075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new ObjectStreamField("segmentMask", Integer.TYPE), 41175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new ObjectStreamField("segmentShift", Integer.TYPE) 41275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle }; 41375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 41475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Nodes -------------- */ 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 416a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 41775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Key-value entry. This class is never exported out as a 41875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * user-mutable Map.Entry (i.e., one supporting setValue; see 41975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * MapEntry below), but can be used for read-only traversals used 42075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * in bulk tasks. Subclasses of Node with a negative hash field 42175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * are special, and contain null keys and values (but are never 42275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * exported). Otherwise, keys and vals are never null. 423a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 42475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static class Node<K,V> implements Map.Entry<K,V> { 425a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson final int hash; 426a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson final K key; 42775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile V val; 42875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> next; 429a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 43075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node(int hash, K key, V val, Node<K,V> next) { 431a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson this.hash = hash; 432a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson this.key = key; 43375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.val = val; 434a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson this.next = next; 435a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 436a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 43775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final K getKey() { return key; } 43875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final V getValue() { return val; } 43975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final int hashCode() { return key.hashCode() ^ val.hashCode(); } 44075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final String toString(){ return key + "=" + val; } 44175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final V setValue(V value) { 44275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new UnsupportedOperationException(); 443a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 444a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 44575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean equals(Object o) { 44675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object k, v, u; Map.Entry<?,?> e; 44775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Map.Entry) && 44875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 44975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v = e.getValue()) != null && 45075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k == key || k.equals(key)) && 45175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v == (u = val) || v.equals(u))); 45275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 45375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 45475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 45575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Virtualized support for map.get(); overridden in subclasses. 45675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 45775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> find(int h, Object k) { 45875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> e = this; 45975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (k != null) { 46075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle do { 46175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K ek; 46275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e.hash == h && 46375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == k || (ek != null && k.equals(ek)))) 46475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e; 46575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } while ((e = e.next) != null); 466a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 46775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 468a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 469a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 470a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 47175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Static utilities -------------- */ 47275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 473a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 47475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Spreads (XORs) higher bits of hash to lower and also forces top 47575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bit to 0. Because the table uses power-of-two masking, sets of 47675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * hashes that vary only in bits above the current mask will 47775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * always collide. (Among known examples are sets of Float keys 47875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * holding consecutive whole numbers in small tables.) So we 47975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * apply a transform that spreads the impact of higher bits 48075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * downward. There is a tradeoff between speed, utility, and 48175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * quality of bit-spreading. Because many common sets of hashes 48275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * are already reasonably distributed (so don't benefit from 48375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * spreading), and because we use trees to handle large sets of 48475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * collisions in bins, we just XOR some shifted bits in the 48575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * cheapest possible way to reduce systematic lossage, as well as 48675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to incorporate impact of the highest bits that would otherwise 48775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * never be used in index calculations because of table bounds. 488a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 48975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int spread(int h) { 49075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (h ^ (h >>> 16)) & HASH_BITS; 491a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 492a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 493a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 49475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a power of two table size for the given desired capacity. 49575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * See Hackers Delight, sec 3.2 496a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 49775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int tableSizeFor(int c) { 49875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n = c - 1; 49975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n |= n >>> 1; 50075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n |= n >>> 2; 50175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n |= n >>> 4; 50275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n |= n >>> 8; 50375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n |= n >>> 16; 50475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; 505a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 50775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 50975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns x's Class if it is of the form "class C implements 51075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Comparable<C>", else null. 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 51275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static Class<?> comparableClassFor(Object x) { 51375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (x instanceof Comparable) { 51475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> c; Type[] ts, as; Type t; ParameterizedType p; 51575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((c = x.getClass()) == String.class) // bypass checks 51675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return c; 51775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((ts = c.getGenericInterfaces()) != null) { 51875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int i = 0; i < ts.length; ++i) { 51975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (((t = ts[i]) instanceof ParameterizedType) && 52075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((p = (ParameterizedType)t).getRawType() == 52175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Comparable.class) && 52275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (as = p.getActualTypeArguments()) != null && 52375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle as.length == 1 && as[0] == c) // type arg is c 52475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return c; 52575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 52675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 52775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 52875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 53275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns k.compareTo(x) if x matches kc (k's screened comparable 53375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * class), else 0. 534bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 53575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings({"rawtypes","unchecked"}) // for cast to Comparable 53675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static int compareComparables(Class<?> kc, Object k, Object x) { 53775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (x == null || x.getClass() != kc ? 0 : 53875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((Comparable)k).compareTo(x)); 53975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Table element access -------------- */ 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* 54475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Volatile access methods are used for table elements as well as 54575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * elements of in-progress next table while resizing. All uses of 54675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the tab arguments must be null checked by callers. All callers 54775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * also paranoically precheck that tab's length is not zero (or an 54875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * equivalent check), thus ensuring that any index argument taking 54975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the form of a hash value anded with (length - 1) is a valid 55075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * index. Note that, to be correct wrt arbitrary concurrency 55175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * errors by users, these checks must operate on local variables, 55275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * which accounts for some odd-looking inline assignments below. 55375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Note that calls to setTabAt always occur within locked regions, 55475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * and so do not need full volatile semantics, but still require 55575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * ordering to maintain concurrent readability. 55675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 557a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 55875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings("unchecked") 55975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) { 56075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE); 56175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 56375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i, 56475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> c, Node<K,V> v) { 56575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v); 56675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 567a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 56875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) { 56975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.putOrderedObject(tab, ((long)i << ASHIFT) + ABASE, v); 57075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 57275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Fields -------------- */ 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 57475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 57575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The array of bins. Lazily initialized upon first insertion. 57675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Size is always a power of two. Accessed directly by iterators. 57775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 57875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transient volatile Node<K,V>[] table; 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 58075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 58175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The next table to use; non-null only while resizing. 58275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 58375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile Node<K,V>[] nextTable; 584bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 58575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 58675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Base counter value, used mainly when there is no contention, 58775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * but also as a fallback during table initialization 58875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * races. Updated via CAS. 58975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 59075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile long baseCount; 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 59275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 59375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Table initialization and resizing control. When negative, the 59475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * table is being initialized or resized: -1 for initialization, 59575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * else -(1 + the number of active resizing threads). Otherwise, 59675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * when table is null, holds the initial table size to use upon 59775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * creation, or 0 for default. After initialization, holds the 59875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * next element count value upon which to resize the table. 59975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 60075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile int sizeCtl; 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 60275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 60375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The next table index (plus one) to split while resizing. 60475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 60575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile int transferIndex; 606a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 60775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 60875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The least available table index to split while resizing. 60975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 61075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile int transferOrigin; 611a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 61275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 61375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Spinlock (locked via CAS) used when resizing and/or creating CounterCells. 61475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 61575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile int cellsBusy; 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 61775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 61875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Table of counter cells. When non-null, size is a power of 2. 61975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 62075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient volatile CounterCell[] counterCells; 621a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 62275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // views 62375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient KeySetView<K,V> keySet; 62475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient ValuesView<K,V> values; 62575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private transient EntrySetView<K,V> entrySet; 626a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 627a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 62875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Public operations -------------- */ 629a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 630a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 63175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new, empty map with the default initial table size (16). 632a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 63375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public ConcurrentHashMap() { 634a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 636a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 63775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new, empty map with an initial table size 63875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * accommodating the specified number of elements without the need 63975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * to dynamically resize. 640a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 64175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param initialCapacity The implementation performs internal 64275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * sizing to accommodate this many elements. 64375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws IllegalArgumentException if the initial capacity of 64475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * elements is negative 645a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 64675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public ConcurrentHashMap(int initialCapacity) { 64775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (initialCapacity < 0) 64875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new IllegalArgumentException(); 64975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ? 65075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle MAXIMUM_CAPACITY : 65175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1)); 65275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.sizeCtl = cap; 653a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 654a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 655a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 65675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new map with the same mappings as the given map. 65775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 65875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param m the map 659a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 66075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public ConcurrentHashMap(Map<? extends K, ? extends V> m) { 66175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.sizeCtl = DEFAULT_CAPACITY; 66275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle putAll(m); 663a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 66675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new, empty map with an initial table size based on 66775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the given number of elements ({@code initialCapacity}) and 66875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * initial table density ({@code loadFactor}). 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param initialCapacity the initial capacity. The implementation 67175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * performs internal sizing to accommodate this many elements, 67275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * given the specified load factor. 67375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param loadFactor the load factor (table density) for 67475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * establishing the initial table size 6756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalArgumentException if the initial capacity of 6766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * elements is negative or the load factor is nonpositive 6776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 6786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @since 1.6 6796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 6806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public ConcurrentHashMap(int initialCapacity, float loadFactor) { 68175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this(initialCapacity, loadFactor, 1); 6826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 68575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new, empty map with an initial table size based on 68675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the given number of elements ({@code initialCapacity}), table 68775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * density ({@code loadFactor}), and number of concurrently 68875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * updating threads ({@code concurrencyLevel}). 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 690bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param initialCapacity the initial capacity. The implementation 69175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * performs internal sizing to accommodate this many elements, 69275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * given the specified load factor. 69375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param loadFactor the load factor (table density) for 69475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * establishing the initial table size 69575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param concurrencyLevel the estimated number of concurrently 69675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * updating threads. The implementation may use this value as 69775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * a sizing hint. 69875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws IllegalArgumentException if the initial capacity is 69975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * negative or the load factor or concurrencyLevel are 70075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * nonpositive 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 70275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public ConcurrentHashMap(int initialCapacity, 70375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle float loadFactor, int concurrencyLevel) { 70475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) 70575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new IllegalArgumentException(); 70675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (initialCapacity < concurrencyLevel) // Use at least as many bins 70775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle initialCapacity = concurrencyLevel; // as estimated threads 70875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long size = (long)(1.0 + (long)initialCapacity / loadFactor); 70975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int cap = (size >= (long)MAXIMUM_CAPACITY) ? 71075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle MAXIMUM_CAPACITY : tableSizeFor((int)size); 71175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.sizeCtl = cap; 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 71475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // Original (since JDK1.2) Map methods 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 71775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 71975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public int size() { 72075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long n = sumCount(); 72175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((n < 0L) ? 0 : 72275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : 72375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (int)n); 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 726bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 72775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 728bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isEmpty() { 73075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return sumCount() <= 0L; // ignore transient negative values 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 734bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns the value to which the specified key is mapped, 735bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * or {@code null} if this map contains no mapping for the key. 736bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 737bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>More formally, if this map contains a mapping from a key 738bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@code k} to a value {@code v} such that {@code key.equals(k)}, 739bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * then this method returns {@code v}; otherwise it returns 740bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@code null}. (There can be at most one such mapping.) 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 742bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified key is null 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V get(Object key) { 74575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek; 74675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = spread(key.hashCode()); 74775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((tab = table) != null && (n = tab.length) > 0 && 74875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (e = tabAt(tab, (n - 1) & h)) != null) { 74975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((eh = e.hash) == h) { 75075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((ek = e.key) == key || (ek != null && key.equals(ek))) 75175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e.val; 75275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 75375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (eh < 0) 75475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (p = e.find(h, key)) != null ? p.val : null; 75575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while ((e = e.next) != null) { 75675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e.hash == h && 75775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == key || (ek != null && key.equals(ek)))) 75875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e.val; 759a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 760a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 761a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson return null; 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Tests if the specified object is a key in this table. 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 76775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param key possible key 76875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if and only if the specified object 769bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * is a key in this table, as determined by the 77075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code equals} method; {@code false} otherwise 771bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified key is null 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean containsKey(Object key) { 77475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return get(key) != null; 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 77875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns {@code true} if this map maps one or more keys to the 77975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * specified value. Note: This method may require a full traversal 78075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of the map, and is much slower than method {@code containsKey}. 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 782bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param value value whose presence in this map is to be tested 78375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if this map maps one or more keys to the 784bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * specified value 785bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified value is null 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean containsValue(Object value) { 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value == null) 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 79075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 79175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((t = table) != null) { 79275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 79375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p; (p = it.advance()) != null; ) { 79475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v; 79575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((v = p.val) == value || (v != null && value.equals(v))) 79675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 797bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 798bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 79975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 803bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Maps the specified key to the specified value in this table. 804bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Neither the key nor the value can be null. 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 80675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>The value can be retrieved by calling the {@code get} method 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with a key that is equal to the original key. 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 809bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param key key with which the specified value is to be associated 810bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param value value to be associated with the specified key 81175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the previous value associated with {@code key}, or 81275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code null} if there was no mapping for {@code key} 813bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified key or value is null 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V put(K key, V value) { 81675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return putVal(key, value, false); 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 81975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** Implementation for put and putIfAbsent */ 82075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final V putVal(K key, V value, boolean onlyIfAbsent) { 82175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (key == null || value == null) throw new NullPointerException(); 82275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int hash = spread(key.hashCode()); 82375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int binCount = 0; 82475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V>[] tab = table;;) { 82575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> f; int n, i, fh; 82675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tab == null || (n = tab.length) == 0) 82775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tab = initTable(); 82875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { 82975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (casTabAt(tab, i, null, 83075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new Node<K,V>(hash, key, value, null))) 83175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; // no lock when adding to empty bin 83275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 83375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((fh = f.hash) == MOVED) 83475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tab = helpTransfer(tab, f); 83575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 83675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V oldVal = null; 83775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle synchronized (f) { 83875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tabAt(tab, i) == f) { 83975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (fh >= 0) { 84075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle binCount = 1; 84175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> e = f;; ++binCount) { 84275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K ek; 84375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e.hash == hash && 84475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == key || 84575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (ek != null && key.equals(ek)))) { 84675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle oldVal = e.val; 84775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!onlyIfAbsent) 84875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e.val = value; 84975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 85075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 85175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> pred = e; 85275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((e = e.next) == null) { 85375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pred.next = new Node<K,V>(hash, key, 85475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle value, null); 85575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 85675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 85775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 85875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 85975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (f instanceof TreeBin) { 86075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 86175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle binCount = 2; 86275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key, 86375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle value)) != null) { 86475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle oldVal = p.val; 86575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!onlyIfAbsent) 86675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.val = value; 86775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 86875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 86975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 87075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 87175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (binCount != 0) { 87275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (binCount >= TREEIFY_THRESHOLD) 87375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle treeifyBin(tab, i); 87475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (oldVal != null) 87575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return oldVal; 87675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 87775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 87875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 87975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 88075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle addCount(1L, binCount); 88175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copies all of the mappings from the specified map to this one. 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * These mappings replace any mappings that this map had for any of the 887bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * keys currently in the specified map. 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 889bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param m mappings to be stored in this map 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 891bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public void putAll(Map<? extends K, ? extends V> m) { 89275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tryPresize(m.size()); 893bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) 89475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle putVal(e.getKey(), e.getValue(), false); 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 898bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Removes the key (and its corresponding value) from this map. 899bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * This method does nothing if the key is not in the map. 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 901bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param key the key that needs to be removed 90275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the previous value associated with {@code key}, or 90375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code null} if there was no mapping for {@code key} 904bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified key is null 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V remove(Object key) { 90775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return replaceNode(key, null, null); 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 91175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Implementation for the four public remove/replace methods: 91275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Replaces node value with v, conditional upon match of cv if 91375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * non-null. If resulting value is null, delete. 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 91575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final V replaceNode(Object key, V value, Object cv) { 91675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int hash = spread(key.hashCode()); 91775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V>[] tab = table;;) { 91875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> f; int n, i, fh; 91975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tab == null || (n = tab.length) == 0 || 92075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (f = tabAt(tab, i = (n - 1) & hash)) == null) 92175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 92275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((fh = f.hash) == MOVED) 92375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tab = helpTransfer(tab, f); 92475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 92575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V oldVal = null; 92675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean validated = false; 92775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle synchronized (f) { 92875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tabAt(tab, i) == f) { 92975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (fh >= 0) { 93075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle validated = true; 93175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> e = f, pred = null;;) { 93275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K ek; 93375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e.hash == hash && 93475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == key || 93575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (ek != null && key.equals(ek)))) { 93675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V ev = e.val; 93775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (cv == null || cv == ev || 93875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (ev != null && cv.equals(ev))) { 93975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle oldVal = ev; 94075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (value != null) 94175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e.val = value; 94275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pred != null) 94375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pred.next = e.next; 94475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 94575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, i, e.next); 94675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 94775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 94875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 94975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pred = e; 95075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((e = e.next) == null) 95175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 95275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 95375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 95475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (f instanceof TreeBin) { 95575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle validated = true; 95675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeBin<K,V> t = (TreeBin<K,V>)f; 95775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> r, p; 95875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((r = t.root) != null && 95975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (p = r.findTreeNode(hash, key, null)) != null) { 96075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V pv = p.val; 96175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (cv == null || cv == pv || 96275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (pv != null && cv.equals(pv))) { 96375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle oldVal = pv; 96475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (value != null) 96575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.val = value; 96675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (t.removeTreeNode(p)) 96775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, i, untreeify(t.first)); 96875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 96975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 97075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 97175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 97275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 97375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (validated) { 97475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (oldVal != null) { 97575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (value == null) 97675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle addCount(-1L, -1); 97775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return oldVal; 97875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 97975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 98075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 98175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 98275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 98375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 987bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Removes all of the mappings from this map. 988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() { 99075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long delta = 0L; // negative number of deletions 99175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int i = 0; 99275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab = table; 99375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (tab != null && i < tab.length) { 99475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int fh; 99575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> f = tabAt(tab, i); 99675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (f == null) 99775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++i; 99875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((fh = f.hash) == MOVED) { 99975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tab = helpTransfer(tab, f); 100075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle i = 0; // restart 100175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 100275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 100375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle synchronized (f) { 100475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tabAt(tab, i) == f) { 100575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p = (fh >= 0 ? f : 100675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (f instanceof TreeBin) ? 100775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((TreeBin<K,V>)f).first : null); 100875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (p != null) { 100975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle --delta; 101075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = p.next; 101175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 101275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, i++, null); 101375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 101475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 101575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1016a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 101775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (delta != 0L) 101875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle addCount(delta, -1); 1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1022bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns a {@link Set} view of the keys contained in this map. 1023bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The set is backed by the map, so changes to the map are 102475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * reflected in the set, and vice-versa. The set supports element 1025bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * removal, which removes the corresponding mapping from this map, 102675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * via the {@code Iterator.remove}, {@code Set.remove}, 102775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code removeAll}, {@code retainAll}, and {@code clear} 102875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * operations. It does not support the {@code add} or 102975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code addAll} operations. 1030bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 103175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>The view's {@code iterator} is a "weakly consistent" iterator 1032bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * that will never throw {@link ConcurrentModificationException}, 1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and guarantees to traverse elements as they existed upon 1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * construction of the iterator, and may (but is not guaranteed to) 1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reflect any modifications subsequent to construction. 103675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 103775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the set view 103875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set<K> keySet() { 104175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle KeySetView<K,V> ks; 104275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null)); 1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1046bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns a {@link Collection} view of the values contained in this map. 1047bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The collection is backed by the map, so changes to the map are 1048bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * reflected in the collection, and vice-versa. The collection 1049bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * supports element removal, which removes the corresponding 105075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * mapping from this map, via the {@code Iterator.remove}, 105175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code Collection.remove}, {@code removeAll}, 105275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code retainAll}, and {@code clear} operations. It does not 105375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * support the {@code add} or {@code addAll} operations. 1054bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 105575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>The view's {@code iterator} is a "weakly consistent" iterator 1056bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * that will never throw {@link ConcurrentModificationException}, 1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and guarantees to traverse elements as they existed upon 1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * construction of the iterator, and may (but is not guaranteed to) 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reflect any modifications subsequent to construction. 106075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 106175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the collection view 1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Collection<V> values() { 106475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ValuesView<K,V> vs; 106575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (vs = values) != null ? vs : (values = new ValuesView<K,V>(this)); 1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1069bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns a {@link Set} view of the mappings contained in this map. 1070bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The set is backed by the map, so changes to the map are 1071bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * reflected in the set, and vice-versa. The set supports element 1072bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * removal, which removes the corresponding mapping from the map, 107375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * via the {@code Iterator.remove}, {@code Set.remove}, 107475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code removeAll}, {@code retainAll}, and {@code clear} 107575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * operations. 1076bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 107775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * <p>The view's {@code iterator} is a "weakly consistent" iterator 1078bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * that will never throw {@link ConcurrentModificationException}, 1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and guarantees to traverse elements as they existed upon 1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * construction of the iterator, and may (but is not guaranteed to) 1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reflect any modifications subsequent to construction. 108275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 108375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the set view 1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set<Map.Entry<K,V>> entrySet() { 108675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle EntrySetView<K,V> es; 108775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (es = entrySet) != null ? es : (entrySet = new EntrySetView<K,V>(this)); 1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 109175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the hash code value for this {@link Map}, i.e., 109275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the sum of, for each key-value pair in the map, 109375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code key.hashCode() ^ value.hashCode()}. 1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 109575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the hash code value for this map 1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 109775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public int hashCode() { 109875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = 0; 109975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 110075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((t = table) != null) { 110175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 110275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p; (p = it.advance()) != null; ) 110375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h += p.key.hashCode() ^ p.val.hashCode(); 110475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 110575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return h; 1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 110975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a string representation of this map. The string 111075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * representation consists of a list of key-value mappings (in no 111175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * particular order) enclosed in braces ("{@code {}}"). Adjacent 111275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * mappings are separated by the characters {@code ", "} (comma 111375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * and space). Each key-value mapping is rendered as the key 111475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * followed by an equals sign ("{@code =}") followed by the 111575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * associated value. 1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 111775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return a string representation of this map 1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 111975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public String toString() { 112075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 112175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = table) == null ? 0 : t.length; 112275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, f, 0, f); 112375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle StringBuilder sb = new StringBuilder(); 112475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append('{'); 112575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 112675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = it.advance()) != null) { 1127a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson for (;;) { 112875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K k = p.key; 112975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v = p.val; 113075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append(k == this ? "(this Map)" : k); 113175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append('='); 113275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append(v == this ? "(this Map)" : v); 113375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = it.advance()) == null) 1134a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson break; 113575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append(',').append(' '); 1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 113875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return sb.append('}').toString(); 1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 114275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Compares the specified object with this map for equality. 114375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns {@code true} if the given object is a map with the same 114475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * mappings as this map. This operation may return misleading 114575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * results if either map is concurrently modified during execution 114675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of this method. 114775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 114875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param o object to be compared for equality with this map 114975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if the specified object is equal to this map 1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 115175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean equals(Object o) { 115275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (o != this) { 115375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!(o instanceof Map)) 1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 115575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Map<?,?> m = (Map<?,?>) o; 115675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 115775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = table) == null ? 0 : t.length; 115875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, f, 0, f); 115975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p; (p = it.advance()) != null; ) { 116075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V val = p.val; 116175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object v = m.get(p.key); 116275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (v == null || (v != val && !v.equals(val))) 116375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 116475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 116575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Map.Entry<?,?> e : m.entrySet()) { 116675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object mk, mv, v; 116775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((mk = e.getKey()) == null || 116875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (mv = e.getValue()) == null || 116975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v = get(mk)) == null || 117075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (mv != v && !mv.equals(v))) 117175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 117275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 117475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 117775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 117875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Stripped-down version of helper class used in previous version, 117975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * declared for the sake of serialization compatibility 118075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 118175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static class Segment<K,V> extends ReentrantLock implements Serializable { 118275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long serialVersionUID = 2249069246763182397L; 118375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final float loadFactor; 118475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Segment(float lf) { this.loadFactor = lf; } 118575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 118875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Saves the state of the {@code ConcurrentHashMap} instance to a 1189a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * stream (i.e., serializes it). 1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param s the stream 1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @serialData 1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the key (Object) and value (Object) 1193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for each key-value mapping, followed by a null pair. 1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The key-value mappings are emitted in no particular order. 1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1196a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson private void writeObject(java.io.ObjectOutputStream s) 119775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throws java.io.IOException { 119875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // For serialization compatibility 119975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // Emulate segment calculation from previous version of this class 120075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int sshift = 0; 120175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int ssize = 1; 120275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (ssize < DEFAULT_CONCURRENCY_LEVEL) { 120375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++sshift; 120475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ssize <<= 1; 120575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 120675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int segmentShift = 32 - sshift; 120775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int segmentMask = ssize - 1; 120875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings("unchecked") Segment<K,V>[] segments = (Segment<K,V>[]) 120975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL]; 121075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int i = 0; i < segments.length; ++i) 121175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle segments[i] = new Segment<K,V>(LOAD_FACTOR); 121275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s.putFields().put("segments", segments); 121375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s.putFields().put("segmentShift", segmentShift); 121475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s.putFields().put("segmentMask", segmentMask); 121575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s.writeFields(); 121675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 121775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 121875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((t = table) != null) { 121975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 122075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p; (p = it.advance()) != null; ) { 122175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s.writeObject(p.key); 122275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s.writeObject(p.val); 1223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.writeObject(null); 1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.writeObject(null); 122775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle segments = null; // throw away 1228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 123175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Reconstitutes the instance from a stream (that is, deserializes it). 1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param s the stream 1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void readObject(java.io.ObjectInputStream s) 123575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throws java.io.IOException, ClassNotFoundException { 123675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* 123775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * To improve performance in typical cases, we create nodes 123875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * while reading, then place in table once size is known. 123975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * However, we must also validate uniqueness and deal with 124075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * overpopulated bins while doing so, which requires 124175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * specialized versions of putVal mechanics. 124275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 124375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = -1; // force exclusion for table construction 1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.defaultReadObject(); 124575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long size = 0L; 124675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p = null; 124775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (;;) { 124875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings("unchecked") K k = (K) s.readObject(); 124975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings("unchecked") V v = (V) s.readObject(); 125075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (k != null && v != null) { 125175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = new Node<K,V>(spread(k.hashCode()), k, v, p); 125275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++size; 125375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 125475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 125575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 125675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 125775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (size == 0L) 125875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = 0; 125975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 126075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n; 126175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (size >= (long)(MAXIMUM_CAPACITY >>> 1)) 126275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n = MAXIMUM_CAPACITY; 126375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 126475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int sz = (int)size; 126575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n = tableSizeFor(sz + (sz >>> 1) + 1); 126675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 126775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings({"rawtypes","unchecked"}) 126875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab = (Node<K,V>[])new Node[n]; 126975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int mask = n - 1; 127075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long added = 0L; 127175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (p != null) { 127275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean insertAtFront; 127375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> next = p.next, first; 127475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = p.hash, j = h & mask; 127575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((first = tabAt(tab, j)) == null) 127675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle insertAtFront = true; 127775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 127875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K k = p.key; 127975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (first.hash < 0) { 128075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeBin<K,V> t = (TreeBin<K,V>)first; 128175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (t.putTreeVal(h, k, p.val) == null) 128275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++added; 128375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle insertAtFront = false; 128475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 128575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 128675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int binCount = 0; 128775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle insertAtFront = true; 128875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> q; K qk; 128975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (q = first; q != null; q = q.next) { 129075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (q.hash == h && 129175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((qk = q.key) == k || 129275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (qk != null && k.equals(qk)))) { 129375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle insertAtFront = false; 129475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 129575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 129675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++binCount; 129775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 129875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (insertAtFront && binCount >= TREEIFY_THRESHOLD) { 129975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle insertAtFront = false; 130075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++added; 130175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.next = first; 130275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> hd = null, tl = null; 130375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (q = p; q != null; q = q.next) { 130475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> t = new TreeNode<K,V> 130575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (q.hash, q.key, q.val, null, null); 130675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((t.prev = tl) == null) 130775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hd = t; 130875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 130975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl.next = t; 131075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl = t; 131175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 131275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, j, new TreeBin<K,V>(hd)); 131375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 131475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 131575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 131675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (insertAtFront) { 131775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++added; 131875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.next = first; 131975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, j, p); 132075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 132175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = next; 1322a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 132375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle table = tab; 132475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = n - (n >>> 2); 132575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle baseCount = added; 1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 132775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 132975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // ConcurrentMap methods 133075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 133175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 133275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 133375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 133475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the previous value associated with the specified key, 133575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * or {@code null} if there was no mapping for the key 133675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key or value is null 133775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 133875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public V putIfAbsent(K key, V value) { 133975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return putVal(key, value, true); 134075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 134175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 134275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 134375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 134475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 134575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key is null 134675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 134775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean remove(Object key, Object value) { 134875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (key == null) 134975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NullPointerException(); 135075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return value != null && replaceNode(key, null, value) != null; 135175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 135275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 135375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 135475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 135575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 135675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if any of the arguments are null 135775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 135875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean replace(K key, V oldValue, V newValue) { 135975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (key == null || oldValue == null || newValue == null) 136075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NullPointerException(); 136175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return replaceNode(key, newValue, oldValue) != null; 136275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 136375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 136475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 136575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 136675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 136775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the previous value associated with the specified key, 136875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * or {@code null} if there was no mapping for the key 136975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key or value is null 137075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 137175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public V replace(K key, V value) { 137275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (key == null || value == null) 137375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NullPointerException(); 137475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return replaceNode(key, value, null); 137575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 137675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // Hashtable legacy methods 137775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 137875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 137975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Legacy method testing if some key maps into the specified value 138075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * in this table. This method is identical in functionality to 138175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@link #containsValue(Object)}, and exists solely to ensure 138275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * full compatibility with class {@link java.util.Hashtable}. 138375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 138475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param value a value to search for 138575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if and only if some key maps to the 138675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code value} argument in this table as 138775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * determined by the {@code equals} method; 138875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@code false} otherwise 138975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified value is null 139075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 139175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean contains(Object value) { 139275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // BEGIN android-note 139375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // removed deprecation 139475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // END android-note 139575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return containsValue(value); 139675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 139775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 139875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 139975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns an enumeration of the keys in this table. 140075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 140175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return an enumeration of the keys in this table 140275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @see #keySet() 140375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 140475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public Enumeration<K> keys() { 140575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 140675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = table) == null ? 0 : t.length; 140775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new KeyIterator<K,V>(t, f, 0, f, this); 140875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 140975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 141075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 141175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns an enumeration of the values in this table. 141275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 141375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return an enumeration of the values in this table 141475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @see #values() 141575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 141675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public Enumeration<V> elements() { 141775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 141875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = table) == null ? 0 : t.length; 141975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new ValueIterator<K,V>(t, f, 0, f, this); 142075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 142175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 142275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // ConcurrentHashMap-only methods 142375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 142475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 142575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the number of mappings. This method should be used 142675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * instead of {@link #size} because a ConcurrentHashMap may 142775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * contain more mappings than can be represented as an int. The 142875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * value returned is an estimate; the actual count may differ if 142975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * there are concurrent insertions or removals. 143075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 143175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the number of mappings 143275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @since 1.8 143375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 143475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @hide 143575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 143675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public long mappingCount() { 143775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long n = sumCount(); 143875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (n < 0L) ? 0L : n; // ignore transient negative values 143975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 144075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 144175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 144275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new {@link Set} backed by a ConcurrentHashMap 144375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * from the given type to {@code Boolean.TRUE}. 144475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 144575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the new set 144675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @since 1.8 144775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 144875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @hide 144975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 145075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public static <K> KeySetView<K,Boolean> newKeySet() { 145175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new KeySetView<K,Boolean> 145275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (new ConcurrentHashMap<K,Boolean>(), Boolean.TRUE); 145375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 145475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 145575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 145675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates a new {@link Set} backed by a ConcurrentHashMap 145775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * from the given type to {@code Boolean.TRUE}. 145875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 145975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param initialCapacity The implementation performs internal 146075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * sizing to accommodate this many elements. 146175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws IllegalArgumentException if the initial capacity of 146275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * elements is negative 146375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the new set 146475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @since 1.8 146575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 146675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @hide 146775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 146875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) { 146975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new KeySetView<K,Boolean> 147075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (new ConcurrentHashMap<K,Boolean>(initialCapacity), Boolean.TRUE); 147175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 147275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 147375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 147475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a {@link Set} view of the keys in this map, using the 147575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * given common mapped value for any additions (i.e., {@link 147675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Collection#add} and {@link Collection#addAll(Collection)}). 147775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * This is of course only appropriate if it is acceptable to use 147875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the same value for all additions from this view. 147975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 148075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param mappedValue the mapped value to use for any additions 148175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the set view 148275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the mappedValue is null 148375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 148475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @hide 148575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 148675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public Set<K> keySet(V mappedValue) { 148775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (mappedValue == null) 148875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NullPointerException(); 148975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new KeySetView<K,V>(this, mappedValue); 149075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 149175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 149275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Special Nodes -------------- */ 149375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 149475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 149575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * A node inserted at head of bins during transfer operations. 149675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 149775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class ForwardingNode<K,V> extends Node<K,V> { 149875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final Node<K,V>[] nextTable; 149975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ForwardingNode(Node<K,V>[] tab) { 150075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(MOVED, null, null, null); 150175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.nextTable = tab; 150275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 150375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 150475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> find(int h, Object k) { 150575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> e; int n; 150675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab = nextTable; 150775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (k != null && tab != null && (n = tab.length) > 0 && 150875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (e = tabAt(tab, (n - 1) & h)) != null) { 150975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle do { 151075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int eh; K ek; 151175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((eh = e.hash) == h && 151275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == k || (ek != null && k.equals(ek)))) 151375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e; 151475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (eh < 0) 151575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e.find(h, k); 151675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } while ((e = e.next) != null); 151775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 151875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 151975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 152075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 152175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 152275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 152375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * A place-holder node used in computeIfAbsent and compute 152475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 152575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class ReservationNode<K,V> extends Node<K,V> { 152675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ReservationNode() { 152775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(RESERVED, null, null, null); 152875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 152975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 153075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> find(int h, Object k) { 153175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 153275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 153375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 153475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 153575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Table Initialization and Resizing -------------- */ 153675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 153775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 153875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Initializes table, using the size recorded in sizeCtl. 153975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 154075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final Node<K,V>[] initTable() { 154175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab; int sc; 154275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while ((tab = table) == null || tab.length == 0) { 154375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((sc = sizeCtl) < 0) 154475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Thread.yield(); // lost initialization race; just spin 154575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) { 154675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 154775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((tab = table) == null || tab.length == 0) { 154875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n = (sc > 0) ? sc : DEFAULT_CAPACITY; 154975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings({"rawtypes","unchecked"}) 155075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] nt = (Node<K,V>[])new Node[n]; 155175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle table = tab = nt; 155275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sc = n - (n >>> 2); 155375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 155475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 155575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = sc; 155675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 155775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 155875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 155975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 156075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return tab; 156175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 156275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 156375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 156475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Adds to count, and if table is too small and not already 156575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * resizing, initiates transfer. If already resizing, helps 156675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * perform transfer if work is available. Rechecks occupancy 156775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * after a transfer to see if another resize is already needed 156875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * because resizings are lagging additions. 156975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 157075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param x the count to add 157175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param check if <0, don't check resize, if <= 1 only check if uncontended 157275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 157375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void addCount(long x, int check) { 157475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] as; long b, s; 157575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((as = counterCells) != null || 157675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) { 157775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterHashCode hc; CounterCell a; long v; int m; 157875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean uncontended = true; 157975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((hc = threadCounterHashCode.get()) == null || 158075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle as == null || (m = as.length - 1) < 0 || 158175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (a = as[m & hc.code]) == null || 158275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle !(uncontended = 158375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) { 158475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle fullAddCount(x, hc, uncontended); 158575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return; 158675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 158775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (check <= 1) 158875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return; 158975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s = sumCount(); 159075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 159175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (check >= 0) { 159275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab, nt; int sc; 159375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (s >= (long)(sc = sizeCtl) && (tab = table) != null && 159475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tab.length < MAXIMUM_CAPACITY) { 159575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sc < 0) { 159675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sc == -1 || transferIndex <= transferOrigin || 159775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (nt = nextTable) == null) 159875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 159975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (U.compareAndSwapInt(this, SIZECTL, sc, sc - 1)) 160075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transfer(tab, nt); 160175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 160275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (U.compareAndSwapInt(this, SIZECTL, sc, -2)) 160375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transfer(tab, null); 160475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s = sumCount(); 160575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 160675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 160775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 160875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 160975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 161075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Helps transfer if a resize is in progress. 161175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 161275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) { 161375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] nextTab; int sc; 161475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((f instanceof ForwardingNode) && 161575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) { 161675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (nextTab == nextTable && tab == table && 161775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transferIndex > transferOrigin && (sc = sizeCtl) < -1 && 161875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.compareAndSwapInt(this, SIZECTL, sc, sc - 1)) 161975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transfer(tab, nextTab); 162075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return nextTab; 162175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 162275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return table; 162375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 162475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 162575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 162675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Tries to presize table to accommodate the given number of elements. 162775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 162875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param size number of elements (doesn't need to be perfectly accurate) 162975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 163075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void tryPresize(int size) { 163175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY : 163275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tableSizeFor(size + (size >>> 1) + 1); 163375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int sc; 163475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while ((sc = sizeCtl) >= 0) { 163575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab = table; int n; 163675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tab == null || (n = tab.length) == 0) { 163775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n = (sc > c) ? sc : c; 163875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) { 163975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 164075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (table == tab) { 164175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings({"rawtypes","unchecked"}) 164275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] nt = (Node<K,V>[])new Node[n]; 164375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle table = nt; 164475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sc = n - (n >>> 2); 164575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 164675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 164775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = sc; 164875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 164975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 165075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 165175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (c <= sc || n >= MAXIMUM_CAPACITY) 165275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 165375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (tab == table && 165475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.compareAndSwapInt(this, SIZECTL, sc, -2)) 165575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transfer(tab, null); 165675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 165775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 165875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 165975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 166075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Moves and/or copies the nodes in each bin to new table. See 166175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * above for explanation. 166275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 166375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) { 166475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n = tab.length, stride; 166575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE) 166675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle stride = MIN_TRANSFER_STRIDE; // subdivide range 166775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (nextTab == null) { // initiating 166875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 166975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings({"rawtypes","unchecked"}) 167075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] nt = (Node<K,V>[])new Node[n << 1]; 167175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle nextTab = nt; 167275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } catch (Throwable ex) { // try to cope with OOME 167375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = Integer.MAX_VALUE; 167475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return; 167575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 167675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle nextTable = nextTab; 167775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transferOrigin = n; 167875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transferIndex = n; 167975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ForwardingNode<K,V> rev = new ForwardingNode<K,V>(tab); 168075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int k = n; k > 0;) { // progressively reveal ready slots 168175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int nextk = (k > stride) ? k - stride : 0; 168275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int m = nextk; m < k; ++m) 168375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle nextTab[m] = rev; 168475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int m = n + nextk; m < n + k; ++m) 168575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle nextTab[m] = rev; 168675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.putOrderedInt(this, TRANSFERORIGIN, k = nextk); 168775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 168875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 168975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int nextn = nextTab.length; 169075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab); 169175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean advance = true; 169275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int i = 0, bound = 0;;) { 169375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int nextIndex, nextBound, fh; Node<K,V> f; 169475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while (advance) { 169575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (--i >= bound) 169675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance = false; 169775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((nextIndex = transferIndex) <= transferOrigin) { 169875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle i = -1; 169975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance = false; 170075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 170175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (U.compareAndSwapInt 170275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (this, TRANSFERINDEX, nextIndex, 170375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle nextBound = (nextIndex > stride ? 170475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle nextIndex - stride : 0))) { 170575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle bound = nextBound; 170675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle i = nextIndex - 1; 170775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance = false; 170875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 170975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 171075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (i < 0 || i >= n || i + n >= nextn) { 171175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int sc;;) { 171275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, ++sc)) { 171375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sc == -1) { 171475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle nextTable = null; 171575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle table = nextTab; 171675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sizeCtl = (n << 1) - (n >>> 1); 171775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 171875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return; 171975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 172075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 172175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 172275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((f = tabAt(tab, i)) == null) { 172375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (casTabAt(tab, i, null, fwd)) { 172475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(nextTab, i, null); 172575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(nextTab, i + n, null); 172675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance = true; 172775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 172875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 172975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((fh = f.hash) == MOVED) 173075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance = true; // already processed 173175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 173275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle synchronized (f) { 173375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tabAt(tab, i) == f) { 173475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> ln, hn; 173575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (fh >= 0) { 173675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int runBit = fh & n; 173775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> lastRun = f; 173875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p = f.next; p != null; p = p.next) { 173975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int b = p.hash & n; 174075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (b != runBit) { 174175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle runBit = b; 174275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lastRun = p; 174375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 174475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 174575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (runBit == 0) { 174675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ln = lastRun; 174775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hn = null; 174875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 174975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 175075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hn = lastRun; 175175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ln = null; 175275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 175375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p = f; p != lastRun; p = p.next) { 175475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int ph = p.hash; K pk = p.key; V pv = p.val; 175575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((ph & n) == 0) 175675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ln = new Node<K,V>(ph, pk, pv, ln); 175775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 175875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hn = new Node<K,V>(ph, pk, pv, hn); 175975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 176075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 176175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (f instanceof TreeBin) { 176275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeBin<K,V> t = (TreeBin<K,V>)f; 176375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> lo = null, loTail = null; 176475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> hi = null, hiTail = null; 176575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int lc = 0, hc = 0; 176675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> e = t.first; e != null; e = e.next) { 176775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = e.hash; 176875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> p = new TreeNode<K,V> 176975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (h, e.key, e.val, null, null); 177075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((h & n) == 0) { 177175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p.prev = loTail) == null) 177275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lo = p; 177375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 177475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle loTail.next = p; 177575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle loTail = p; 177675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++lc; 177775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 177875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 177975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p.prev = hiTail) == null) 178075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hi = p; 178175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 178275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hiTail.next = p; 178375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hiTail = p; 178475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ++hc; 178575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 178675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 178775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ln = (lc <= UNTREEIFY_THRESHOLD) ? untreeify(lo) : 178875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (hc != 0) ? new TreeBin<K,V>(lo) : t; 178975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hn = (hc <= UNTREEIFY_THRESHOLD) ? untreeify(hi) : 179075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (lc != 0) ? new TreeBin<K,V>(hi) : t; 179175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 179275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 179375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ln = hn = null; 179475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(nextTab, i, ln); 179575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(nextTab, i + n, hn); 179675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, i, fwd); 179775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance = true; 179875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 179975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 180075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 180175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 180275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 180375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 180475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Conversion from/to TreeBins -------------- */ 180575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 180675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 180775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Replaces all linked nodes in bin at given index unless table is 180875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * too small, in which case resizes instead. 180975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 181075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void treeifyBin(Node<K,V>[] tab, int index) { 181175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> b; int n, sc; 181275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tab != null) { 181375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((n = tab.length) < MIN_TREEIFY_CAPACITY) { 181475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tab == table && (sc = sizeCtl) >= 0 && 181575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.compareAndSwapInt(this, SIZECTL, sc, -2)) 181675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle transfer(tab, null); 181775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 181875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((b = tabAt(tab, index)) != null) { 181975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle synchronized (b) { 182075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tabAt(tab, index) == b) { 182175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> hd = null, tl = null; 182275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> e = b; e != null; e = e.next) { 182375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> p = 182475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new TreeNode<K,V>(e.hash, e.key, e.val, 182575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle null, null); 182675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p.prev = tl) == null) 182775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hd = p; 182875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 182975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl.next = p; 183075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl = p; 183175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 183275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle setTabAt(tab, index, new TreeBin<K,V>(hd)); 183375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 183475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 183575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 183675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 183775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 183875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 183975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 184075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a list on non-TreeNodes replacing those in given list. 184175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 184275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> Node<K,V> untreeify(Node<K,V> b) { 184375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> hd = null, tl = null; 184475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> q = b; q != null; q = q.next) { 184575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p = new Node<K,V>(q.hash, q.key, q.val, null); 184675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tl == null) 184775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hd = p; 184875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 184975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl.next = p; 185075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tl = p; 185175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 185275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return hd; 185375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 185475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 185575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- TreeNodes -------------- */ 185675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 185775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 185875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Nodes for use in TreeBins 185975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 186075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class TreeNode<K,V> extends Node<K,V> { 186175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> parent; // red-black tree links 186275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> left; 186375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> right; 186475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> prev; // needed to unlink next upon deletion 186575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean red; 186675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 186775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode(int hash, K key, V val, Node<K,V> next, 186875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> parent) { 186975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(hash, key, val, next); 187075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.parent = parent; 187175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 187275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 187375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> find(int h, Object k) { 187475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return findTreeNode(h, k, null); 187575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 187675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 187775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 187875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the TreeNode (or null if not found) for the given key 187975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * starting at given root. 188075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 188175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final TreeNode<K,V> findTreeNode(int h, Object k, Class<?> kc) { 188275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (k != null) { 188375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> p = this; 188475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle do { 188575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int ph, dir; K pk; TreeNode<K,V> q; 188675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pl = p.left, pr = p.right; 188775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((ph = p.hash) > h) 188875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = pl; 188975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (ph < h) 189075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = pr; 189175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((pk = p.key) == k || (pk != null && k.equals(pk))) 189275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return p; 189375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pl == null && pr == null) 189475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 189575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((kc != null || 189675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (kc = comparableClassFor(k)) != null) && 189775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (dir = compareComparables(kc, k, pk)) != 0) 189875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = (dir < 0) ? pl : pr; 189975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pl == null) 190075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = pr; 190175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pr == null || 190275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (q = pr.findTreeNode(h, k, kc)) == null) 190375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = pl; 190475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 190575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return q; 190675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } while (p != null); 190775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 190875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 190975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 191075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 191175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 191275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- TreeBins -------------- */ 191375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 191475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 191575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * TreeNodes used at the heads of bins. TreeBins do not hold user 191675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * keys or values, but instead point to list of TreeNodes and 191775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * their root. They also maintain a parasitic read-write lock 191875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * forcing writers (who hold bin lock) to wait for readers (who do 191975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * not) to complete before tree restructuring operations. 192075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 192175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class TreeBin<K,V> extends Node<K,V> { 192275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> root; 192375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile TreeNode<K,V> first; 192475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile Thread waiter; 192575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile int lockState; 192675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // values for lockState 192775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int WRITER = 1; // set while holding write lock 192875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int WAITER = 2; // set when waiting for write lock 192975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int READER = 4; // increment value for setting read lock 193075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 193175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 193275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Creates bin with initial set of nodes headed by b. 193375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 193475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeBin(TreeNode<K,V> b) { 193575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(TREEBIN, null, null, null); 193675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.first = b; 193775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> r = null; 193875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (TreeNode<K,V> x = b, next; x != null; x = next) { 193975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle next = (TreeNode<K,V>)x.next; 194075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.left = x.right = null; 194175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (r == null) { 194275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.parent = null; 194375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = false; 194475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = x; 194575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 194675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 194775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object key = x.key; 194875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int hash = x.hash; 194975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> kc = null; 195075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (TreeNode<K,V> p = r;;) { 195175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int dir, ph; 195275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((ph = p.hash) > hash) 195375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = -1; 195475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (ph < hash) 195575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = 1; 195675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((kc != null || 195775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (kc = comparableClassFor(key)) != null)) 195875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = compareComparables(kc, key, p.key); 195975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 196075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = 0; 196175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> xp = p; 196275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = (dir <= 0) ? p.left : p.right) == null) { 196375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.parent = xp; 196475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (dir <= 0) 196575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.left = x; 196675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 196775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.right = x; 196875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = balanceInsertion(r, x); 196975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 197075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 197175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 197275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 197375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 197475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.root = r; 197575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 197675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 197775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 197875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Acquires write lock for tree restructuring. 197975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 198075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void lockRoot() { 198175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!U.compareAndSwapInt(this, LOCKSTATE, 0, WRITER)) 198275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle contendedLock(); // offload to separate method 198375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 198475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 198575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 198675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Releases write lock for tree restructuring. 198775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 198875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void unlockRoot() { 198975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lockState = 0; 199075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 199175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 199275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 199375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Possibly blocks awaiting root lock. 199475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 199575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void contendedLock() { 199675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean waiting = false; 199775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int s;;) { 199875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (((s = lockState) & WRITER) == 0) { 199975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (U.compareAndSwapInt(this, LOCKSTATE, s, WRITER)) { 200075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (waiting) 200175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle waiter = null; 200275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return; 200375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 200475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 20054d75d062fa8392cb914829394f8bc76822fbc741You Kim else if ((s & WAITER) == 0) { 200675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (U.compareAndSwapInt(this, LOCKSTATE, s, s | WAITER)) { 200775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle waiting = true; 200875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle waiter = Thread.currentThread(); 200975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 201075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 201175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (waiting) 201275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle LockSupport.park(this); 201375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 201475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 201575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 201675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 201775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns matching node or null if none. Tries to search 201875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * using tree comparisons from root, but continues linear 201975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * search when lock not available. 202075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 202175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final Node<K,V> find(int h, Object k) { 202275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (k != null) { 202375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> e = first; e != null; e = e.next) { 202475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int s; K ek; 202575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (((s = lockState) & (WAITER|WRITER)) != 0) { 202675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e.hash == h && 202775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((ek = e.key) == k || (ek != null && k.equals(ek)))) 202875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return e; 202975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 203075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (U.compareAndSwapInt(this, LOCKSTATE, s, 203175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s + READER)) { 203275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> r, p; 203375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 203475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p = ((r = root) == null ? null : 203575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r.findTreeNode(h, k, null)); 203675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 203775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 203875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Thread w; 203975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int ls; 204075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle do {} while (!U.compareAndSwapInt 204175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (this, LOCKSTATE, 204275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ls = lockState, ls - READER)); 204375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (ls == (READER|WAITER) && (w = waiter) != null) 204475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle LockSupport.unpark(w); 204575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 204675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return p; 204775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 204875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 204975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 205075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 205175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 205275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 205375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 205475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Finds or adds a node. 205575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return null if added 205675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 205775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final TreeNode<K,V> putTreeVal(int h, K k, V v) { 205875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> kc = null; 205975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (TreeNode<K,V> p = root;;) { 206075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int dir, ph; K pk; TreeNode<K,V> q, pr; 206175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (p == null) { 206275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle first = root = new TreeNode<K,V>(h, k, v, null, null); 206375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 206475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 206575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((ph = p.hash) > h) 206675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = -1; 206775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (ph < h) 206875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = 1; 206975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((pk = p.key) == k || (pk != null && k.equals(pk))) 207075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return p; 207175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((kc == null && 207275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (kc = comparableClassFor(k)) == null) || 207375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (dir = compareComparables(kc, k, pk)) == 0) { 207475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (p.left == null) 207575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = 1; 207675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((pr = p.right) == null || 207775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (q = pr.findTreeNode(h, k, kc)) == null) 207875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle dir = -1; 207975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 208075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return q; 208175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 208275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> xp = p; 208375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = (dir < 0) ? p.left : p.right) == null) { 208475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> x, f = first; 208575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle first = x = new TreeNode<K,V>(h, k, v, f, xp); 208675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (f != null) 208775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle f.prev = x; 208875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (dir < 0) 208975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.left = x; 209075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 209175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.right = x; 209275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!xp.red) 209375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = true; 209475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 209575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lockRoot(); 209675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 209775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = balanceInsertion(root, x); 209875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 209975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle unlockRoot(); 210075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 210175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 210275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 210375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 210475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 210575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle assert checkInvariants(root); 210675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return null; 210775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 210875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 210975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 211075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Removes the given node, that must be present before this 211175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * call. This is messier than typical red-black deletion code 211275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * because we cannot swap the contents of an interior node 211375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * with a leaf successor that is pinned by "next" pointers 211475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * that are accessible independently of lock. So instead we 211575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * swap the tree linkages. 211675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 211775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return true if now too small, so should be untreeified 211875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 211975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final boolean removeTreeNode(TreeNode<K,V> p) { 212075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> next = (TreeNode<K,V>)p.next; 212175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pred = p.prev; // unlink traversal pointers 212275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> r, rl; 212375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (pred == null) 212475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle first = next; 212575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 212675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pred.next = next; 212775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (next != null) 212875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle next.prev = pred; 212975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (first == null) { 213075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = null; 213175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 213275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 213375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((r = root) == null || r.right == null || // too small 213475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (rl = r.left) == null || rl.left == null) 213575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 213675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lockRoot(); 213775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 213875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> replacement; 213975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pl = p.left; 214075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pr = p.right; 214175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (pl != null && pr != null) { 214275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> s = pr, sl; 214375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle while ((sl = s.left) != null) // find successor 214475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s = sl; 214575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean c = s.red; s.red = p.red; p.red = c; // swap colors 214675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> sr = s.right; 214775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pp = p.parent; 214875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (s == pr) { // p was s's direct parent 214975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.parent = s; 215075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle s.right = p; 215175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 215275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 215375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> sp = s.parent; 215475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p.parent = sp) != null) { 215575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (s == sp.left) 215675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sp.left = p; 215775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 215875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sp.right = p; 215975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 216075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((s.right = pr) != null) 216175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pr.parent = s; 216275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 216375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.left = null; 216475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p.right = sr) != null) 216575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sr.parent = p; 216675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((s.left = pl) != null) 216775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pl.parent = s; 216875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((s.parent = pp) == null) 216975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = s; 217075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (p == pp.left) 217175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.left = s; 217275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 217375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.right = s; 217475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sr != null) 217575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle replacement = sr; 217675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 217775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle replacement = p; 217875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 217975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pl != null) 218075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle replacement = pl; 218175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pr != null) 218275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle replacement = pr; 218375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 218475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle replacement = p; 218575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (replacement != p) { 218675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pp = replacement.parent = p.parent; 218775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (pp == null) 218875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = replacement; 218975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (p == pp.left) 219075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.left = replacement; 219175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 219275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.right = replacement; 219375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.left = p.right = p.parent = null; 219475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 219575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 219675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = (p.red) ? r : balanceDeletion(r, replacement); 219775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 219875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (p == replacement) { // detach pointers 219975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> pp; 220075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((pp = p.parent) != null) { 220175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (p == pp.left) 220275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.left = null; 220375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (p == pp.right) 220475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.right = null; 220575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.parent = null; 220675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 220775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 220875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 220975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle unlockRoot(); 221075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 221175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle assert checkInvariants(root); 221275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 221375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 221475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 221575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ------------------------------------------------------------ */ 221675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // Red-black tree methods, all adapted from CLR 221775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 221875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root, 221975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> p) { 222075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> r, pp, rl; 222175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (p != null && (r = p.right) != null) { 222275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((rl = p.right = r.left) != null) 222375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle rl.parent = p; 222475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((pp = r.parent = p.parent) == null) 222575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (root = r).red = false; 222675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pp.left == p) 222775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.left = r; 222875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 222975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.right = r; 223075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r.left = p; 223175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.parent = r; 223275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 223375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return root; 223475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 223575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 223675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root, 223775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> p) { 223875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> l, pp, lr; 223975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (p != null && (l = p.left) != null) { 224075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((lr = p.left = l.right) != null) 224175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lr.parent = p; 224275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((pp = l.parent = p.parent) == null) 224375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (root = l).red = false; 224475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (pp.right == p) 224575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.right = l; 224675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 224775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle pp.left = l; 224875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle l.right = p; 224975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle p.parent = l; 225075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 225175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return root; 225275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 225375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 225475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root, 225575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> x) { 225675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = true; 225775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (TreeNode<K,V> xp, xpp, xppl, xppr;;) { 225875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((xp = x.parent) == null) { 225975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = false; 226075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return x; 226175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 226275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (!xp.red || (xpp = xp.parent) == null) 226375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return root; 226475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xp == (xppl = xpp.left)) { 226575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((xppr = xpp.right) != null && xppr.red) { 226675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xppr.red = false; 226775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 226875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp.red = true; 226975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xpp; 227075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 227175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 227275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (x == xp.right) { 227375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateLeft(root, x = xp); 227475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp = (xp = x.parent) == null ? null : xp.parent; 227575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 227675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xp != null) { 227775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 227875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpp != null) { 227975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp.red = true; 228075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateRight(root, xpp); 228175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 228275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 228375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 228475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 228575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 228675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xppl != null && xppl.red) { 228775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xppl.red = false; 228875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 228975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp.red = true; 229075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xpp; 229175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 229275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 229375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (x == xp.left) { 229475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateRight(root, x = xp); 229575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp = (xp = x.parent) == null ? null : xp.parent; 229675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 229775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xp != null) { 229875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 229975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpp != null) { 230075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpp.red = true; 230175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateLeft(root, xpp); 230275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 230375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 230475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 230575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 230675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 230775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 230875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 230975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root, 231075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> x) { 231175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (TreeNode<K,V> xp, xpl, xpr;;) { 231275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (x == null || x == root) 231375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return root; 231475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((xp = x.parent) == null) { 231575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = false; 231675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return x; 231775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 231875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (x.red) { 231975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x.red = false; 232075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return root; 232175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 232275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if ((xpl = xp.left) == x) { 232375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((xpr = xp.right) != null && xpr.red) { 232475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr.red = false; 232575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = true; 232675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateLeft(root, xp); 232775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr = (xp = x.parent) == null ? null : xp.right; 232875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 232975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpr == null) 233075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xp; 233175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 233275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> sl = xpr.left, sr = xpr.right; 233375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((sr == null || !sr.red) && 233475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (sl == null || !sl.red)) { 233575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr.red = true; 233675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xp; 233775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 233875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 233975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sr == null || !sr.red) { 234075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sl != null) 234175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sl.red = false; 234275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr.red = true; 234375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateRight(root, xpr); 234475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr = (xp = x.parent) == null ? 234575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle null : xp.right; 234675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 234775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpr != null) { 234875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpr.red = (xp == null) ? false : xp.red; 234975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((sr = xpr.right) != null) 235075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sr.red = false; 235175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 235275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xp != null) { 235375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 235475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateLeft(root, xp); 235575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 235675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = root; 235775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 235875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 235975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 236075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { // symmetric 236175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpl != null && xpl.red) { 236275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl.red = false; 236375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = true; 236475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateRight(root, xp); 236575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl = (xp = x.parent) == null ? null : xp.left; 236675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 236775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpl == null) 236875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xp; 236975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 237075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> sl = xpl.left, sr = xpl.right; 237175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((sl == null || !sl.red) && 237275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (sr == null || !sr.red)) { 237375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl.red = true; 237475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = xp; 237575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 237675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else { 237775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sl == null || !sl.red) { 237875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sr != null) 237975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sr.red = false; 238075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl.red = true; 238175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateLeft(root, xpl); 238275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl = (xp = x.parent) == null ? 238375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle null : xp.left; 238475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 238575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xpl != null) { 238675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xpl.red = (xp == null) ? false : xp.red; 238775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((sl = xpl.left) != null) 238875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sl.red = false; 238975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 239075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (xp != null) { 239175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle xp.red = false; 239275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle root = rotateRight(root, xp); 239375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 239475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle x = root; 239575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 239675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 239775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 239875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 239975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 240075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 240175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 240275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Recursive invariant check 240375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 240475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static <K,V> boolean checkInvariants(TreeNode<K,V> t) { 240575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right, 240675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tb = t.prev, tn = (TreeNode<K,V>)t.next; 240775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tb != null && tb.next != t) 240875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 240975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tn != null && tn.prev != t) 241075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 241175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tp != null && t != tp.left && t != tp.right) 241275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 241375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tl != null && (tl.parent != t || tl.hash > t.hash)) 241475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 241575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tr != null && (tr.parent != t || tr.hash < t.hash)) 241675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 241775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (t.red && tl != null && tl.red && tr != null && tr.red) 241875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 241975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tl != null && !checkInvariants(tl)) 242075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 242175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (tr != null && !checkInvariants(tr)) 242275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 242375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 242475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 242575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 242675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final sun.misc.Unsafe U; 242775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long LOCKSTATE; 242875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static { 242975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 243075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U = sun.misc.Unsafe.getUnsafe(); 243175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> k = TreeBin.class; 243275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle LOCKSTATE = U.objectFieldOffset 243375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k.getDeclaredField("lockState")); 243475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } catch (Exception e) { 243575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new Error(e); 243675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 243775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 243875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 243975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 244075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ----------------Table Traversal -------------- */ 244175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 244275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 244375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Encapsulates traversal for methods such as containsValue; also 244475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * serves as a base class for other iterators. 244575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 244675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Method advance visits once each still-valid node that was 244775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * reachable upon iterator construction. It might miss some that 244875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * were added to a bin after the bin was visited, which is OK wrt 244975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * consistency guarantees. Maintaining this property in the face 245075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of possible ongoing resizes requires a fair amount of 245175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * bookkeeping state that is difficult to optimize away amidst 245275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * volatile accesses. Even so, traversal maintains reasonable 245375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * throughput. 245475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 245575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Normally, iteration proceeds bin-by-bin traversing lists. 245675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * However, if the table has been resized, then all future steps 245775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * must traverse both the bin at the current index as well as at 245875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (index + baseSize); and so on for further resizings. To 245975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * paranoically cope with potential sharing by users of iterators 246075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * across threads, iteration terminates if a bounds checks fails 246175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * for a table read. 246275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 246375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static class Traverser<K,V> { 246475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] tab; // current table; updated if resized 246575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> next; // the next entry to use 246675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int index; // index of bin to use next 246775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int baseIndex; // current index of initial table 246875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int baseLimit; // index bound for initial table 246975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final int baseSize; // initial table size 247075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 247175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser(Node<K,V>[] tab, int size, int index, int limit) { 247275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.tab = tab; 247375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.baseSize = size; 247475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.baseIndex = this.index = index; 247575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.baseLimit = limit; 247675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.next = null; 247775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 247875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 247975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 248075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Advances if possible, returning next valid node, or null if none. 248175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 248275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final Node<K,V> advance() { 248375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> e; 248475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((e = next) != null) 248575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e = e.next; 248675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (;;) { 248775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; int i, n; K ek; // must use locals in checks 248875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e != null) 248975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return next = e; 249075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (baseIndex >= baseLimit || (t = tab) == null || 249175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (n = t.length) <= (i = index) || i < 0) 249275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return next = null; 249375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((e = tabAt(t, index)) != null && e.hash < 0) { 249475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e instanceof ForwardingNode) { 249575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle tab = ((ForwardingNode<K,V>)e).nextTable; 249675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e = null; 249775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle continue; 249875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 249975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (e instanceof TreeBin) 250075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e = ((TreeBin<K,V>)e).first; 250175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 250275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle e = null; 250375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 250475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((index += baseSize) >= n) 250575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle index = ++baseIndex; // visit upper slots if present 250675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 250775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 250875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 250975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 251075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 251175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Base of key, value, and entry Iterators. Adds fields to 251275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Traverser to support iterator.remove. 251375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 251475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static class BaseIterator<K,V> extends Traverser<K,V> { 251575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final ConcurrentHashMap<K,V> map; 251675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> lastReturned; 251775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle BaseIterator(Node<K,V>[] tab, int size, int index, int limit, 251875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> map) { 251975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(tab, size, index, limit); 252075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.map = map; 252175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance(); 252275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 252375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 252475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean hasNext() { return next != null; } 252575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean hasMoreElements() { return next != null; } 252675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 252775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final void remove() { 252875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 252975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = lastReturned) == null) 253075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new IllegalStateException(); 253175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lastReturned = null; 253275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle map.replaceNode(p.key, null, null); 253375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 253475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 253575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 253675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class KeyIterator<K,V> extends BaseIterator<K,V> 253775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Iterator<K>, Enumeration<K> { 253875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle KeyIterator(Node<K,V>[] tab, int index, int size, int limit, 253975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> map) { 254075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(tab, index, size, limit, map); 254175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 254275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 254375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final K next() { 254475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 254575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = next) == null) 254675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NoSuchElementException(); 254775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K k = p.key; 254875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lastReturned = p; 254975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance(); 255075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return k; 255175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 255275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 255375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final K nextElement() { return next(); } 255475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 255575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 255675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class ValueIterator<K,V> extends BaseIterator<K,V> 255775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Iterator<V>, Enumeration<V> { 255875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ValueIterator(Node<K,V>[] tab, int index, int size, int limit, 255975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> map) { 256075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(tab, index, size, limit, map); 256175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 256275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 256375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final V next() { 256475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 256575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = next) == null) 256675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NoSuchElementException(); 256775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v = p.val; 256875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lastReturned = p; 256975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance(); 257075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return v; 257175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 257275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 257375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final V nextElement() { return next(); } 257475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 257575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 257675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class EntryIterator<K,V> extends BaseIterator<K,V> 257775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Iterator<Map.Entry<K,V>> { 257875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle EntryIterator(Node<K,V>[] tab, int index, int size, int limit, 257975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> map) { 258075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(tab, index, size, limit, map); 258175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 258275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 258375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final Map.Entry<K,V> next() { 258475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V> p; 258575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((p = next) == null) 258675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new NoSuchElementException(); 258775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle K k = p.key; 258875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v = p.val; 258975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle lastReturned = p; 259075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle advance(); 259175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new MapEntry<K,V>(k, v, map); 259275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 259375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 259475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 259575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 259675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Exported Entry for EntryIterator 259775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 259875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class MapEntry<K,V> implements Map.Entry<K,V> { 259975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final K key; // non-null 260075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V val; // non-null 260175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final ConcurrentHashMap<K,V> map; 260275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle MapEntry(K key, V val, ConcurrentHashMap<K,V> map) { 260375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.key = key; 260475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.val = val; 260575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.map = map; 260675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 260775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public K getKey() { return key; } 260875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public V getValue() { return val; } 260975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public int hashCode() { return key.hashCode() ^ val.hashCode(); } 261075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public String toString() { return key + "=" + val; } 261175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 261275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean equals(Object o) { 261375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object k, v; Map.Entry<?,?> e; 261475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Map.Entry) && 261575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 261675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v = e.getValue()) != null && 261775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k == key || k.equals(key)) && 261875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v == val || v.equals(val))); 261975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 262075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 262175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 262275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Sets our entry's value and writes through to the map. The 262375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * value to return is somewhat arbitrary here. Since we do not 262475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * necessarily track asynchronous changes, the most recent 262575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * "previous" value could be different from what we return (or 262675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * could even have been removed, in which case the put will 262775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * re-establish). We do not and cannot guarantee more. 262875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 262975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public V setValue(V value) { 263075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (value == null) throw new NullPointerException(); 263175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v = val; 263275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle val = value; 263375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle map.put(key, value); 263475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return v; 263575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 263675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 263775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 263875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ----------------Views -------------- */ 263975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 264075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 264175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Base class for views. 264275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 264375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 264475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle abstract static class CollectionView<K,V,E> 264575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Collection<E>, java.io.Serializable { 264675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long serialVersionUID = 7249069246763182397L; 264775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final ConcurrentHashMap<K,V> map; 264875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CollectionView(ConcurrentHashMap<K,V> map) { this.map = map; } 264975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 265075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 265175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the map backing this view. 265275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 265375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the map backing this view 265475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 265575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public ConcurrentHashMap<K,V> getMap() { return map; } 265675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 265775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 265875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Removes all of the elements from this view, by removing all 265975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the mappings from the map backing this view. 266075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 266175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final void clear() { map.clear(); } 266275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final int size() { return map.size(); } 266375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean isEmpty() { return map.isEmpty(); } 266475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 266575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // implementations below rely on concrete classes supplying these 266675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // abstract methods 266775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 266875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a "weakly consistent" iterator that will never 266975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * throw {@link ConcurrentModificationException}, and 267075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * guarantees to traverse elements as they existed upon 267175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * construction of the iterator, and may (but is not 267275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * guaranteed to) reflect any modifications subsequent to 267375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * construction. 267475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 267575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public abstract Iterator<E> iterator(); 267675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public abstract boolean contains(Object o); 267775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public abstract boolean remove(Object o); 267875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 267975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final String oomeMsg = "Required array size too large"; 268075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 268175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final Object[] toArray() { 268275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long sz = map.mappingCount(); 268375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sz > MAX_ARRAY_SIZE) 268475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new OutOfMemoryError(oomeMsg); 268575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n = (int)sz; 268675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object[] r = new Object[n]; 268775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int i = 0; 268875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (E e : this) { 268975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (i == n) { 269075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (n >= MAX_ARRAY_SIZE) 269175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new OutOfMemoryError(oomeMsg); 269275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) 269375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n = MAX_ARRAY_SIZE; 269475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 269575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n += (n >>> 1) + 1; 269675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = Arrays.copyOf(r, n); 269775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 269875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r[i++] = e; 269975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 270075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (i == n) ? r : Arrays.copyOf(r, i); 270175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 270275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 270375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle @SuppressWarnings("unchecked") 270475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final <T> T[] toArray(T[] a) { 270575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long sz = map.mappingCount(); 270675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (sz > MAX_ARRAY_SIZE) 270775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new OutOfMemoryError(oomeMsg); 270875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int m = (int)sz; 270975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle T[] r = (a.length >= m) ? a : 271075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (T[])java.lang.reflect.Array 271175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle .newInstance(a.getClass().getComponentType(), m); 271275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int n = r.length; 271375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int i = 0; 271475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (E e : this) { 271575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (i == n) { 271675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (n >= MAX_ARRAY_SIZE) 271775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new OutOfMemoryError(oomeMsg); 271875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) 271975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n = MAX_ARRAY_SIZE; 272075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 272175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle n += (n >>> 1) + 1; 272275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r = Arrays.copyOf(r, n); 272375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 272475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r[i++] = (T)e; 272575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 272675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (a == r && i < n) { 272775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle r[i] = null; // null-terminate 272875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return r; 272975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 273075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return (i == n) ? r : Arrays.copyOf(r, i); 273175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 273275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 273375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 273475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns a string representation of this collection. 273575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The string representation consists of the string representations 273675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * of the collection's elements in the order they are returned by 273775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * its iterator, enclosed in square brackets ({@code "[]"}). 273875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Adjacent elements are separated by the characters {@code ", "} 273975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * (comma and space). Elements are converted to strings as by 274075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@link String#valueOf(Object)}. 274175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 274275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return a string representation of this collection 274375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 274475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final String toString() { 274575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle StringBuilder sb = new StringBuilder(); 274675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append('['); 274775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Iterator<E> it = iterator(); 274875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (it.hasNext()) { 274975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (;;) { 275075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object e = it.next(); 275175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append(e == this ? "(this Collection)" : e); 275275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!it.hasNext()) 275375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 275475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sb.append(',').append(' '); 275575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 275675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 275775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return sb.append(']').toString(); 275875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 275975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 276075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean containsAll(Collection<?> c) { 276175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (c != this) { 276275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Object e : c) { 276375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (e == null || !contains(e)) 276475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 276575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 276675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 276775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 276875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 276975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 277075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean removeAll(Collection<?> c) { 277175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean modified = false; 277275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Iterator<E> it = iterator(); it.hasNext();) { 277375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (c.contains(it.next())) { 277475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle it.remove(); 277575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle modified = true; 277675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 277775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 277875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return modified; 277975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 278075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 278175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean retainAll(Collection<?> c) { 278275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean modified = false; 278375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Iterator<E> it = iterator(); it.hasNext();) { 278475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (!c.contains(it.next())) { 278575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle it.remove(); 278675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle modified = true; 278775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 278875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 278975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return modified; 279075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 279175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 279275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 279375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 279475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 279575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * A view of a ConcurrentHashMap as a {@link Set} of keys, in 279675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * which additions may optionally be enabled by mapping to a 279775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * common value. This class cannot be directly instantiated. 279875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * See {@link #keySet() keySet()}, 279975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@link #keySet(Object) keySet(V)}, 280075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@link #newKeySet() newKeySet()}, 280175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@link #newKeySet(int) newKeySet(int)}. 280275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 280375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @since 1.8 280475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 280575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @hide 280675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 280775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public static class KeySetView<K,V> extends CollectionView<K,V,K> 280875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Set<K>, java.io.Serializable { 280975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long serialVersionUID = 7249069246763182397L; 281075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final V value; 281175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle KeySetView(ConcurrentHashMap<K,V> map, V value) { // non-public 281275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle super(map); 281375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle this.value = value; 281475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 281575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 281675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 281775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the default mapped value for additions, 281875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * or {@code null} if additions are not supported. 281975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 282075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return the default mapped value for additions, or {@code null} 282175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * if not supported 282275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 282375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public V getMappedValue() { return value; } 282475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 282575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 282675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@inheritDoc} 282775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key is null 282875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 282975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean contains(Object o) { return map.containsKey(o); } 283075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 283175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 283275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Removes the key from this map view, by removing the key (and its 283375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * corresponding value) from the backing map. This method does 283475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * nothing if the key is not in the map. 283575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 283675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param o the key to be removed from the backing map 283775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if the backing map contained the specified key 283875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key is null 283975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 284075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean remove(Object o) { return map.remove(o) != null; } 284175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 284275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 284375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return an iterator over the keys of the backing map 284475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 284575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public Iterator<K> iterator() { 284675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 284775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> m = map; 284875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = m.table) == null ? 0 : t.length; 284975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new KeyIterator<K,V>(t, f, 0, f, m); 285075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 285175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 285275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 285375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Adds the specified key to this set view by mapping the key to 285475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * the default mapped value in the backing map, if defined. 285575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 285675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param e key to be added 285775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if this set changed as a result of the call 285875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the specified key is null 285975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws UnsupportedOperationException if no default mapped value 286075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * for additions was provided 286175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 286275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean add(K e) { 286375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v; 286475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((v = value) == null) 286575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new UnsupportedOperationException(); 286675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return map.putVal(e, v, true) == null; 286775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 286875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 286975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 287075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Adds all of the elements in the specified collection to this set, 287175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * as if by calling {@link #add} on each one. 287275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * 287375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @param c the elements to be inserted into this set 287475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return {@code true} if this set changed as a result of the call 287575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws NullPointerException if the collection or any of its 287675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * elements are {@code null} 287775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @throws UnsupportedOperationException if no default mapped value 287875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * for additions was provided 287975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 288075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean addAll(Collection<? extends K> c) { 288175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean added = false; 288275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle V v; 288375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((v = value) == null) 288475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new UnsupportedOperationException(); 288575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (K e : c) { 288675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (map.putVal(e, v, true) == null) 288775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle added = true; 288875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 288975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return added; 289075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 289175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 289275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public int hashCode() { 289375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = 0; 289475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (K e : this) 289575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h += e.hashCode(); 289675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return h; 289775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 289875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 289975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean equals(Object o) { 290075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Set<?> c; 290175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Set) && 290275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((c = (Set<?>)o) == this || 290375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (containsAll(c) && c.containsAll(this)))); 290475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 290575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 290675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 290775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 290875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 290975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * A view of a ConcurrentHashMap as a {@link Collection} of 291075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * values, in which additions are disabled. This class cannot be 291175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * directly instantiated. See {@link #values()}. 291275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 291375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class ValuesView<K,V> extends CollectionView<K,V,V> 291475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Collection<V>, java.io.Serializable { 291575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long serialVersionUID = 2249069246763182397L; 291675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ValuesView(ConcurrentHashMap<K,V> map) { super(map); } 291775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean contains(Object o) { 291875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return map.containsValue(o); 291975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 292075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 292175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean remove(Object o) { 292275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (o != null) { 292375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Iterator<V> it = iterator(); it.hasNext();) { 292475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (o.equals(it.next())) { 292575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle it.remove(); 292675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return true; 292775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 292875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 292975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 293075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return false; 293175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 293275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 293375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final Iterator<V> iterator() { 293475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> m = map; 293575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 293675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = m.table) == null ? 0 : t.length; 293775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new ValueIterator<K,V>(t, f, 0, f, m); 293875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 293975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 294075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean add(V e) { 294175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new UnsupportedOperationException(); 294275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 294375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean addAll(Collection<? extends V> c) { 294475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new UnsupportedOperationException(); 294575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 294675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 294775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 294875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 294975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 295075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * A view of a ConcurrentHashMap as a {@link Set} of (key, value) 295175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * entries. This class cannot be directly instantiated. See 295275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@link #entrySet()}. 295375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 295475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class EntrySetView<K,V> extends CollectionView<K,V,Map.Entry<K,V>> 295575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle implements Set<Map.Entry<K,V>>, java.io.Serializable { 295675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long serialVersionUID = 2249069246763182397L; 295775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle EntrySetView(ConcurrentHashMap<K,V> map) { super(map); } 295875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 295975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean contains(Object o) { 296075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object k, v, r; Map.Entry<?,?> e; 296175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Map.Entry) && 296275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 296375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (r = map.get(k)) != null && 296475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v = e.getValue()) != null && 296575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v == r || v.equals(r))); 296675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 296775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 296875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean remove(Object o) { 296975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Object k, v; Map.Entry<?,?> e; 297075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Map.Entry) && 297175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 297275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (v = e.getValue()) != null && 297375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle map.remove(k, v)); 297475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 297575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 297675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 297775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * @return an iterator over the entries of the backing map 297875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 297975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public Iterator<Map.Entry<K,V>> iterator() { 298075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ConcurrentHashMap<K,V> m = map; 298175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 298275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int f = (t = m.table) == null ? 0 : t.length; 298375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return new EntryIterator<K,V>(t, f, 0, f, m); 298475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 298575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 298675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean add(Entry<K,V> e) { 298775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return map.putVal(e.getKey(), e.getValue(), false) == null; 298875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 298975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 299075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public boolean addAll(Collection<? extends Entry<K,V>> c) { 299175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean added = false; 299275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Entry<K,V> e : c) { 299375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (add(e)) 299475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle added = true; 299575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 299675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return added; 299775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 299875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 299975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final int hashCode() { 300075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h = 0; 300175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Node<K,V>[] t; 300275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((t = map.table) != null) { 300375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 300475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (Node<K,V> p; (p = it.advance()) != null; ) { 300575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h += p.hashCode(); 300675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 300775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 300875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return h; 300975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 301075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 301175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle public final boolean equals(Object o) { 301275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Set<?> c; 301375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return ((o instanceof Set) && 301475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ((c = (Set<?>)o) == this || 301575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (containsAll(c) && c.containsAll(this)))); 301675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 301775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 301875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 301975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 302075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 302175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /* ---------------- Counters -------------- */ 302275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 302375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // Adapted from LongAdder and Striped64. 302475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // See their internal docs for explanation. 302575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 302675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // A padded cell for distributing counts 302775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class CounterCell { 302875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile long p0, p1, p2, p3, p4, p5, p6; 302975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile long value; 303075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle volatile long q0, q1, q2, q3, q4, q5, q6; 303175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell(long x) { value = x; } 303275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 303375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 303475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 303575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Holder for the thread-local hash code determining which 303675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * CounterCell to use. The code is initialized via the 303775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * counterHashCodeGenerator, but may be moved upon collisions. 303875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 303975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final class CounterHashCode { 304075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int code; 304175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 304275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 304375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 304475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Generates initial value for per-thread CounterHashCodes. 304575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 304675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final AtomicInteger counterHashCodeGenerator = new AtomicInteger(); 304775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 304875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 304975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Increment for counterHashCodeGenerator. See class ThreadLocal 305075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * for explanation. 305175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 305275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final int SEED_INCREMENT = 0x61c88647; 305375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 305475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle /** 305575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Per-thread counter hash codes. Shared across all instances. 305675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle */ 305775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle static final ThreadLocal<CounterHashCode> threadCounterHashCode = 305875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle new ThreadLocal<CounterHashCode>(); 305975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 306075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle final long sumCount() { 306175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] as = counterCells; CounterCell a; 306275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle long sum = baseCount; 306375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (as != null) { 306475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int i = 0; i < as.length; ++i) { 306575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((a = as[i]) != null) 306675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle sum += a.value; 306775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 306875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 306975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return sum; 307075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 307175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle 307275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle // See LongAdder version for explanation 307375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private final void fullAddCount(long x, CounterHashCode hc, 307475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean wasUncontended) { 307575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int h; 307675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (hc == null) { 307775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hc = new CounterHashCode(); 307875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int s = counterHashCodeGenerator.addAndGet(SEED_INCREMENT); 307975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h = hc.code = (s == 0) ? 1 : s; // Avoid zero 308075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle threadCounterHashCode.set(hc); 308175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 308275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else 308375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h = hc.code; 308475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean collide = false; // True if last slot nonempty 308575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (;;) { 308675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] as; CounterCell a; int n; long v; 308775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((as = counterCells) != null && (n = as.length) > 0) { 308875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((a = as[(n - 1) & h]) == null) { 308975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (cellsBusy == 0) { // Try to attach new Cell 309075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell r = new CounterCell(x); // Optimistic create 309175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (cellsBusy == 0 && 309275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) { 309375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean created = false; 309475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { // Recheck under lock 309575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] rs; int m, j; 309675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((rs = counterCells) != null && 309775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (m = rs.length) > 0 && 309875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle rs[j = (m - 1) & h] == null) { 309975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle rs[j] = r; 310075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle created = true; 310175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 310275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 310375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle cellsBusy = 0; 310475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 310575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (created) 310675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 310775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle continue; // Slot is now non-empty 310875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 310975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 311075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle collide = false; 311175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 311275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (!wasUncontended) // CAS already known to fail 311375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle wasUncontended = true; // Continue after rehash 311475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x)) 311575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 311675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (counterCells != as || n >= NCPU) 311775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle collide = false; // At max size or stale 311875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (!collide) 311975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle collide = true; 312075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (cellsBusy == 0 && 312175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) { 312275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { 312375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (counterCells == as) {// Expand table unless stale 312475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] rs = new CounterCell[n << 1]; 312575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle for (int i = 0; i < n; ++i) 312675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle rs[i] = as[i]; 312775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle counterCells = rs; 312875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 312975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 313075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle cellsBusy = 0; 313175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 313275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle collide = false; 313375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle continue; // Retry with expanded table 313475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 313575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h ^= h << 13; // Rehash 313675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h ^= h >>> 17; 313775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle h ^= h << 5; 313875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 313975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (cellsBusy == 0 && counterCells == as && 314075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) { 314175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle boolean init = false; 314275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle try { // Initialize table 314375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (counterCells == as) { 314475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CounterCell[] rs = new CounterCell[2]; 314575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle rs[h & 1] = new CounterCell(x); 314675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle counterCells = rs; 314775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle init = true; 314875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 314975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } finally { 315075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle cellsBusy = 0; 315175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 315275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if (init) 315375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; 315475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle } 315575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle else if (U.compareAndSwapLong(this, BASECOUNT, v = baseCount, v + x)) 315675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle break; // Fall back on using base 3157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 315875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle hc.code = h; // Record index for next time 3159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3160a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 3161a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson // Unsafe mechanics 316275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final sun.misc.Unsafe U; 316375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long SIZECTL; 316475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long TRANSFERINDEX; 316575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long TRANSFERORIGIN; 316675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long BASECOUNT; 316775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long CELLSBUSY; 316875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long CELLVALUE; 316975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final long ABASE; 317075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle private static final int ASHIFT; 3171a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 3172a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson static { 3173a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson try { 317475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle U = sun.misc.Unsafe.getUnsafe(); 317575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> k = ConcurrentHashMap.class; 317675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle SIZECTL = U.objectFieldOffset 317775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k.getDeclaredField("sizeCtl")); 317875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TRANSFERINDEX = U.objectFieldOffset 317975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k.getDeclaredField("transferIndex")); 318075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle TRANSFERORIGIN = U.objectFieldOffset 318175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k.getDeclaredField("transferOrigin")); 318275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle BASECOUNT = U.objectFieldOffset 318375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k.getDeclaredField("baseCount")); 318475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CELLSBUSY = U.objectFieldOffset 318575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (k.getDeclaredField("cellsBusy")); 318675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> ck = CounterCell.class; 318775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle CELLVALUE = U.objectFieldOffset 318875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle (ck.getDeclaredField("value")); 318975a06e56a4cc4599946e21422513e4bafa759509Calin Juravle Class<?> ak = Node[].class; 319075a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ABASE = U.arrayBaseOffset(ak); 319175a06e56a4cc4599946e21422513e4bafa759509Calin Juravle int scale = U.arrayIndexScale(ak); 319275a06e56a4cc4599946e21422513e4bafa759509Calin Juravle if ((scale & (scale - 1)) != 0) 319375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle throw new Error("data type scale not a power of two"); 319475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle ASHIFT = 31 - Integer.numberOfLeadingZeros(scale); 3195a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } catch (Exception e) { 3196a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson throw new Error(e); 3197a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 3198a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 3199a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 3200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 3201