MCPcopy
hub / github.com/questdb/questdb / ConcurrentHashMap

Class ConcurrentHashMap

core/src/main/java/io/questdb/std/ConcurrentHashMap.java:239–3789  ·  view source on GitHub ↗

A hash table supporting full concurrency of retrievals and high expected concurrency for updates. This class obeys the same functional specification as java.util.Hashtable, and includes versions of methods corresponding to each method of Hashtable. However, even though all operations

Source from the content-addressed store, hash-verified

237 * @since 1.5
238 */
239@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
240public class ConcurrentHashMap<V> extends AbstractMap<CharSequence, V>
241 implements ConcurrentMap<CharSequence, V>, Serializable {
242 static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash
243
244 /*
245 * Overview:
246 *
247 * The primary design goal of this hash table is to maintain
248 * concurrent readability (typically method get(), but also
249 * iterators and related methods) while minimizing update
250 * contention. Secondary goals are to keep space consumption about
251 * the same or better than java.util.HashMap, and to support high
252 * initial insertion rates on an empty table by many threads.
253 *
254 * This map usually acts as a binned (bucketed) hash table. Each
255 * key-value mapping is held in a Node. Most nodes are instances
256 * of the basic Node class with hash, key, value, and next
257 * fields. However, various subclasses exist: TreeNodes are
258 * arranged in balanced trees, not lists. TreeBins hold the roots
259 * of sets of TreeNodes. ForwardingNodes are placed at the heads
260 * of bins during resizing. ReservationNodes are used as
261 * placeholders while establishing values in computeIfAbsent and
262 * related methods. The types TreeBin, ForwardingNode, and
263 * ReservationNode do not hold normal user keys, values, or
264 * hashes, and are readily distinguishable during search etc
265 * because they have negative hash fields and null key and value
266 * fields. (These special nodes are either uncommon or transient,
267 * so the impact of carrying around some unused fields is
268 * insignificant.)
269 *
270 * The table is lazily initialized to a power-of-two size upon the
271 * first insertion. Each bin in the table normally contains a
272 * list of Nodes (most often, the list has only zero or one Node).
273 * Table accesses require volatile/atomic reads, writes, and
274 * CASes. Because there is no other way to arrange this without
275 * adding further indirections, we use intrinsics
276 * (sun.misc.Unsafe) operations.
277 *
278 * We use the top (sign) bit of Node hash fields for control
279 * purposes -- it is available anyway because of addressing
280 * constraints. Nodes with negative hash fields are specially
281 * handled or ignored in map methods.
282 *
283 * Insertion (via put or its variants) of the first node in an
284 * empty bin is performed by just CASing it to the bin. This is
285 * by far the most common case for put operations under most
286 * key/hash distributions. Other update operations (insert,
287 * delete, and replace) require locks. We do not want to waste
288 * the space required to associate a distinct lock object with
289 * each bin, so instead use the first node of a bin list itself as
290 * a lock. Locking support for these locks relies on builtin
291 * "synchronized" monitors.
292 *
293 * Using the first node of a list as a lock does not by itself
294 * suffice though: When a node is locked, any update must first
295 * validate that it is still the first node after locking it, and
296 * retry if not. Because new nodes are always appended to lists,

Callers

nothing calls this directly

Calls 4

initialSeedMethod · 0.95
objectFieldOffsetMethod · 0.95
arrayBaseOffsetMethod · 0.95
arrayIndexScaleMethod · 0.95

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…