Home / Class/ ConcurrentSkipListIntObjMultimap Class — netty Architecture

ConcurrentSkipListIntObjMultimap Class — netty Architecture

Architecture documentation for the ConcurrentSkipListIntObjMultimap class in ConcurrentSkipListIntObjMultimap.java from the netty codebase.

Entity Profile

Dependency Diagram

graph TD
  d9a8da36_aab9_ab33_dc67_870b34dcd270["ConcurrentSkipListIntObjMultimap"]
  2dc2d6e5_c15a_8f05_f928_659448d21a9f["ConcurrentSkipListIntObjMultimap.java"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|defined in| 2dc2d6e5_c15a_8f05_f928_659448d21a9f
  7e2d9d49_a28d_4cbe_a83c_2187034997b4["cpr()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| 7e2d9d49_a28d_4cbe_a83c_2187034997b4
  46a88bc6_04d3_48e3_2fff_16407ed81e0c["baseHead()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| 46a88bc6_04d3_48e3_2fff_16407ed81e0c
  14308445_2437_e26b_41bb_c7458d3b14e0["unlinkNode()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| 14308445_2437_e26b_41bb_c7458d3b14e0
  f9a987be_7587_17d3_1e33_3b91accd15b7["addCount()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| f9a987be_7587_17d3_1e33_3b91accd15b7
  12659e86_a84c_a54a_0f57_eafb421a134f["getAdderCount()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| 12659e86_a84c_a54a_0f57_eafb421a134f
  ff16b6d0_47d8_82e1_a033_998f1f35233f["findPredecessor()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| ff16b6d0_47d8_82e1_a033_998f1f35233f
  e6377398_2342_36cb_6b52_ad257316c9a9["findNode()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| e6377398_2342_36cb_6b52_ad257316c9a9
  c3cfe397_12eb_0ed0_7cef_c3f236e1c658["V()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| c3cfe397_12eb_0ed0_7cef_c3f236e1c658
  4b0df467_4bc8_3d65_e85c_0c0d65eefc3c["addIndices()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| 4b0df467_4bc8_3d65_e85c_0c0d65eefc3c
  a5591d9d_8462_4796_8a91_2dfef6e505cf["tryReduceLevel()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| a5591d9d_8462_4796_8a91_2dfef6e505cf
  55e0f54c_1f67_1d03_40c0_55d8270fc50b["findFirst()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| 55e0f54c_1f67_1d03_40c0_55d8270fc50b
  81092863_905e_04ce_e76a_57bcd98f336f["findFirstEntry()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| 81092863_905e_04ce_e76a_57bcd98f336f
  e1018349_653b_7710_9bf6_715fdd68c860["doRemoveFirstEntry()"]
  d9a8da36_aab9_ab33_dc67_870b34dcd270 -->|method| e1018349_653b_7710_9bf6_715fdd68c860

Relationship Graph

Source Code

common/src/main/java/io/netty/util/concurrent/ConcurrentSkipListIntObjMultimap.java lines 85–1619

public class ConcurrentSkipListIntObjMultimap<V> implements Iterable<ConcurrentSkipListIntObjMultimap.IntEntry<V>> {
    /*
     * This class implements a tree-like two-dimensionally linked skip
     * list in which the index levels are represented in separate
     * nodes from the base nodes holding data.  There are two reasons
     * for taking this approach instead of the usual array-based
     * structure: 1) Array based implementations seem to encounter
     * more complexity and overhead 2) We can use cheaper algorithms
     * for the heavily-traversed index lists than can be used for the
     * base lists.  Here's a picture of some of the basics for a
     * possible list with 2 levels of index:
     *
     * Head nodes          Index nodes
     * +-+    right        +-+                      +-+
     * |2|---------------->| |--------------------->| |->null
     * +-+                 +-+                      +-+
     *  | down              |                        |
     *  v                   v                        v
     * +-+            +-+  +-+       +-+            +-+       +-+
     * |1|----------->| |->| |------>| |----------->| |------>| |->null
     * +-+            +-+  +-+       +-+            +-+       +-+
     *  v              |    |         |              |         |
     * Nodes  next     v    v         v              v         v
     * +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+
     * | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null
     * +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+
     *
     * The base lists use a variant of the HM linked ordered set
     * algorithm. See Tim Harris, "A pragmatic implementation of
     * non-blocking linked lists"
     * https://www.cl.cam.ac.uk/~tlh20/publications.html and Maged
     * Michael "High Performance Dynamic Lock-Free Hash Tables and
     * List-Based Sets"
     * https://www.research.ibm.com/people/m/michael/pubs.htm.  The
     * basic idea in these lists is to mark the "next" pointers of
     * deleted nodes when deleting to avoid conflicts with concurrent
     * insertions, and when traversing to keep track of triples
     * (predecessor, node, successor) in order to detect when and how
     * to unlink these deleted nodes.
     *
     * Rather than using mark-bits to mark list deletions (which can
     * be slow and space-intensive using AtomicMarkedReference), nodes
     * use direct CAS'able next pointers.  On deletion, instead of
     * marking a pointer, they splice in another node that can be
     * thought of as standing for a marked pointer (see method
     * unlinkNode).  Using plain nodes acts roughly like "boxed"
     * implementations of marked pointers, but uses new nodes only
     * when nodes are deleted, not for every link.  This requires less
     * space and supports faster traversal. Even if marked references
     * were better supported by JVMs, traversal using this technique
     * might still be faster because any search need only read ahead
     * one more node than otherwise required (to check for trailing
     * marker) rather than unmasking mark bits or whatever on each
     * read.
     *
     * This approach maintains the essential property needed in the HM
     * algorithm of changing the next-pointer of a deleted node so
     * that any other CAS of it will fail, but implements the idea by
     * changing the pointer to point to a different node (with
     * otherwise illegal null fields), not by marking it.  While it
     * would be possible to further squeeze space by defining marker
     * nodes not to have key/value fields, it isn't worth the extra
     * type-testing overhead.  The deletion markers are rarely
     * encountered during traversal, are easily detected via null
     * checks that are needed anyway, and are normally quickly garbage
     * collected. (Note that this technique would not work well in
     * systems without garbage collection.)
     *
     * In addition to using deletion markers, the lists also use
     * nullness of value fields to indicate deletion, in a style
     * similar to typical lazy-deletion schemes.  If a node's value is
     * null, then it is considered logically deleted and ignored even
     * though it is still reachable.
     *
     * Here's the sequence of events for a deletion of node n with
     * predecessor b and successor f, initially:
     *
     *        +------+       +------+      +------+
     *   ...  |   b  |------>|   n  |----->|   f  | ...
     *        +------+       +------+      +------+
     *

Frequently Asked Questions

What is the ConcurrentSkipListIntObjMultimap class?
ConcurrentSkipListIntObjMultimap is a class in the netty codebase, defined in common/src/main/java/io/netty/util/concurrent/ConcurrentSkipListIntObjMultimap.java.
Where is ConcurrentSkipListIntObjMultimap defined?
ConcurrentSkipListIntObjMultimap is defined in common/src/main/java/io/netty/util/concurrent/ConcurrentSkipListIntObjMultimap.java at line 85.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free