/*
*
*
*
*
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
import java.io.Serializable;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NavigableSet;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedMap;
import java.util.Spliterator;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* 可扩展的并发 ConcurrentNavigableMap 实现。
* A scalable concurrent {@link ConcurrentNavigableMap} implementation.
* 映射可以根据key的自然顺序进行排序,也可以根据创建Map时所提供的 Comparator 进行排序,
* 具体取决于使用的构造方法
* The map is sorted according to the {@linkplain Comparable natural
* ordering} of its keys, or by a {@link Comparator} provided at map
* creation time, depending on which constructor is used.
*
* 此类实现 SkipLists 的并发变体,为 containsKey、get、put、remove 操作及其变体提供预期
* 平均 log(n) 时间开销。
* <p>This class implements a concurrent variant of <a
* href="http://en.wikipedia.org/wiki/Skip_list" target="_top">SkipLists</a>
* providing expected average <i>log(n)</i> time cost for the
* {@code containsKey}, {@code get}, {@code put} and
* {@code remove} operations and their variants. Insertion, removal,
* 多个线程可以安全地并发执行插入、移除、更新和访问操作。
* update, and access operations safely execute concurrently by
* multiple threads.
*
* Iterators and spliterators是弱一致性的 (1、next()返回的值(key / value)可能已经被删除了;2、返回的value是缓存的值,如果期间value 被修改了,
* 也不会返回最新的值。
* <p>Iterators and spliterators are
* <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* 升序key排序视图及其迭代器比降序key排序视图及其迭代器更快。
* <p>Ascending key ordered views and their iterators are faster than
* descending ones.
*
* 此类及此类视图中的方法返回的所有 Map.Entry 对,表示他们生成时的映射关系快照。
* <p>All {@code Map.Entry} pairs returned by methods in this class
* and its views represent snapshots of mappings at the time they were
* 它们不 支持 Entry.setValue 方法。
* produced. They do <em>not</em> support the {@code Entry.setValue}
* (注意,根据所需效果,可以使用 put、putIfAbsent 或 replace 更改关联映射中的映射关系。)
* method. (Note however that it is possible to change mappings in the
* associated map using {@code put}, {@code putIfAbsent}, or
* {@code replace}, depending on exactly which effect you need.)
*
* 请注意,与在大多数 collection 中不同,这里的 size 方法不是 一个常量时间操作。
* <p>Beware that, unlike in most collections, the {@code size}
* method is <em>not</em> a constant-time operation. Because of the
* 因为这些映射的异步特性,确定元素的当前数目需要遍历元素,并可能报告不正确的结果,
* 如果这个集合在遍历期间被修改。
* asynchronous nature of these maps, determining the current number
* of elements requires a traversal of the elements, and so may report
* inaccurate results if this collection is modified during traversal.
* 此外,批量操作 putAll、equals 和 clear 并不 保证能以原子方式 (atomically) 执行。
* Additionally, the bulk operations {@code putAll}, {@code equals},
* {@code toArray}, {@code containsValue}, and {@code clear} are
* <em>not</em> guaranteed to be performed atomically. For example, an
* 例如,与 putAll 操作一起并发操作的迭代器只能查看某些添加元素。
* iterator operating concurrently with a {@code putAll} operation
* might view only some of the added elements.
*
* 此类及其视图和迭代器实现 Map 和 Iterator 接口的所有可选 方法。
* <p>This class and its views and iterators implement all of the
* <em>optional</em> methods of the {@link Map} and {@link Iterator}
* interfaces. Like most other concurrent collections, this class does
* 与大多数其他并发 collection 一样,此类不 允许使用 null 键或值,因为无法可靠地
* 区分 null 返回值与不存在的元素值。
* <em>not</em> permit the use of {@code null} keys or values because some
* null return values cannot be reliably distinguished from the absence of
* elements.
*
* 此类是 Java Collections Framework 的成员。
* <p>This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @param <K> the type of keys maintained by this map
* @param <V> the type of mapped values
* @author Doug Lea
* @since 1.6
*/
/**
* 1、目前还没有有效的针对搜索树的无锁插入和删除算法。 搜索树至少有左右两个节点,没办法像列表一样,
* 通过CAS修改要删除节点的next 字段来表示该节点将要删除,从而不能在该节点进行插入操作。(因为需要
* 同时修改子节点,必须使用锁来进行多个子节点的原子性修改)
*
*/
public class ConcurrentSkipListMap<K, V> extends AbstractMap<K, V>
implements ConcurrentNavigableMap<K, V>, Cloneable, Serializable {
/*
* 这个类实现了一个类似于树的二维链接的跳跃列表,其中索引级别由不同于持有数据的
* 基本节点的单独节点表示。
* 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
* 1、基于数组的实现似乎会遇到更多的复杂性和开销
* structure: 1) Array based implementations seem to encounter
* 2、我们可以使用比基链表更便宜的算法来遍历索引链表。
* more complexity and overhead 2) We can use cheaper algorithms
* for the heavily-traversed index lists than can be used for the
* 这里是一些基本的图片为一个可能的列表,有2级的索引:
* 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
* +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
*
* 基本列表使用HM链接有序set算法的变体。
* The base lists use a variant of the HM linked ordered set
* 参见Tim Harris的“非阻塞链表的实用实现”和Maged Michael的“高性能动态无锁哈希表
* 和基于列表的集合”。
* algorithm. See Tim Harris, "A pragmatic implementation of
* non-blocking linked lists"
* http://www.cl.cam.ac.uk/~tlh20/publications.html and Maged
* Michael "High Performance Dynamic Lock-Free Hash Tables and
* List-Based Sets"
* http://www.research.ibm.com/people/m/michael/pubs.htm. The
* 这些列表的基本思想是在删除时标记被删除节点的“next”指针,以避免与并发插入发生冲突,
* 并在遍历时跟踪三元组(predecessor、node、successor),以检测何时以及如何断开这些
* 被删除节点的链接。
* 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.
*
* 节点使用直接的CAS'able next指针,而不是使用标记位来标记列表删除(使用
* AtomicMarkedReference可能会很慢而且占用大量空间)。
* 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 (indicating this by
* using otherwise impossible field values). Using plain nodes
* 使用普通节点的行为类似于标记指针的“boxed”实现,但是仅在删除节点时才
* 使用新节点,而不是针对每个链接。
* 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
* 即使jvm更好地支持标记的引用,使用这种技术的遍历仍然可能更快,因为与其他方法相比,
* 任何搜索只需要多读取一个节点(检查tailing标记),而不是在每次读取时解除标记位或其他内容。
* 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.
*
* 这种方法保留了HM算法中更改已删除节点的next指针所需要的基本属性,因此它的任何其他CAS都将失败,
* 但是通过将指针更改为指向另一个节点来实现这一思想,而不是通过标记它。
* 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, not by
* 虽然可以通过定义不具有key/value字段的标记节点来进一步压缩空间,但是不值得额外的类型测试开销。
* 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 and are
* normally quickly garbage collected. (Note that this technique
* would not work well in systems without garbage collection.)
*
* 除了使用删除标记外,列表还使用value字段的空值来表示删除,其风格类似于典型的延迟删除模式。
* 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,那么它在逻辑上被删除并被忽略,即使它仍然是可访问的。
* null, then it is considered logically deleted and ignored even
* though it is still reachable. This maintains proper control of
* 这维护了对并发替换vs删除操作的适当控制——如果delete通过空字段击败了试图进行的替换,则替换必须失败,
* 并且delete必须返回字段中最后一个非空值。
* concurrent replace vs delete operations -- an attempted replace
* must fail if a delete beat it by nulling field, and a delete
* must return the last non-null value held in the field. (Note:
* (注意:这里的值字段使用Null,而不是一些特殊的标记,因为它恰好符合Map API的要求,即如果没有映射,
* 方法get将返回Null,这允许节点在被删除时仍然保持并发的可读性。在这里使用任何其他标记值会更加混乱。)
* Null, rather than some special marker, is used for value fields
* here because it just so happens to mesh with the Map API
* requirement that method get returns null if there is no
* mapping, which allows nodes to remain concurrently readable
* even when deleted. Using any other marker value here would be
* messy at best.)
*
* 这是一个删除节点n带有前继节点b和后继节点f的最初节点顺序:
* Here's the sequence of events for a deletion of node n with
* predecessor b and successor f, initially:
*
* +------+ +------+ +------+
* ... | b |------>| n |----->| f | ...
* +------+ +------+ +------+
*
* 1、 CAS更新n 的value字段从非空到空。
* 1. CAS n's value field from non-null to null.
* 从此以后,遇到节点的公共操作都不会认为这个映射存在。
* From this point on, no public operations encountering
* the node consider this mapping to exist. However, other
* 但是,其他正在进行的插入和删除可能仍然会修改n的next指针。
* ongoing insertions and deletions might still modify
* n's next pointer.
*
* 2、CAS更新n 的next 指针,指向一个新的标记节点。
* 2. CAS n's next pointer to point to a new marker node.
* 从此以后,不能将任何其他节点追加到n。
* From this point on, no other nodes can be appended to n.
* 避免了在基于case的链表中删除错误。
* which avoids deletion errors in CAS-based linked lists.
*
* +------+ +------+ +------+ +------+
* ... | b |------>| n |----->|marker|------>| f | ...
* +------+ +------+ +------+ +------+
*
* 3、CAS更新b 的next 执行,跳过n 和它的标记节点。
* 3. CAS b's next pointer over both n and its marker.
* 从此以后,不会有新的遍历会遇到节点n,并且它终于可以被垃圾回收器回收。
* From this point on, no new traversals will encounter n,
* and it can eventually be GCed.
* +------+ +------+
* ... | b |----------------------------------->| f | ...
* +------+ +------+
*
* 由于与另一个操作的竞争失败,第1步的失败将导致简单的重试。
* A failure at step 1 leads to simple retry due to a lost race
* with another operation. Steps 2-3 can fail because some other
* 步骤2-3可能会失败,因为其他一些线程注意到在遍历具有null值的节点时,通过
* 标记 和/或 取消链接来帮助解决这个问题。
* thread noticed during a traversal a node with null value and
* helped out by marking and/or unlinking. This helping-out
* 这种帮助确保没有线程会因为等待删除线程的进程而卡住。
* ensures that no thread can become stuck waiting for progress of
* the deleting thread. The use of marker nodes slightly
* 使用标记节点使帮助代码略复杂,因为遍历必须跟踪四节点的读一致(b、n、marker、f),不仅(b、n、f),
* 虽然标记节点的next字段是不可变的,一旦next字段通过CAS执行一个标记节点,它再也不会改变,所以这需要
* 更少的关心。
* complicates helping-out code because traversals must track
* consistent reads of up to four nodes (b, n, marker, f), not
* just (b, n, f), although the next field of a marker is
* immutable, and once a next field is CAS'ed to point to a
* marker, it never again changes, so this requires less care.
*
* 跳跃列表将索引添加到这个方案中,这样,基本级别的遍历开始时就接近正在查找、插入或删除的位置
* ——通常基本级别的遍历只遍历几个节点。
* Skip lists add indexing to this scheme, so that the base-level
* traversals start close to the locations being found, inserted
* or deleted -- usually base level traversals only traverse a few
* 这不会改变基本算法,除了需要确保基本遍历从 没有(在结构上)被删除的前辈(这里是b)开始,
* 否则在处理删除后重试。
* nodes. This doesn't change the basic algorithm except for the
* need to make sure base traversals start at predecessors (here,
* b) that are not (structurally) deleted, otherwise retrying
* after processing the deletion.
*
* 索引级别保持为具有volatile next字段的列表,使用CAS进行链接和取消链接。
* Index levels are maintained as lists with volatile next fields,
* using CAS to link and unlink. Races are allowed in index-list
* 在索引列表操作中允许有竞争,这些操作可能(很少)在链接新索引节点或删除索引节点时失败。
* operations that can (rarely) fail to link in a new index node
* (当然,对于数据节点我们不能这样做。)
* or delete one. (We can't do this of course for data nodes.)
* 然而,即使发生这种情况,索引列表仍然是有序的,因此正确地作为索引。
* However, even when this happens, the index lists remain sorted,
* so correctly serve as indices. This can impact performance,
* 这可能会影响性能,但是由于跳跃表是概率性的,所以最终的结果是,在争用情况下,
* 有效的“p”值可能低于其名义值。
* but since skip lists are probabilistic anyway, the net result
* is that under contention, the effective "p" value may be lower
* than its nominal value. And race windows are kept small enough
* 并且竞争窗口被保持得足够小,以至于在实践中这些失败是很少见的,即使是在很多竞争的情况下。
* that in practice these failures are rare, even under a lot of
* contention.
*
* 由于建立索引,重试(对于基本列表和索引列表)相对便宜,这一事实允许对重试逻辑进行一些简单的简化。
* The fact that retries (for both base and index lists) are
* relatively cheap due to indexing allows some minor
* simplifications of retry logic. Traversal restarts are
* 遍历重新开始是在大多数“帮助” CAS之后执行的。
* performed after most "helping-out" CASes. This isn't always
* 这并不总是严格必要的,但是隐式的回退有助于减少其他下游失败的CAS,足以抵消重新启动的成本。
* strictly necessary, but the implicit backoffs tend to help
* reduce other downstream failed CAS's enough to outweigh restart
* 这恶化了最坏的情况,但似乎改善了高度竞争的情况。
* cost. This worsens the worst case, but seems to improve even
* highly contended cases.
*
* 与大多数跳转列表实现不同,这里的索引插入和删除需要在基本级操作之后进行
* 单独的遍历,以添加或删除索引节点。
* Unlike most skip-list implementations, index insertion and
* deletion here require a separate traversal pass occurring after
* the base-level action, to add or remove index nodes. This adds
* 这增加了单线程开销,但是通过缩小干扰窗口提高了争用多线程的性能,并允许删除,
* 以确保从公共删除操作返回时所有索引节点都是不可访问的,从而避免不必要的垃圾保留。
* to single-threaded overhead, but improves contended
* multithreaded performance by narrowing interference windows,
* and allows deletion to ensure that all index nodes will be made
* unreachable upon return from a public remove operation, thus
* avoiding unwanted garbage retention. This is more important
* 这在这里比在其他一些数据结构中更重要,因为我们不能取消引用用户键的节点字段,
* 因为它们仍然可能被其他正在进行的遍历读取。
* here than in some other data structures because we cannot null
* out node fields referencing user keys since they might still be
* read by other ongoing traversals.
*
* 索引使用跳跃表参数来保持良好的搜索性能,同时使用比通常更少的索引:固定的参数k=1, p=0.5
* (参见方法doPut)意味着大约四分之一的节点有索引。
* Indexing uses skip list parameters that maintain good search
* performance while using sparser-than-usual indices: The
* hardwired parameters k=1, p=0.5 (see method doPut) mean
* that about one-quarter of the nodes have indices. Of those that
* 其中,有一半的节点只有一个级别,四分之一的节点有两个级别,以此类推(参见Pugh的Skip List Cookbook,第3.4节)。
* do, half have one level, a quarter have two, and so on (see
* Pugh's Skip List Cookbook, sec 3.4). The expected total space
* 映射的预期总空间需求略小于java.util.TreeMap的当前实现。
* requirement for a map is slightly less than for the current
* implementation of java.util.TreeMap.
*
* 改变索引的级别(即,树状结构的高度)也是使用CAS。
* Changing the level of the index (i.e, the height of the
* tree-like structure) also uses CAS. The head index has initial
* head索引的初始水平/高度为1。
* level/height of one. Creation of an index with height greater
* 创建高度大于当前级别的索引将通过对新最顶部的头部进行CAS'ing向头部索引添加一个级别。
* than the current level adds a level to the head index by
* CAS'ing on a new top-most head. To maintain good performance
* 为了在大量删除之后保持良好的性能,删除方法尝试减少高度(如果最顶层接近空的)。
* after a lot of removals, deletion methods heuristically try to
* reduce the height if the topmost levels appear to be empty.
* 这可能会遇到可能(但很少)减少和“丢失”一个等级的冲突,就像它将要包含一个索引一样(这将永远不会被遇到)。
* This may encounter races in which it possible (but rare) to
* reduce and "lose" a level just as it is about to contain an
* index (that will then never be encountered). This does no
* 这不会造成结构性损害,而且在实践中,这似乎是比放任无限制增长更好的选择。
* structural harm, and in practice appears to be a better option
* than allowing unrestrained growth of levels.
*
* 所有这些的代码比您希望的更冗长。
* The code for all this is more verbose than you'd like. Most
* 大多数操作都需要定位一个元素(或插入元素的位置)。
* operations entail locating an element (or position to insert an
* element). The code to do this can't be nicely factored out
* 这样做的代码不能很好地分解出来,因为后续的使用需要前一个节点 和/或 后一个节点 和/或
* 值字段的快照,这些字段不能一次全部返回,至少在没有创建另一个对象来保存它们之前不能返回
* because subsequent uses require a snapshot of predecessor
* and/or successor and/or value fields which can't be returned
* all at once, at least not without creating yet another object
* 对于基本的内部搜索操作来说,创建这样的小对象是一个特别糟糕的主意,因为它增加了GC开销。
* to hold them -- creating such little objects is an especially
* bad idea for basic internal search operations because it adds
* to GC overhead. (This is one of the few times I've wished Java
* (这是我希望Java有宏的少数几次之一。)相反,一些遍历代码在插入和删除操作中交错。
* had macros.) Instead, some traversal code is interleaved within
* insertion and removal operations. The control logic to handle
* 处理所有重试条件的控制逻辑有时很复杂。
* all the retry conditions is sometimes twisty. Most search is
* 大多数搜索被分成两部分。findPredecessor()只搜索索引节点,返回键的基本级predecessor。
* findNode()完成了基本级的搜索。
* broken into 2 parts. findPredecessor() searches index nodes
* only, returning a base-level predecessor of the key. findNode()
* finishes out the base-level search. Even with this factoring,
* 即使使用这种分解方法,仍然有相当数量的近乎重复的代码来处理变量。
* there is a fair amount of near-duplication of code to handle
* variants.
*
* 为了在跨线程不干扰的情况下生成随机值,我们使用了jdk线程内部的本地随机支持(通过“secondary seed”,
* 以避免与用户级ThreadLocalRandom的干扰)。
* To produce random values without interference across threads,
* we use within-JDK thread local random support (via the
* "secondary seed", to avoid interference with user-level
* ThreadLocalRandom.)
*
* 这个类的先前版本将非comparable键与其比较器包装起来,以便在使用comparators时模拟Comparables。
* A previous version of this class wrapped non-comparable keys
* with their comparators to emulate Comparables when using
* comparators vs Comparables. However, JVMs now appear to better
* 但是,现在jvm似乎可以更好地将比comparator-vs-comparable的选择注入到搜索循环中。
* handle infusing comparator-vs-comparable choice into search
* 静态方法cpr(comparator,x, y)用于所有的比较,只要比较器参数设置在循环外部
* (因此有时作为参数传递给内部方法),就可以工作得很好,以避免字段重新读取。
* loops. Static method cpr(comparator, x, y) is used for all
* comparisons, which works well as long as the comparator
* argument is set up outside of loops (thus sometimes passed as
* an argument to internal methods) to avoid field re-reads.
*
* 要了解与此算法至少共享两个特征的算法,请参阅米哈伊尔·富米切夫的论文、基尔·弗雷泽的论文和哈坎·桑德尔的论文
* For explanation of algorithms sharing at least a couple of
* features with this one, see Mikhail Fomitchev's thesis
* (http://www.cs.yorku.ca/~mikhail/), Keir Fraser's thesis
* (http://www.cl.cam.ac.uk/users/kaf24/), and Hakan Sundell's
* thesis (http://www.cs.chalmers.se/~phs/).
*
* 由于使用了类似树的索引节点,您可能想知道为什么不使用某种搜索树来代替它,
* 搜索树支持更快的搜索操作。
* Given the use of tree-like index nodes, you might wonder why
* this doesn't use some kind of search tree instead, which would
* support somewhat faster search operations. The reason is that
* 原因是目前还没有有效的针对搜索树的无锁插入和删除算法。
* there are no known efficient lock-free insertion and deletion
* algorithms for search trees. The immutability of the "down"
* 索引节点的“down”链接的不变性(与true树中可变的“left”字段相反)使此操作仅使用CAS操作即可处理。
* links of index nodes (as opposed to mutable "left" fields in
* true trees) makes this tractable using only CAS operations.
*
* 本地变量的符号指南
* Notation guide for local variables
* Node: b, n, f for predecessor, node, successor
* Index: q, r, d for index node, right, down.
* t for another index node
* Head: h
* Levels: j
* Keys: k, key
* Values: v, value
* Comparisons: c
*/
private static final long serialVersionUID = -8627078645895051609L;
/**
* 用于标识基本级header的特殊值
* Special value used to identify base-level header
*/
private static final Object BASE_HEADER = new Object();
/**
* skiplist最顶端的索引。
* The topmost head index of the skiplist.
*/
private transient volatile HeadIndex<K, V> head;
/**
* The comparator used to maintain order in this map, or null if
* using natural ordering. (Non-private to simplify access in
* nested classes.)
*
* @serial
*/
final Comparator<? super K> comparator;
/**
* 延迟初始化keySet
* Lazily initialized key set
*/
private transient KeySet<K> keySet;
/**
* 延迟初始化 entry 集合
* Lazily initialized entry set
*/
private transient EntrySet<K, V> entrySet;
/**
* 延迟初始化value 集合
* Lazily initialized values collection
*/
private transient Values<V> values;
/**
* 延迟初始化降序 key 集合
* Lazily initialized descending key set
*/
private transient ConcurrentNavigableMap<K, V> descendingMap;
/**
* 初始化或重置状态。构造方法、clone、clear、readObject 以及ConcurrentSkipListSet.clone 需要这个方法。
* Initializes or resets state. Needed by constructors, clone,
* clear, readObject. and ConcurrentSkipListSet.clone.
* (注意,comparator需要单独被初始化)
* (Note that comparator must be separately initialized.)
*/
private void initialize() {
keySet = null;
entrySet = null;
values = null;
descendingMap = null;
// 初始化head 节点, Node的value 值不能为null,null表示该Node已被删除
head = new HeadIndex<K, V>(new Node<K, V>(null, BASE_HEADER, null),
null, null, 1);
}
/**
* compareAndSet head node
*/
private boolean casHead(HeadIndex<K, V> cmp, HeadIndex<K, V> val) {
return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
}
/* ---------------- Nodes -------------- */
/**
* 节点持有key和value,并按排序顺序单向链接,可能中间有一些介入标记节点。
* Nodes hold keys and values, and are singly linked in sorted
* order, possibly with some intervening marker nodes. The list is
* 该列表由一个可以作为head.node访问的虚拟节点作为头节点。
* headed by a dummy node accessible as head.node. The value field
* 值字段只声明为Object,因为它为标记和头节点接受特殊的非V 值。
* is declared only as Object because it takes special non-V
* values for marker and header nodes.
*/
static final class Node<K, V> {
final K key;
volatile Object value;
volatile Node<K, V> next;
/**
* 创建一个新的普通节点。
* Creates a new regular node.
*/
Node(K key, Object value, Node<K, V> next) {
this.key = key;
this.value = value;
this.next = next;
}
/**
* 创建一个新的标记节点。标记的区别在于它的值字段指向自身。
* Creates a new marker node. A marker is distinguished by
* having its value field point to itself. Marker nodes also
* 标记节点也有null键,有几个地方利用了这一事实,但这并不能将标记节点与基本级别的头节点(head.node)区分开来,
* 后者也有一个null键。
* have null keys, a fact that is exploited in a few places,
* but this doesn't distinguish markers from the base-level
* header node (head.node), which also has a null key.
*/
Node(Node<K, V> next) {
this.key = null;
this.value = this;
this.next = next;
}
/**
* CAS value 字段
* compareAndSet value field
*/
boolean casValue(Object cmp, Object val) {
return UNSAFE.compareAndSwapObject(this, valueOffset, cmp, val);
}
/**
* CAS next 字段
* compareAndSet next field
*/
boolean casNext(Node<K, V> cmp, Node<K, V> val) {
return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
}
/**
* 如果这个节点时一个标记节点,返回true。
* Returns true if this node is a marker. This method isn't
* 这个方法实际上并没有在当前的任何代码用来检查标记节点中被调用,因为调用者已经读取了值字段,
* 并且需要使用这个读操作(这里没有另一个操作),所以直接测试值是否指向node。
* actually called in any current code checking for markers
* because callers will have already read value field and need
* to use that read (not another done here) and so directly
* test if value points to node.
*
* @return true if this node is a marker node
*/
boolean isMarker() {
return value == this;
}
/**
* 如果此节点是基本级列表的header,则返回true。
* Returns true if this node is the header of base-level list.
*
* @return true if this node is header node
*/
boolean isBaseHeader() {
return value == BASE_HEADER;
}
/**
* 尝试追加删除标记节点到这个node.
* Tries to append a deletion marker to this node.
*
* @param f the assumed current successor of this node
* @return true if successful
*/
boolean appendMarker(Node<K, V> f) {
// new Node<K, V>(f) 创建删除标记节点, value = this, next = f
return casNext(f, new Node<K, V>(f));
}
/**
* 通过添加标记节点或从前一个节点断开链接来帮助删除。
* Helps out a deletion by appending marker or unlinking from
* 当value字段为null时,在遍历过程中调用此函数。
* predecessor. This is called during traversals when value
* field seen to be null.
*
* @param b predecessor
* @param f successor
*/
// b -> this 的前一个节点 f -> this 的后一个节点
// 帮助删除节点,需要分两个步骤: 1、插入删除标记节点 2、删除节点n 和标记节点. 每次调用只会执行一个步骤
void helpDelete(Node<K, V> b, Node<K, V> f) {
/*
* 重新检查链接,然后在每次调用时只执行一个帮助步骤,可以尽量减少帮助线程之间的CAS干扰。
* Rechecking links and then doing only one of the
* help-out stages per call tends to minimize CAS
* interference among helping threads.
*/
// 判断三节点是否一致 (判断f是否是this的后一个节点, b 是否是this 的前一个节点)
if (f == next && this == b.next) {
// 后面没有节点了 || 后一个节点不是标记节点
if (f == null || f.value != f) // not already marked 还未标记 (还未插入标记节点)
// new Node<K, V>(f) 创建一个标记节点 -> value = this , next = f
// CAS 更新next 为新创建的标记节点
casNext(f, new Node<K, V>(f));
else
// CAS更新前一个节点的next字段,跳过 this 和 标记节点
b.casNext(this, f.next);
}
}
/**
* 如果此节点包含有效的key-value对,则返回value,否则为空。
* Returns value if this node contains a valid key-value pair,
* else null.
*
* 如果这个节点不是标记节点、header,或已经被删除,则返回节点的value,否则返回null
* @return this node's value if it isn't a marker or header or
* is deleted, else null
*/
V getValidValue() {
Object v = value;
// v == this 说明是一个删除标记节点
// v == BASE_HEADER 说明是header 节点
if (v == this || v == BASE_HEADER)
return null;
// 如果该节点已经删除,那么v = null,返回结果也是null 值
@SuppressWarnings("unchecked") V vv = (V) v;
return vv;
}
/**
* 创建并返回一个持有当前映射的新的SimpleImmutableEntry(如果这个节点持有有效值,否则返回null)
* Creates and returns a new SimpleImmutableEntry holding current
* mapping if this node holds a valid value, else null.
*
* @return new entry or null
*/
AbstractMap.SimpleImmutableEntry<K, V> createSnapshot() {
Object v = value;
// 如果节点已经删除,或者是删除标记节点,或者是header节点,则此节点无效,返回null
if (v == null || v == this || v == BASE_HEADER)
return null;
@SuppressWarnings("unchecked") V vv = (V) v;
// 将key 和 value 封装到SimpleImmutableEntry,然后返回
return new AbstractMap.SimpleImmutableEntry<K, V>(key, vv);
}
// UNSAFE mechanics
private static final sun.misc.Unsafe UNSAFE;
private static final long valueOffset;
private static final long nextOffset;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> k = Node.class;
valueOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("value"));
nextOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("next"));
} catch (Exception e) {
throw new Error(e);
}
}
}
/* ---------------- Indexing -------------- */
/**
* 索引节点表示跳跃列表的级别。请注意,尽管Node和Index都有向前指向的字段,
* 但它们具有不同的类型,处理方式也不同,因此不能通过将字段放在共享抽象类中
* 来很好地捕获它们。
* Index nodes represent the levels of the skip list. Note that
* even though both Nodes and Indexes have forward-pointing
* fields, they have different types and are handled in different
* ways, that can't nicely be captured by placing field in a
* shared abstract class.
*/
static class Index<K, V> {
final Node<K, V> node;
final Index<K, V> down;
volatile Index<K, V> right;
/**
* 使用给定的值创建索引节点
* Creates index node with given values.
*/
Index(Node<K, V> node, Index<K, V> down, Index<K, V> right) {
this.node = node;
this.down = down;
this.right = right;
}
/**
* CAS right 字段
* compareAndSet right field
*/
final boolean casRight(Index<K, V> cmp, Index<K, V> val) {
return UNSAFE.compareAndSwapObject(this, rightOffset, cmp, val);
}
/**
* 如果此索引的节点已被删除,则返回true。
* Returns true if the node this indexes has been deleted.
*
* @return true if indexed node is known to be deleted
*/
final boolean indexesDeletedNode() {
return node.value == null;
}
/**
* 尝试CAS newSucc作为后继节点。
* Tries to CAS newSucc as successor. To minimize races with
* 为了最小化可能丢失此索引节点的解除链接的竞争,如果已知被索引的节点已被删除,
* 则它不会尝试进行链接。
* unlink that may lose this index node, if the node being
* indexed is known to be deleted, it doesn't try to link in.
*
* @param succ the expected current successor
* @param newSucc the new successor
* @return true if successful
*/
final boolean link(Index<K, V> succ, Index<K, V> newSucc) {
Node<K, V> n = node;
// 新的后继节点的右节点为旧的后继节点
newSucc.right = succ;
// 如果已知被索引的节点已被删除, 则它不会尝试进行链接。
// CAS更新right
return n.value != null && casRight(succ, newSucc);
}
/**
* 尝试CAS right 字段跳过明显的后继节点succ。
* Tries to CAS right field to skip over apparent successor
* succ. Fails (forcing a retraversal by caller) if this node
* 如果已知此节点已被删除,则失败(强制调用者重新遍历)。
* is known to be deleted.
*
* @param succ the expected current successor
* @return true if successful
*/
final boolean unlink(Index<K, V> succ) {
// node.value != null 判断node 节点未被删除(最小化竞争,如果该索引节点在这时候被删除了,
// 则修改该索引节点的right 也不会影响索引列表)
// CAS 修改right 字段
return node.value != null && casRight(succ, succ.right);
}
// Unsafe mechanics
private static final sun.misc.Unsafe UNSAFE;
private static final long rightOffset;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> k = Index.class;
rightOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("right"));
} catch (Exception e) {
throw new Error(e);
}
}
}
/* ---------------- Head nodes -------------- */
/**
* 每个层的head节点跟踪它们的层级。
* Nodes heading each level keep track of their level.
*/
static final class HeadIndex<K, V> extends Index<K, V> {
final int level;
HeadIndex(Node<K, V> node, Index<K, V> down, Index<K, V> right, int level) {
super(node, down, right);
this.level = level;
}
}
/* ---------------- Comparison utilities -------------- */
/**
* 使用comparator 进行比较,或者comparator 为null,比较自然顺序。
* Compares using comparator or natural ordering if null.
* 仅由已执行所需类型检查的方法调用。
* Called only by methods that have performed required type checks.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
static final int cpr(Comparator c, Object x, Object y) {
return (c != null) ? c.compare(x, y) : ((Comparable) x).compareTo(y);
}
/* ---------------- Traversal -------------- */
/**
* 返回一个键值严格小于给定键值的基本级节点(索引节点上的数据节点),如果没有这样的节点,则返回基本级header节点。
* Returns a base-level node with key strictly less than given key,
* or the base-level header if there is no such node. Also
* 并且解除沿途发现的已删除节点的索引链接。
* unlinks indexes to deleted nodes found along the way. Callers
* 调用者依赖于清除到删除节点的索引的副作用。
* rely on this side-effect of clearing indices to deleted nodes.
*
* @param key the key
* @return a predecessor of key
*/
// 如果只有head 一个节点,那么返回 head.node
// 查找小于key 的索引节点上的数据节点,并删除无效的索引节点
private Node<K, V> findPredecessor(Object key, Comparator<? super K> cmp) {
if (key == null)
throw new NullPointerException(); // don't postpone errors 不要推迟错误
for (; ; ) {
// q, r, d -> index node, right, down.
for (Index<K, V> q = head, r = q.right, d; ; ) {
if (r != null) {
Node<K, V> n = r.node;
K k = n.key;
// n.value == null 说明n 节点已被删除,索引无效
if (n.value == null) {
if (!q.unlink(r))
// 如果删除r 索引失败,那么重新遍历 (在实践中这些失败是很少见的)
break; // restart 重新遍历
// 读取下一个索引节点
r = q.right; // reread r 重新读取r
continue;
}
// 比较给定的key 值 和 该索引的k 值
if (cpr(cmp, key, k) > 0) {
// key 大于索引的k 值,继续查找下一个索引
q = r;
r = r.right;
continue;
}
}
// ---- q.node.key(可能是头节点) < key <= r.node.key ----
// 查找下一级索引
if ((d = q.down) == null)
// 达到最后一级索引,返回该索引的节点
// note: 这里返回的是q.node ,不是r.node (q.node.key(可能是头节点) < key)
return q.node;
// q 和 r 赋值为下一级索引的值
q = d;
r = d.right;
}
}
}
/**
* 返回持有key的节点,如果没有,则返回null,清除沿途看到的所有已删除节点。
* Returns node holding key or null if no such, clearing out any
* deleted nodes seen along the way. Repeatedly traverses at
* 从基本层级重复遍历,从findPredecessor返回的predecessor处开始查找key,
* 处理遇到的基级删除。
* base-level looking for key starting at predecessor returned
* from findPredecessor, processing base-level deletions as
* 一些调用者依赖于清除删除节点的副作用。
* encountered. Some callers rely on this side-effect of clearing
* deleted nodes.
* <p>
* 重新开始,如果在以节点n为中心的遍历步骤中:
* Restarts occur, at traversal step centered on node n, if:
* <p>
* (1)读取n的next字段后,n不再假设前一节点b的当前后继节点,这意味着我们没有一致的3节点快照,
* 因此无法取消遇到的任何后续删除节点的链接。
* (1) After reading n's next field, n is no longer assumed
* predecessor b's current successor, which means that
* we don't have a consistent 3-node snapshot and so cannot
* unlink any subsequent deleted nodes encountered.
* <p>
* (2) n的value字段为null,表示删除了n,在这种情况下,我们在重试之前帮助正在进行的结构删除。
* (2) n's value field is null, indicating n is deleted, in
* which case we help out an ongoing structural deletion
* before retrying. Even though there are cases where such
* 即使在某些情况下,这样的断开连接不需要重新启动,但在这里并没有对它们进行分类,
* 因为这样做通常不会超过重新启动的成本。
* unlinking doesn't require restart, they aren't sorted out
* here because doing so would not usually outweigh cost of
* restarting.
* <p>
* (3)n 是一个标记节点 或者n 的前一个节点的value字段是null,表示(在其他可能性中)
* findPredecessor返回已删除节点。
* (3) n is a marker or n's predecessor's value field is null,
* indicating (among other possibilities) that
* findPredecessor returned a deleted node. We can't unlink
* 我们无法解除这个节点的链接,因为我们不知道它的前一个节点,所以依赖于另一个对findPredecessor
* 的调用来通知并返回一些更早的前辈,它将这样做。
* the node because we don't know its predecessor, so rely
* on another call to findPredecessor to notice and return
* some earlier predecessor, which it will do. This check is
* 这种检查只在循环开始时才严格需要(而b.value检查根本不是严格需要的),
* 但是每次迭代都要进行检查,以帮助避免调用者与其他线程争用而无法更改链接,
* 因此无论如何都要重试。
* only strictly needed at beginning of loop, (and the
* b.value check isn't strictly needed at all) but is done
* each iteration to help avoid contention with other
* threads by callers that will fail to be able to change
* links, and so will retry anyway.
* <p>
* doPut、doRemove和findNear中的遍历循环都包含这相同的三种检查。
* The traversal loops in doPut, doRemove, and findNear all
* include the same three kinds of checks. And specialized
* 专门化版本出现在findFirst和findLast及其变体中。
* versions appear in findFirst, and findLast and their
* 它们不能很容易地共享代码,因为每一个都使用了本地字段的读操作,这些读操作
* 按照它们执行的顺序发生。
* variants. They can't easily share code because each uses the
* reads of fields held in locals occurring in the orders they
* were performed.
*
* @param key the key
* @return node holding key, or null if no such
*/
// 返回持有key的节点,如果没有,则返回null,清除沿途看到的所有已删除节点。
private Node<K, V> findNode(Object key) {
if (key == null)
throw new NullPointerException(); // don't postpone errors 不要延迟错误的抛出
Comparator<? super K> cmp = comparator;
outer:
for (; ; ) {
// b, n, f -> predecessor, node, successor
// findPredecessor 会删除无效的索引节点
for (Node<K, V> b = findPredecessor(key, cmp), n = b.next; ; ) {
Object v;
int c;
// 没有下一个节点了,结束外循环
if (n == null)
break outer;
Node<K, V> f = n.next;
if (n != b.next) // inconsistent read 不一致的读
// 重新开始
break;
if ((v = n.value) == null) { // n is deleted n 已经删除
// 帮助删除节点,需要分两个步骤: 1、插入标记节点 2、删除节点n 和标记节点。
// 每次调用只会执行一个步骤
n.helpDelete(b, f);
break; // 重新开始
}
// v == n -> n.value == n 即n 是标记节点
// b.next 是一个标记节点,说明b 节点已经删除了
if (b.value == null || v == n) // b is deleted b 已经删除
break;
if ((c = cpr(cmp, key, n.key)) == 0)
// 找到目标节点,返回
return n;
// key < n.key 说明key 不存在,结束循环,返回null
if (c < 0)
break outer;
// 遍历下一个节点
b = n;
n = f;
}
}
return null;
}
/**
* 使用key 获取value。与findNode几乎相同,但返回找到的值(以避免在重新读取期间重试)
* Gets value for key. Almost the same as findNode, but returns
* the found value (to avoid retries during re-reads)
*
* @param key the key
* @return the value, or null if absent
*/
private V doGet(Object key) {
if (key == null)
throw new NullPointerException();
Comparator<? super K> cmp = comparator;
outer:
for (; ; ) {
// b, n, f -> predecessor, node, successor
// findPredecessor 会删除无效的索引节点
for (Node<K, V> b = findPredecessor(key, cmp), n = b.next; ; ) {
Object v;
int c;
// 没有下一个节点了,结束外循环,返回null
if (n == null)
break outer;
Node<K, V> f = n.next;
if (n != b.next) // inconsistent read 不一致的读
// 重新开始
break;
if ((v = n.value) == null) { // n is deleted n 已经删除
// 帮助删除节点,需要分两个步骤: 1、插入标记节点 2、删除节点n 和标记节点。
// 每次调用只会执行一个步骤
n.helpDelete(b, f);
break; // 重新开始
}
// v == n -> n.value == n 即n 是标记节点
// b.next 是一个标记节点,说明b 节点已经删除了
if (b.value == null || v == n) // b is deleted b 已经删除
break;
if ((c = cpr(cmp, key, n.key)) == 0) {
// 找目标节点,返回目标节点的值
@SuppressWarnings("unchecked") V vv = (V) v;
return vv;
}
// key < n.key 说明key 不存在,结束循环,返回null
if (c < 0)
break outer;
// 比较下一个节点
b = n;
n = f;
}
}
return null;
}
/* ---------------- Insertion -------------- */
/**
* 主要的插入方法。如果不存在则添加元素,如果存在并且onlyIfAbsent 为false,则替换值。
* Main insertion method. Adds element if not present, or
* replaces value if present and onlyIfAbsent is false.
*
* @param key the key
* @param value the value that must be associated with key
* @param onlyIfAbsent if should not insert if already present
*
* 返回旧的值,如果是新插入的,返回null
* @return the old value, or null if newly inserted
*/
private V doPut(K key, V value, boolean onlyIfAbsent) {
Node<K, V> z; // added node 添加的节点
if (key == null)
throw new NullPointerException();
Comparator<? super K> cmp = comparator;
outer:
for (; ; ) {
// b, n, f -> predecessor, node, successor
// findPredecessor()返回小于key 的基本级节点
for (Node<K, V> b = findPredecessor(key, cmp), n = b.next; ; ) {
if (n != null) {
Object v;
int c;
Node<K, V> f = n.next;
if (n != b.next) // inconsistent read 不一致读
// 重新开始
break;
if ((v = n.value) == null) { // n is deleted n 节点已经删除了
// 帮助删除节点,需要分两个步骤: 1、插入标记节点 2、删除节点n 和标记节点.
// 每次调用只会执行一个步骤
n.helpDelete(b, f);
break; // 从新开始
}
// v == n -> n.value == n 即n 是标记节点
// b.next 是一个标记节点,说明b 节点已经删除了
if (b.value == null || v == n) // b is deleted b 节点已经删除
break;
// key > n.key
if ((c = cpr(cmp, key, n.key)) > 0) {
// 比较下一个节点
b = n;
n = f;
continue;
}
// key 已经存在
if (c == 0) {
// 如果onlyIfAbsent = true,则不会进行替换值操作
if (onlyIfAbsent || n.casValue(v, value)) {
@SuppressWarnings("unchecked") V vv = (V) v;
// 返回旧值
return vv;
}
// 如果替换值竞争失败,重新开始
break; // restart if lost race to replace value
}
// else c < 0, 即 b.key < key < n.key 将key追加到b 节点的后面
// else c < 0; fall through
}
// K key, Object value, Node<K, V> next
z = new Node<K, V>(key, value, n);
// CAS修改 b的 next 节点为 z
if (!b.casNext(n, z))
// 如果追加到b 节点后面竞争失败,那么重新开始
break; // restart if lost race to append to b
// 追加成功,结束外部循环
break outer;
}
}
// --------- outer end 下面为添加索引节点操作 --------------
/*
* Head nodes Index nodes
* +-+ right +-+ +-+
* |2|---------------->| |--------------------->| |->null ===> 2 是level
* +-+ +-+ +-+
* | 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 ==> 第一个节点是虚假节点,不保存数据
* +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
*
*/
// 获取线程的threadLocalRandomSecondarySeed 值
int rnd = ThreadLocalRandom.nextSecondarySeed();
// 0x80000001 -> 0100 0000 0000 0000 0000 0000 0000 0001
// 判断第一位和第31位的值是否是0
if ((rnd & 0x80000001) == 0) { // test highest and lowest bits 测试最高位和最低位的值
int level = 1, max;
// rnd = rnd >>> 1, 判断 rnd 从第二位开始有连续几个1
while (((rnd >>>= 1) & 1) != 0)
++level;
Index<K, V> idx = null;
HeadIndex<K, V> h = head;
if (level <= (max = h.level)) {
// note: 索引节点只从1 创建到level 层级
for (int i = 1; i <= level; ++i)
// z 为此次插入的新节点
// Node<K, V> node, Index<K, V> down, Index<K, V> right
// 循环创建索引节点,down 为 idx (第一级down 为null)
idx = new Index<K, V>(z, idx, null);
} else { // try to grow by one level 尝试增长一个层级
// ------ level > h.level -----
level = max + 1; // hold in array and later pick the one to use 在数组中保持,然后选择要使用的一个
// 长度为level + 1, 索引0没有存数据
@SuppressWarnings("unchecked") Index<K, V>[] idxs =
(Index<K, V>[]) new Index<?, ?>[level + 1];
for (int i = 1; i <= level; ++i)
// z 为此次插入的新节点
// Node<K, V> node, Index<K, V> down, Index<K, V> right
// 循环创建索引节点,down 为 idx
idxs[i] = idx = new Index<K, V>(z, idx, null);
for (; ; ) {
h = head;
int oldLevel = h.level;
if (level <= oldLevel) // lost race to add level 增长层级竞争失败
// 另一个线程已经增长层级了,结束循环,不用更新head,但还是会插入索引节点idx
break;
HeadIndex<K, V> newh = h;
Node<K, V> oldbase = h.node;
// 并发下可能层级会减少,即此时 h.level < max,所以需要循环创建 HeadIndex
// 从head.level + 1 层级开始创建HeadIndex,直到level 层级
for (int j = oldLevel + 1; j <= level; ++j)
// Node<K, V> node, Index<K, V> down, Index<K, V> right, int level
// 原head 节点成为新节点down 节点
newh = new HeadIndex<K, V>(oldbase, newh, idxs[j], j);
// 更新head 节点,层级增长 (新的层级没有其他节点,因此更新head 即可)
if (casHead(h, newh)) {
// newh 赋值给h,下面还会用到h
h = newh;
// level = oldLevel, idx = idxs[oldLevel], 从oldLevel 层级开始插入索引节点
// (并不是从新的层级开始插入索引节点)
idx = idxs[level = oldLevel];
break;
}
}
}
// 找到插入点并进行拼接
// find insertion points and splice in
splice:
for (int insertionLevel = level; ; ) { // 逐级进行插入
int j = h.level;
// idx 为要插入的索引节点的顶级索引节点
for (Index<K, V> q = h, r = q.right, t = idx; ; ) {
// q == null 说明已经达到索引的最底层
// t == null 说明已经达到索引的最底层 或者 没有要插入的索引节点(比如:增长层级竞争失败)
if (q == null || t == null)
break splice;
if (r != null) {
Node<K, V> n = r.node;
// 检查删除前比较,避免需要重新检查 (比较后还需检查节点是否已经删除)
// compare before deletion check avoids needing recheck
int c = cpr(cmp, key, n.key);
// n.value == null 说明n 节点已经删除了
if (n.value == null) {
if (!q.unlink(r))
// 跳出内循环,重新开始(但是是从insertionLevel 才会开始插入)
break;
// 删除索引节点成功,读取新的r
r = q.right;
continue;
}
// c > 0 说明 key > n.key ,即要插入的索引节点在r 的右边
if (c > 0) {
// 向右前进一个节点,继续判断索引节点的插入位置
q = r;
r = r.right;
continue;
}
}
// ---- r == null || q.node.key(可能是头节点) < key <= r.node.key ---
// 判断该索引节点是否是当前要插入的索引节点 (有可能已经插入过了,即 j > insertionLevel)
if (j == insertionLevel) {
// 把索引节点t 追加到q 的后面
if (!q.link(r, t))
// 竞争失败,重新开始
break; // restart
// 若索引节点对应的节点已经删除了,则该索引节点无效已经无效了
// 帮助删除无效的索引节点,然后退出外部循环
if (t.node.value == null) {
// 删除查找key沿途看到的已删除的节点 (主要目的:1、删除前面已经插入的索引节点t
// 2、删除节点插入的节点z)
findNode(key);
break splice;
}
// 插入成功 insertionLevel - 1,若 insertionLevel = 0则表示插入索引节点完全,
// 跳出外部循环
if (--insertionLevel == 0)
break splice;
}
// insertionLevel 是下一次要插入索引节点的层级
if (--j >= insertionLevel && j < level)
// 获取下一级要插入的索引节点
t = t.down;
// 获取下一级索引节点
q = q.down;
r = q.right;
}
}
}
return null;
}
/* ---------------- Deletion -------------- */
/**
* 主要删除方法。定位节点、设置value为null、追加删除标记节点、取消前一个节点链接、
* 删除相关索引节点,并可能降低head索引级别。
* Main deletion method. Locates node, nulls value, appends a
* deletion marker, unlinks predecessor, removes associated index
* nodes, and possibly reduces head index level.
* <p>
* 只需调用findPredecessor就可以清除索引节点。
* Index nodes are cleared out simply by calling findPredecessor.
* 它将索引解链接到沿着索引到 key找到的已删除节点,其中将包括到此节点的索引。
* which unlinks indexes to deleted nodes found along path to key,
* which will include the indexes to this node. This is done
* 这是无条件的。我们不能预先检查是否有索引节点,因为在对该节点进行初始搜索时,
* 可能还没有为该节点插入部分或全部索引,而且我们希望确保没有垃圾保留,因此必须调用来确定。
* unconditionally. We can't check beforehand whether there are
* index nodes because it might be the case that some or all
* indexes hadn't been inserted yet for this node during initial
* search for it, and we'd like to ensure lack of garbage
* retention, so must call to be sure.
*
* @param key the key
* 如果非null,value 必须和key 关联
* @param value if non-null, the value that must be
* associated with key
* @return the node, or null if not found
*/
final V doRemove(Object key, Object value) {
if (key == null)
throw new NullPointerException();
Comparator<? super K> cmp = comparator;
outer:
for (; ; ) {
// 查找小于key 的索引节点上的数据节点,并删除无效的索引节点
for (Node<K, V> b = findPredecessor(key, cmp), n = b.next; ; ) {
Object v;
int c;
// 没有下一个节点了,结束循环,返回null
if (n == null)
break outer;
Node<K, V> f = n.next;
if (n != b.next) // inconsistent read 不一致的读
// 重新开始
break;
if ((v = n.value) == null) { // n is deleted n 已经删除
// 帮助删除节点,需要分两个步骤: 1、插入标记节点 2、删除节点n 和标记节点。
// 每次调用只会执行一个步骤
n.helpDelete(b, f);
break;
}
// v == n -> n.value == n 即n 是标记节点
// b.next 是一个标记节点,说明b 节点已经删除了
if (b.value == null || v == n) // b is deleted b 已经删除
break;
// key < n.key 说明key 不存在
if ((c = cpr(cmp, key, n.key)) < 0)
break outer;
// key > n.key
if (c > 0) {
// 比较下一个节点
b = n;
n = f;
continue;
}
// ---- key == n.key -----
// 如果value != null,那么节点映射的值必须等于value,否则不进行任何操作
if (value != null && !value.equals(v))
break outer;
// CAS 更新value 为null
if (!n.casValue(v, null))
// CAS竞争失败,重新开始
break;
// n.appendMarker() -> n节点追加删除标记节点(表示不能再追加其他节点)
// b.casNext(n, f) -> CAS更新b 节点(n的前一个节点)的next 为f
if (!n.appendMarker(f) || !b.casNext(n, f))
// 已经通过CAS 修改value 为null,逻辑上已经成功将n 节点删除了,但是结构上由于竞争删除失败,
// 通过findNode 尝试从结构上删除n 节点
findNode(key); // retry via findNode 通过findNode 重试
else {
// 删除索引节点 (依赖于清除到删除节点的索引的副作用)
findPredecessor(key, cmp); // clean index 删除索引节点
// 如果最上级的索引节点没有右节点,那么尝试降低层级 (提高层级时,只会往原来已有的层级上插入索引节点,
// 新增长的层级不会立即插入索引节点)
if (head.right == null)
// 尝试降低层级 (只有最上面的三级是空的,才会降低层级)
tryReduceLevel();
}
// 返回key 原来映射的值
@SuppressWarnings("unchecked") V vv = (V) v;
return vv;
}
}
return null;
}
/**
* 如果head没有右节点,可能会降低head 层级。
* Possibly reduce head level if it has no nodes. This method can
* 此方法可能(很少)出错,在这种情况下,层级可能会消失,即使它们即将包含索引节点。
* (rarely) make mistakes, in which case levels can disappear even
* though they are about to contain index nodes. This impacts
* 这影响的是性能,而不是正确性。为了减少错误和迟滞,只有当最上面的三层看起来是空
* 的时候,这个级别才会减少一层。
* performance, not correctness. To minimize mistakes as well as
* to reduce hysteresis, the level is reduced by one only if the
* topmost three levels look empty. Also, if the removed level
* 另外,如果删除的级别在CAS之后看起来不是空的,我们会在任何人注意到我们的错误之前尽快将它更改回来!
* looks non-empty after CAS, we try to change it back quick
* before anyone notices our mistake! (This trick works pretty
* (这个技巧非常有效,因为这个方法实际上永远不会出错,除非当前线程在第一个CAS之前立即停止,
* 在这种情况下,它不太可能在CAS之后再次立即停止,所以会恢复。)
* well because this method will practically never make mistakes
* unless current thread stalls immediately before first CAS, in
* which case it is very unlikely to stall again immediately
* afterwards, so will recover.)
* <p>
* 我们容忍所有这一切,而不是仅仅让层级增长,因为否则,即使是一个小的map,即使经历了大量的插入和删除,
* 也会有大量的层级,比起偶尔不必要的减少,会减慢访问速度。
* We put up with all this rather than just let levels grow
* because otherwise, even a small map that has undergone a large
* number of insertions and removals will have a lot of levels,
* slowing down access more than would an occasional unwanted
* reduction.
*/
private void tryReduceLevel() {
HeadIndex<K, V> h = head;
HeadIndex<K, V> d;
HeadIndex<K, V> e;
// 为了减少错误和迟滞,只有当最上面的三层看起来是空的时候,这个级别才会减少一层。
if (h.level > 3 &&
(d = (HeadIndex<K, V>) h.down) != null &&
(e = (HeadIndex<K, V>) d.down) != null &&
e.right == null && // 索引节点的插入是从上(head)往下插入的,因此从下往上读取right,尽可能减少错误
d.right == null &&
h.right == null &&
casHead(h, d) && // try to set 尝试CAS 修改head 为d (下一级层级)
h.right != null) // recheck 重新检查
// 如果删除的级别在CAS之后看起来不是空的,我们会在任何人注意到我们的错误之前尽快将它更改回来!
// 删除的层级不会空,撤销删除
casHead(d, h); // try to backout 尝试撤回
}
// 查找和删除第一个元素
/* ---------------- Finding and removing first element -------------- */
/**
* findNode的特殊变体,以获得第一个有效节点。
* Specialized variant of findNode to get first valid node.
*
* @return first node or null if empty
*/
// 获取第一个有效的节点
final Node<K, V> findFirst() {
for (Node<K, V> b, n; ; ) {
if ((n = (b = head.node).next) == null)
// 此map 中没有有效节点,返回null
return null;
// 判断n 节点是否被删除了
if (n.value != null)
// n 节点没有被删除,返回
return n;
// 帮助删除节点,需要分两个步骤: 1、插入删除标记节点 2、删除节点n 和标记节点.
// 每次调用只会执行一个步骤
n.helpDelete(b, n.next);
}
}
/**
* 删除第一个entry,返回它的快照。
* Removes first entry; returns its snapshot.
*
* @return null if empty, else snapshot of first entry
*/
private Map.Entry<K, V> doRemoveFirstEntry() {
for (Node<K, V> b, n; ; ) {
// b = head.node , n = head.node.next
if ((n = (b = head.node).next) == null)
// 如果此map 为空,返回null
return null;
Node<K, V> f = n.next;
if (n != b.next) // 不一致的读
continue; // 重新开始
Object v = n.value;
if (v == null) { // n 已经删除
// 帮助删除节点,需要分两个步骤: 1、插入标记节点 2、删除节点n 和标记节点。
// 每次调用只会执行一个步骤
n.helpDelete(b, f);
continue; // 重新开始
}
// CAS 更新value 为null
if (!n.casValue(v, null))
// CAS竞争失败,重新开始
continue;
// --- CAS成功 ----
// appendMarker 追加删除标记节点
// CAS修改b.next 为f ,删除n 节点和标记节点
if (!n.appendMarker(f) || !b.casNext(n, f))
// 结构上删除失败,调用findFirst() 重试删除第一个节点
findFirst(); // retry
// 清除与已删除的第一个entry关联的索引节点 (清除每层head后的第一个已删除的索引节点)。
clearIndexToFirst();
@SuppressWarnings("unchecked") V vv = (V) v;
// 将key 和 value 封装到SimpleImmutableEntry 中 (不支持Entry.setValue 操作)
return new AbstractMap.SimpleImmutableEntry<K, V>(n.key, vv);
}
}
/**
* 清除与已删除的第一个entry关联的索引节点。
* Clears out index nodes associated with deleted first entry.
*/
// 清除每层head后的第一个已删除的索引节点
private void clearIndexToFirst() {
for (; ; ) {
for (Index<K, V> q = head; ; ) {
Index<K, V> r = q.right;
// r.indexesDeletedNode() 若索引的节点已被删除,则返回true
if (r != null && r.indexesDeletedNode() && !q.unlink(r))
// 索引节点r 已被删除,但是解除链接失败,重新从head开始
break;
// q = q.down,索引向下一层
if ((q = q.down) == null) {
// ---- 没有下一级索引节点了 ---
if (head.right == null)
// 尝试降低索引层级
tryReduceLevel();
return;
}
}
}
}
/**
* 删除最后一个entry;返回它的快照。
* Removes last entry; returns its snapshot.
* doRemove 的特殊版本。
* Specialized variant of doRemove.
*
* @return null if empty, else snapshot of last entry
*/
private Map.Entry<K, V> doRemoveLastEntry() {
for (; ; ) {
// 不直接查找最后一个数据节点是因为: 如果这个数据节点在返回后被删除了,则没办法在结构上帮助这个节点进行删除,
// 因为不知道它的前一个节点。
// 返回最后一个索引节点 或 倒数第二个索引节点(当最后一个索引节点上数据节点没有后继节点时) 上对应的数据节点
Node<K, V> b = findPredecessorOfLast();
Node<K, V> n = b.next;
if (n == null) {
// 判断b 是否是HeadIndex 上的节点
if (b.isBaseHeader()) // empty
// 此map 为空,返回null
return null;
else
// b 的所有后继节点都被删除了,重试
continue; // all b's successors are deleted; retry
}
for (; ; ) {
Node<K, V> f = n.next;
if (n != b.next) // inconsistent read 不一致的读
// 重新开始
break;
Object v = n.value;
if (v == null) { // n is deleted n 已经删除
// 帮助删除节点,需要分两个步骤: 1、插入标记节点 2、删除节点n 和标记节点。
// 每次调用只会执行一个步骤
n.helpDelete(b, f);
break;
}
// v == n -> n.value == n 即n 是标记节点
// b.next 是一个标记节点,说明b 节点已经删除了
if (b.value == null || v == n) // b is deleted b 已经删除
break;
// 还有后继节点
if (f != null) {
// 前进一个节点
b = n;
n = f;
continue;
}
// ---- n 是最后一个节点 -----
// CAS 更新value 为null
if (!n.casValue(v, null))
// CAS竞争失败,重新开始
break;
K key = n.key;
// n.appendMarker() -> n节点追加删除标记节点(表示不能再追加其他节点)
// b.casNext(n, f) -> CAS更新b 节点(n的前一个节点)的next 为f,删除节点n 和 标记节点
if (!n.appendMarker(f) || !b.casNext(n, f))
// 通过findNode 尝试从结构上删除n 节点
findNode(key); // retry via findNode
else { // clean index 清除索引
// 删除索引节点 (依赖于清除到删除节点的索引的副作用)
findPredecessor(key, comparator);
if (head.right == null)
// 尝试降低层级 (只有最上面的三级是空的,才会降低层级)
tryReduceLevel();
}
@SuppressWarnings("unchecked") V vv = (V) v;
// 将key 和 value 封装到SimpleImmutableEntry
return new AbstractMap.SimpleImmutableEntry<K, V>(key, vv);
}
}
}
/* ---------------- Finding and removing last element -------------- */
/**
* 查找的特殊版本,以获取最后一个有效节点。
* Specialized version of find to get last valid node.
*
* @return last node or null if empty
*/
// 查找最后一个有效节点
final Node<K, V> findLast() {
/*
* findPredecessor不能用于遍历索引级别,因为它不使用比较。
* findPredecessor can't be used to traverse index level
* because this doesn't use comparisons. So traversals of
* 因此,这两层的遍历是折叠在一起的。
* both levels are folded together.
*/
Index<K, V> q = head;
for (; ; ) {
Index<K, V> d, r;
// 判断right 是否为null (是否有右索引节点)
if ((r = q.right) != null) {
// indexesDeletedNode 如果此索引的节点已被删除,则返回true。
if (r.indexesDeletedNode()) {
// 解除索引节点r 的链接
q.unlink(r);
q = head; // restart 从head 重新开始
} else
q = r; // 前进一个索引节点
// 判断是否有下层索引节点
} else if ((d = q.down) != null) {
// 往下一层
q = d;
} else {
// --- 没有右索引节点,且已经到最底层的索引了 ---
for (Node<K, V> b = q.node, n = b.next; ; ) {
if (n == null)
// n == null,那么b 就是最后一个节点,判断b是否是head 节点,是则说明此map为空,返回null
return b.isBaseHeader() ? null : b;
Node<K, V> f = n.next; // inconsistent read
if (n != b.next) // 不一致的读
break; // 重新开始
Object v = n.value;
if (v == null) { // n is deleted n 已经删除
// 帮助删除节点,需要分两个步骤: 1、插入标记节点 2、删除节点n 和标记节点。
// 每次调用只会执行一个步骤
n.helpDelete(b, f);
break; // 重新开始
}
// v == n -> n.value == n 即n 是标记节点
// b.next 是一个标记节点,说明b 节点已经删除了
if (b.value == null || v == n) // b is deleted b 已经删除
break; // 重新开始
// 前进一个节点
b = n;
n = f;
}
// q 重置为head,继续从head 索引节点开始
q = head; // restart
}
}
}
/**
* findPredecessor的特殊版本,以获取最后一个有效节点的前一个节点。
* Specialized variant of findPredecessor to get predecessor of last
* 在删除最后一个entry时需要。有可能返回节点的所有后继节点在返回时都已被删除,
* 在这种情况下可以重试此方法。
* valid node. Needed when removing the last entry. It is possible
* that all successors of returned node will have been deleted upon
* return, in which case this method can be retried.
*
* @return likely predecessor of last node
*/
// 返回索引节点对应的数据节点 (1、q是最后一个索引节点 2、q是倒数第二个索引节点(当最后一个索引
// 节点上数据节点没有后继节点时))
// 不直接查找最后一个数据节点是因为: 如果这个数据节点在返回后被删除了,则没办法在结构上
// 帮助这个节点进行删除,因为不知道它的前一个节点。
private Node<K, V> findPredecessorOfLast() {
for (; ; ) {
for (Index<K, V> q = head; ; ) {
Index<K, V> d, r;
if ((r = q.right) != null) {
// indexesDeletedNode 如果此索引的节点已被删除,则返回true。
if (r.indexesDeletedNode()) {
// 解除索引节点r 的链接
q.unlink(r);
break; // must restart 必须重新开始
}
// 在没有超过的情况下,越远越好。
// proceed as far across as possible without overshooting
// 仅当右边的索引节点上数据节点还有后继节点的情况下,索引节点才会向右前进一个索引节点,
// 因此返回的节点一个有后继节点,除非所有的后继节点都被删除了,这种情况下可以重试此方法。
if (r.node.next != null) {
// 向右前进一个索引节点
q = r;
continue;
}
}
// 判断是否有下层索引节点
if ((d = q.down) != null)
// 往下一层
q = d;
else
// 返回索引节点对应的数据节点 (1、q是最后一个索引节点 2、q是倒数第二个索引节点(当最后一个索引
// 节点上数据节点没有后继节点时))
return q.node;
}
}
}
/* ---------------- Relational operations -------------- */
// Control values OR'ed as arguments to findNear
// EQ | GT = 1, 在这些应用中,不会单独使用EQ,EQ都是跟 LT / GT 组合使用的,因此 1 表示 >=
private static final int EQ = 1;
private static final int LT = 2;
private static final int GT = 0; // Actually checked as !LT 实际检查为 !LT
/**
* ceiling, floor, lower, higher 的通用方法。
* Utility for ceiling, floor, lower, higher methods.
*
* @param key the key
* 关系 -- EQ, LT, GT 进行OR 组合
* @param rel the relation -- OR'ed combination of EQ, LT, GT
* 满足关系的最接近节点,没有则返回null
* @return nearest node fitting relation, or null if no such
*/
final Node<K, V> findNear(K key, int rel, Comparator<? super K> cmp) {
if (key == null)
throw new NullPointerException();
for (; ; ) {
// 查找小于key 的索引节点上的数据节点,并删除无效的索引节点 (b.key < key)
for (Node<K, V> b = findPredecessor(key, cmp), n = b.next; ; ) {
Object v;
if (n == null)
// 1、(rel & LT) == 0 即 !LT,查找满足 b.key >= key 的最小节点,而此时b.key < key,所以返回null
// b.isBaseHeader() 判断b 是否是header节点,如果b 是header节点,且没有下一个节点,
// 那么说明此map 为空,返回null
// 2、如果是查找满足 b.key <= key 的最大节点,那么如果b 不是header 节点,那么返回b
return ((rel & LT) == 0 || b.isBaseHeader()) ? null : b;
Node<K, V> f = n.next;
if (n != b.next) // inconsistent read 不一致的读
// 重新开始
break;
if ((v = n.value) == null) { // n is deleted n 已经删除
// 帮助删除节点,需要分两个步骤: 1、插入标记节点 2、删除节点n 和标记节点。
// 每次调用只会执行一个步骤
n.helpDelete(b, f);
break; // 重新开始
}
// v == n -> n.value == n 即n 是标记节点
// b.next 是一个标记节点,说明b 节点已经删除了
if (b.value == null || v == n) // b is deleted b 已经删除
break;
int c = cpr(cmp, key, n.key);
// 1、 c == 0 即 key == n.key && (rel & EQ) != 0 即查找节点的键需要等于给定的key
// 2、 c < 0 即 key < n.key && (rel & LT) == 0 即 !LT,即查找节点的键需要大于或大于等于给定的key的最小节点
if ((c == 0 && (rel & EQ) != 0) ||
(c < 0 && (rel & LT) == 0))
// 返回 n.key >= key 的最小节点
return n;
// c <= 0 即 key <= n.key
// (rel & LT) != 0,即查找键小于或小于等于 key 的最大节点
if (c <= 0 && (rel & LT) != 0)
// 因为 n.key >= key,所以需要返回n的前一个节点b
// 判断前一个节点是否是有效节点,是则返回,否则返回null
return b.isBaseHeader() ? null : b; // 返回 n.key < key 的最大节点
// --- c > 0 ==> key > n.key 无论是要找比key 小的最大节点,还是要找比key 大的最小节点,都要比较下一个节点 ----
// 如果rel 是EQ的话,那么如果 c != 0,则会一直查找下去,直到最后一个节点,但是此应用中 rel不会单独使用EQ (相等应该使用findNode方法)
// 比较下一个节点
b = n;
n = f;
}
}
}
/**
* 为findNear的结果返回SimpleImmutableEntry。
* Returns SimpleImmutableEntry for results of findNear.
*
* @param key the key
* @param rel the relation -- OR'ed combination of EQ, LT, GT
* @return Entry fitting relation, or null if no such
*/
final AbstractMap.SimpleImmutableEntry<K, V> getNear(K key, int rel) {
Comparator<? super K> cmp = comparator;
for (; ; ) {
// 满足关系的最接近节点,没有则返回null
Node<K, V> n = findNear(key, rel, cmp);
if (n == null)
// 此map 为空,返回null
return null;
// 将key 和 value 封装到 SimpleImmutableEntry,若n 是无效节点,返回null
AbstractMap.SimpleImmutableEntry<K, V> e = n.createSnapshot();
if (e != null)
return e;
}
}
/* ---------------- Constructors -------------- */
/**
* 构造一个新的空map,该映射按照键的自然顺序进行排序。
* Constructs a new, empty map, sorted according to the
* {@linkplain Comparable natural ordering} of the keys.
*/
public ConcurrentSkipListMap() {
this.comparator = null;
initialize();
}
/**
* 构造一个新的空map,根据指定的comparator 进行排序。
* Constructs a new, empty map, sorted according to the specified
* comparator.
*
* @param comparator the comparator that will be used to order this map.
* If {@code null}, the {@linkplain Comparable natural
* ordering} of the keys will be used.
*/
public ConcurrentSkipListMap(Comparator<? super K> comparator) {
this.comparator = comparator;
initialize();
}
/**
* 构造一个新map,该map所包含的映射关系与给定map包含的映射关系相同,并按照键的自然顺序进行排序。
* Constructs a new map containing the same mappings as the given map,
* sorted according to the {@linkplain Comparable natural ordering} of
* the keys.
*
* @param m the map whose mappings are to be placed in this map
* @throws ClassCastException if the keys in {@code m} are not
* {@link Comparable}, or are not mutually comparable
* @throws NullPointerException if the specified map or any of its keys
* or values are null
*/
public ConcurrentSkipListMap(Map<? extends K, ? extends V> m) {
this.comparator = null;
initialize();
// 将m 中所有的映射关系放入此 map 中
putAll(m);
}
/**
* 构造一个新map,该map所包含的映射关系与指定的有序map包含的映射关系相同,使用的顺序也相同。
* Constructs a new map containing the same mappings and using the
* same ordering as the specified sorted map.
*
* @param m the sorted map whose mappings are to be placed in this
* map, and whose comparator is to be used to sort this map
* @throws NullPointerException if the specified sorted map or any of
* its keys or values are null
*/
public ConcurrentSkipListMap(SortedMap<K, ? extends V> m) {
this.comparator = m.comparator();
initialize();
buildFromSorted(m);
}
/**
* Returns a shallow copy of this {@code ConcurrentSkipListMap}
* instance. (The keys and values themselves are not cloned.)
*
* @return a shallow copy of this map
*/
public ConcurrentSkipListMap<K, V> clone() {
try {
@SuppressWarnings("unchecked")
ConcurrentSkipListMap<K, V> clone =
(ConcurrentSkipListMap<K, V>) super.clone();
clone.initialize();
clone.buildFromSorted(this);
return clone;
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
/**
* 流线型批量插入以从给定有序map的元素进行初始化。
* Streamlined bulk insertion to initialize from elements of
* 仅从构造方法或clone 方法调用。
* given sorted map. Call only from constructor or clone
* method.
*/
private void buildFromSorted(SortedMap<K, ? extends V> map) {
if (map == null)
throw new NullPointerException();
HeadIndex<K, V> h = head;
Node<K, V> basepred = h.node;
// 在每一层跟踪当前最右边的节点。
// Track the current rightmost node at each level. Uses an
// 使用ArrayList避免提交到初始级别或最大级别。
// ArrayList to avoid committing to initial or maximum level.
ArrayList<Index<K, V>> preds = new ArrayList<Index<K, V>>();
// 索引节点的层级是从1 开始,preds索引0也放入null元素,是为了使 preds.size == head.level,
// 从而每个层级的最后(最右边)一个索引节点使用 preds.get(level)获取即可
// initialize
for (int i = 0; i <= h.level; ++i)
preds.add(null);
Index<K, V> q = h;
for (int i = h.level; i > 0; --i) {
preds.set(i, q);
q = q.down;
}
Iterator<? extends Map.Entry<? extends K, ? extends V>> it =
map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<? extends K, ? extends V> e = it.next();
int rnd = ThreadLocalRandom.current().nextInt();
int j = 0;
// 判断第一位和第31位的值是否是0
if ((rnd & 0x80000001) == 0) {
do {
++j;
// rnd = rnd >>> 1, 判断 rnd 从第二位开始有连续几个1
} while (((rnd >>>= 1) & 1) != 0);
// 层级 + 1
if (j > h.level)
j = h.level + 1;
}
K k = e.getKey();
V v = e.getValue();
if (k == null || v == null)
throw new NullPointerException();
Node<K, V> z = new Node<K, V>(k, v, null);
// 将z节点追加到basepred 后面
basepred.next = z;
basepred = z;
// 创建索引节点
if (j > 0) {
Index<K, V> idx = null;
for (int i = 1; i <= j; ++i) {
// Node<K, V> node, Index<K, V> down, Index<K, V> right
idx = new Index<K, V>(z, idx, null);
if (i > h.level)
// 创建并保存head 索引节点
h = new HeadIndex<K, V>(h.node, h, idx, i);
if (i < preds.size()) {
// 将索引节点idx 追加到层级i
preds.get(i).right = idx;
// 更新层级i 的最后一个索引节点,用于下次追加索引节点
preds.set(i, idx);
} else
// 层级i 还没有索引节点,添加索引节点
preds.add(idx);
}
}
}
// 将h(HeadIndex) 索引节点赋值给head
head = h;
}
/* ---------------- Serialization -------------- */
/**
* Saves this map to a stream (that is, serializes it).
*
* @param s the stream
* @throws java.io.IOException if an I/O error occurs
* @serialData The key (Object) and value (Object) for each
* key-value mapping represented by the map, followed by
* {@code null}. The key-value mappings are emitted in key-order
* (as determined by the Comparator, or by the keys' natural
* ordering if no Comparator).
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// Write out the Comparator and any hidden stuff
s.defaultWriteObject();
// Write out keys and values (alternating)
for (Node<K, V> n = findFirst(); n != null; n = n.next) {
V v = n.getValidValue();
if (v != null) {
s.writeObject(n.key);
s.writeObject(v);
}
}
s.writeObject(null);
}
/**
* Reconstitutes this map from a stream (that is, deserializes it).
*
* @param s the stream
* @throws ClassNotFoundException if the class of a serialized object
* could not be found
* @throws java.io.IOException if an I/O error occurs
*/
@SuppressWarnings("unchecked")
private void readObject(final java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in the Comparator and any hidden stuff
s.defaultReadObject();
// Reset transients
initialize();
/*
* This is nearly identical to buildFromSorted, but is
* distinct because readObject calls can't be nicely adapted
* as the kind of iterator needed by buildFromSorted. (They
* can be, but doing so requires type cheats and/or creation
* of adaptor classes.) It is simpler to just adapt the code.
*/
HeadIndex<K, V> h = head;
Node<K, V> basepred = h.node;
ArrayList<Index<K, V>> preds = new ArrayList<Index<K, V>>();
for (int i = 0; i <= h.level; ++i)
preds.add(null);
Index<K, V> q = h;
for (int i = h.level; i > 0; --i) {
preds.set(i, q);
q = q.down;
}
for (; ; ) {
Object k = s.readObject();
if (k == null)
break;
Object v = s.readObject();
if (v == null)
throw new NullPointerException();
K key = (K) k;
V val = (V) v;
int rnd = ThreadLocalRandom.current().nextInt();
int j = 0;
if ((rnd & 0x80000001) == 0) {
do {
++j;
} while (((rnd >>>= 1) & 1) != 0);
if (j > h.level) j = h.level + 1;
}
Node<K, V> z = new Node<K, V>(key, val, null);
basepred.next = z;
basepred = z;
if (j > 0) {
Index<K, V> idx = null;
for (int i = 1; i <= j; ++i) {
idx = new Index<K, V>(z, idx, null);
if (i > h.level)
h = new HeadIndex<K, V>(h.node, h, idx, i);
if (i < preds.size()) {
preds.get(i).right = idx;
preds.set(i, idx);
} else
preds.add(idx);
}
}
}
head = h;
}
// Map API 方法
/* ------ Map API methods ------ */
/**
* 如果此map包含指定键的映射,则返回 true。
* Returns {@code true} if this map contains a mapping for the specified
* key.
*
* 测试是否存在于此map中的键
* @param key key whose presence in this map is to be tested
* @return {@code true} if this map contains a mapping for the specified key
* @throws ClassCastException if the specified key cannot be compared
* with the keys currently in the map
* @throws NullPointerException if the specified key is null
*/
public boolean containsKey(Object key) {
return doGet(key) != null;
}
/**
* 返回指定键所映射到的值;如果此map不包含该键的映射关系,则返回 null。
* Returns the value to which the specified key is mapped,
* or {@code null} if this map contains no mapping for the key.
*
* 更确切地讲,如果此映射包含从键 k 到值 v 的映射关系,根据map的顺序,key 与 k 比较起来相等,
* 那么此方法返回 v;否则返回 null。(最多只能有一个这样的映射关系)。
* <p>More formally, if this map contains a mapping from a key
* {@code k} to a value {@code v} such that {@code key} compares
* equal to {@code k} according to the map's ordering, then this
* method returns {@code v}; otherwise it returns {@code null}.
* (There can be at most one such mapping.)
*
* @throws ClassCastException if the specified key cannot be compared
* with the keys currently in the map
* @throws NullPointerException if the specified key is null
*/
public V get(Object key) {
return doGet(key);
}
/**
* 返回指定键映射到的值,如果该map不包含键的映射,则返回给定的defaultValue。
* Returns the value to which the specified key is mapped,
* or the given defaultValue if this map contains no mapping for the key.
*
* @param key the key
* @param defaultValue the value to return if this map contains
* no mapping for the given key
* @return the mapping for the key, if present; else the defaultValue
* @throws NullPointerException if the specified key is null
* @since 1.8
*/
public V getOrDefault(Object key, V defaultValue) {
V v;
// 如果key 没有映射的值,则返回 defaultValue
return (v = doGet(key)) == null ? defaultValue : v;
}
/**
* 将指定值与此map中的指定键关联。
* Associates the specified value with the specified key in this map.
* 如果map已经包含了一个该键的映射关系,那么旧值将被替换。
* If the map previously contained a mapping for the key, the old
* value is replaced.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with the specified key, or
* {@code null} if there was no mapping for the key
* @throws ClassCastException if the specified key cannot be compared
* with the keys currently in the map
* @throws NullPointerException if the specified key or value is null
*/
public V put(K key, V value) {
if (value == null)
throw new NullPointerException();
// onlyIfAbsent = false,如果key 已经存在,那么value 将被替换
return doPut(key, value, false);
}
/**
* 如果存在,则从此map中删除指定key的映射。
* Removes the mapping for the specified key from this map if present.
*
* @param key key for which mapping should be removed
* 以前与指定键关联的值;如果该键没有映射关系,则返回 null
* @return the previous value associated with the specified key, or
* {@code null} if there was no mapping for the key
* @throws ClassCastException if the specified key cannot be compared
* with the keys currently in the map
* @throws NullPointerException if the specified key is null
*/
public V remove(Object key) {
return doRemove(key, null);
}
/**
* 如果此map为指定值映射一个或多个键,则返回 true。此操作所需的时间与映射的大小呈线性关系。
* Returns {@code true} if this map maps one or more keys to the
* specified value. This operation requires time linear in the
* map size. Additionally, it is possible for the map to change
* 此外,在此方法执行期间,map可能会发生更改,在这种情况下,返回的结果可能不准确。
* during execution of this method, in which case the returned
* result may be inaccurate.
*
* 测试是否存在于此映射中的值
* @param value value whose presence in this map is to be tested
* @return {@code true} if a mapping to {@code value} exists;
* {@code false} otherwise
* @throws NullPointerException if the specified value is null
*/
public boolean containsValue(Object value) {
// 此map 不能存入null 值,如果给定的值是null,直接抛出异常
if (value == null)
throw new NullPointerException();
// findFirst 查询第一个有效的节点
for (Node<K, V> n = findFirst(); n != null; n = n.next) {
// 获取n 节点的有效值
V v = n.getValidValue();
if (v != null && value.equals(v))
// 指定的值存在,返回true
return true;
}
// 指定的值不存在,返回false
return false;
}
/**
* 返回此map中的键-值映射关系数。
* Returns the number of key-value mappings in this map. If this map
* 如果此映射包含的元素数大于 Integer.MAX_VALUE,则返回 Integer.MAX_VALUE。
* contains more than {@code Integer.MAX_VALUE} elements, it
* returns {@code Integer.MAX_VALUE}.
*
* 请注意,与在大多数 collection 中不同,此方法在这不是 一个常量时间操作。
* <p>Beware that, unlike in most collections, this method is
* <em>NOT</em> a constant-time operation. Because of the
* 因为这些映射的异步特性,确定元素的当前数目需要遍历元素以计算其数目。
* asynchronous nature of these maps, determining the current
* number of elements requires traversing them all to count them.
* 此外,在执行此方法期间可以更改大小,在这种情况下,返回的结果将不准确。
* Additionally, it is possible for the size to change during
* execution of this method, in which case the returned result
* 因此,此方法在并发应用程序中通常不是很有用。
* will be inaccurate. Thus, this method is typically not very
* useful in concurrent applications.
*
* @return the number of elements in this map
*/
public int size() {
long count = 0;
// 获取第一个有效的节点
for (Node<K, V> n = findFirst(); n != null; n = n.next) {
if (n.getValidValue() != null)
// 该节点具有有效值,count++
++count;
}
// 若数量大于Integer.MAX_VALUE,则Integer.MAX_VALUE
return (count >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) count;
}
/**
* 如果此map未包含键-值映射关系,则返回 true。
* Returns {@code true} if this map contains no key-value mappings.
*
* @return {@code true} if this map contains no key-value mappings
*/
public boolean isEmpty() {
// 判断map是否为空
return findFirst() == null;
}
/**
* 从此map中移除所有映射关系。
* Removes all of the mappings from this map.
*/
public void clear() {
for (; ; ) {
Node<K, V> b, n;
HeadIndex<K, V> h = head, d = (HeadIndex<K, V>) h.down;
if (d != null)
// 删除h 索引层级
casHead(h, d); // remove levels 删除索引层级
// b 是HeadIndex 的节点,不是有效节点,因此不用进行删除
else if ((b = h.node) != null && (n = b.next) != null) {
Node<K, V> f = n.next; // remove values
if (n == b.next) { // 再次判断 n 是否为 b.next
Object v = n.value;
if (v == null)
// n 节点逻辑上已经删除,帮助从结构上进行删除
n.helpDelete(b, f);
// CAS 修改value = null,然后追加删除标记节点
else if (n.casValue(v, null) && n.appendMarker(f))
// CAS 更新b.next 为f,删除n 节点和标记节点
b.casNext(n, f);
}
} else
// map中没有有效节点了,结束循环
break;
}
}
/**
* 如果指定的键尚未与值关联,则尝试使用给定的映射函数计算其值,并将其放入到此map中,除非{@code null}。
* If the specified key is not already associated with a value,
* attempts to compute its value using the given mapping function
* and enters it into this map unless {@code null}. The function
* 仅当值不存在时,才能保证该函数被原子性地应用一次。
* is <em>NOT</em> guaranteed to be applied once atomically only
* if the value is not present.
*
* @param key key with which the specified value is to be associated
* @param mappingFunction the function to compute a value
* 与指定key 关联的当前(已经存在的 或 计算的)值,或null(如果计算出的值是null)
* @return the current (existing or computed) value associated with
* the specified key, or null if the computed value is null
* @throws NullPointerException if the specified key is null
* or the mappingFunction is null
* @since 1.8
*/
public V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
if (key == null || mappingFunction == null)
throw new NullPointerException();
V v, p, r;
// key 不存在此map 中 && 计算出的值非null
if ((v = doGet(key)) == null &&
(r = mappingFunction.apply(key)) != null)
// onlyIfAbsent 传入true,仅当key 不存在时才会添加到此map中
// doPut()返回key 映射的值,若key不存在,返回null,若key不存在返回计算出的值r,否则返回已存在的值p
v = (p = doPut(key, r, true)) == null ? r : p;
return v;
}
/**
* 如果指定键的值存在,则尝试计算给定键及其当前映射值的新映射。
* If the value for the specified key is present, attempts to
* compute a new mapping given the key and its current mapped
* 这个函数不能保证原子地应用一次。
* value. The function is <em>NOT</em> guaranteed to be applied
* once atomically.
*
* @param key key with which a value may be associated
* @param remappingFunction the function to compute a value
* 与指定键关联的新值,如果没有则为null
* @return the new value associated with the specified key, or null if none
* @throws NullPointerException if the specified key is null
* or the remappingFunction is null
* @since 1.8
*/
public V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
if (key == null || remappingFunction == null)
throw new NullPointerException();
Node<K, V> n;
Object v;
// 若key 存在此map 中
while ((n = findNode(key)) != null) {
// 判断节点n 是否已被删除,若已被删除,那么继续循环,findNode()会帮助进行删除
if ((v = n.value) != null) {
@SuppressWarnings("unchecked") V vv = (V) v;
// 传入key 和当前映射的值
V r = remappingFunction.apply(key, vv);
// 判断计算出的新值是否为null
if (r != null) {
// CAS更新value 为新的值r
if (n.casValue(vv, r))
// 更新成功,返回新的值
return r;
// 如果计算出的新值是null,那么删除此key 的映射 (仅当value 为vv 时才会进行删除)
} else if (doRemove(key, vv) != null)
// 删除成功,结束循环,返回null
break;
}
}
return null;
}
/**
* 尝试为指定的键及其当前映射值(如果没有当前映射,则为{@code null})计算映射。
* Attempts to compute a mapping for the specified key and its
* current mapped value (or {@code null} if there is no current
* 这个函数不能保证原子地应用一次。
* mapping). The function is <em>NOT</em> guaranteed to be applied
* once atomically.
*
* @param key key with which the specified value is to be associated
* @param remappingFunction the function to compute a value
* 这个key映射的新值,如果没有则为null
* @return the new value associated with the specified key, or null if none
* @throws NullPointerException if the specified key is null
* or the remappingFunction is null
* @since 1.8
*/
public V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
if (key == null || remappingFunction == null)
throw new NullPointerException();
for (; ; ) {
Node<K, V> n;
Object v;
V r;
// findNode(key) 查找此key 对应的节点,没有则为null (并清除沿途看到的所有已删除节点)
if ((n = findNode(key)) == null) {
// ----- key 不存在此map中 ------
// 计算新的值
if ((r = remappingFunction.apply(key, null)) == null)
// 若key 不存在此map中,并且计算出的值为null,则结束循环,返回null
break;
// onlyIfAbsent = true,仅当key 不存在时,才会进行put操作,若key 已存在,则返回key 映射的值
if (doPut(key, r, true) == null)
// put成功,返回key当前映射的值r
return r;
// --- key 已经存在此map 中 ----
// 判断key 对应的节点是否已被删除,若已被删除,则继续循环,findNode()方法会帮助进行删除
} else if ((v = n.value) != null) {
@SuppressWarnings("unchecked") V vv = (V) v;
// 计算新的值,传入 key 和当前映射的值
if ((r = remappingFunction.apply(key, vv)) != null) {
// CAS 更新value 为r
if (n.casValue(vv, r))
// 返回新的值r
return r;
// 若计算出的新值为null,则删除此映射 (仅当value 为vv 时才会进行删除)
} else if (doRemove(key, vv) != null)
// 删除成功,结束循环,返回null
break;
// 若删除失败,继续循环
}
}
return null;
}
/**
* 如果指定的键尚未与某个值关联,则将其与给定的值关联。
* If the specified key is not already associated with a value,
* associates it with the given value. Otherwise, replaces the
* 否则,将该值替换为给定的重新映射函数的结果,或删除(如果计算出的值为null)。
* value with the results of the given remapping function, or
* removes if {@code null}. The function is <em>NOT</em>
* 这个函数不能保证原子地应用一次。
* guaranteed to be applied once atomically.
*
* @param key key with which the specified value is to be associated
* @param value the value to use if absent
* @param remappingFunction the function to recompute a value if present
* @return the new value associated with the specified key, or null if none
* @throws NullPointerException if the specified key or value is null
* or the remappingFunction is null
* @since 1.8
*/
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
if (key == null || value == null || remappingFunction == null)
throw new NullPointerException();
for (; ; ) {
Node<K, V> n;
Object v;
V r;
// findNode(key) 查找此key 对应的节点,没有则为null (并清除沿途看到的所有已删除节点)
if ((n = findNode(key)) == null) {
// onlyIfAbsent = true,仅当key 不存在时,才会进行put操作,若key 已存在,则返回key 映射的值
if (doPut(key, value, true) == null)
// put成功,返回key当前映射的值value
return value;
// --- key 已经存在此map 中 ----
// 判断key 对应的节点是否已被删除,若已被删除,则继续循环,findNode()方法会帮助进行删除
} else if ((v = n.value) != null) {
@SuppressWarnings("unchecked") V vv = (V) v;
// 使用给定的函数计算新的值,参数传入key 当前映射的值vv,和给定的值value
if ((r = remappingFunction.apply(vv, value)) != null) {
// CAS 更新value 为r
if (n.casValue(vv, r))
// 返回新的值r
return r;
// 若计算出的新值为null,则删除此映射 (仅当value 为vv 时才会进行删除)
} else if (doRemove(key, vv) != null)
// 删除成功,返回null
return null;
}
}
}
// 视图方法
/* ---------------- View methods -------------- */
/*
* 注意:延迟初始化对视图有效,因为视图类是无状态/不可变的,所以如果创建了多个视图
* (这种情况很少发生),那么它不会影响wrt的正确性。
* Note: Lazy initialization works for views because view classes
* are stateless/immutable so it doesn't matter wrt correctness if
* more than one is created (which will only rarely happen). Even
* 即使如此,下面的习惯用法保守地确保了方法返回它创建的视图,而不是返回另一个竞争线程创建的视图。
* so, the following idiom conservatively ensures that the method
* returns the one it created if it does so, not one created by
* another racing thread.
*/
/**
* 返回此map中所包含键的 NavigableSet 视图。
* Returns a {@link NavigableSet} view of the keys contained in this map.
*
* set 的迭代器按升序返回键。
* <p>The set's iterator returns the keys in ascending order.
* 该set的spliterator还报告{@link spliterator #CONCURRENT}、{@link spliterator #NONNULL}、
* {@link spliterator #ORDERED}和{@link spliterator #ORDERED},它们的相遇顺序为key升序。
* The set's spliterator additionally reports {@link Spliterator#CONCURRENT},
* {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and
* {@link Spliterator#ORDERED}, with an encounter order that is ascending
* key order. The spliterator's comparator (see
* 如果map的comparator(参见{@link #comparator()})是{@code null},那么spliterator的comparator
* (参见{@link #comparator()})就是{@code null}。
* {@link java.util.Spliterator#getComparator()}) is {@code null} if
* the map's comparator (see {@link #comparator()}) is {@code null}.
* 否则,spliterator的比较器与map的比较器具有相同的顺序。
* Otherwise, the spliterator's comparator is the same as or imposes the
* same total ordering as the map's comparator.
*
* set 受map支持,因此对map的更改可在 set 中反映出来,反之亦然。
* <p>The set is backed by the map, so changes to the map are
* reflected in the set, and vice-versa. The set supports element
* set 支持元素移除,即通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作
* 从map中移除相应的映射关系。它不支持 add 或 addAll 操作。
* removal, which removes the corresponding mapping from the map,
* via the {@code Iterator.remove}, {@code Set.remove},
* {@code removeAll}, {@code retainAll}, and {@code clear}
* operations. It does not support the {@code add} or {@code addAll}
* operations.
*
* 这个视图的iterators 和spliterators 是弱一致性。
* <p>The view's iterators and spliterators are
* <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* 这个方法等价于navigableKeySet。
* <p>This method is equivalent to method {@code navigableKeySet}.
*
* @return a navigable set view of the keys in this map
*/
public NavigableSet<K> keySet() {
KeySet<K> ks = keySet;
return (ks != null) ? ks : (keySet = new KeySet<K>(this));
}
// 等价于keySet()
public NavigableSet<K> navigableKeySet() {
KeySet<K> ks = keySet;
return (ks != null) ? ks : (keySet = new KeySet<K>(this));
}
/**
* 返回此map中所包含值的 Collection 视图。
* Returns a {@link Collection} view of the values contained in this map.
* collection 的迭代器将按相应键的升序返回值。
* <p>The collection's iterator returns the values in ascending order
* of the corresponding keys. The collections's spliterator additionally
* 集合的spliterator还报告{@link Spliterator#CONCURRENT}、{@link Spliterator#NONNULL}和
* {@link Spliterator#ORDERED},它们的相遇顺序是相应键的升序。
* reports {@link Spliterator#CONCURRENT}, {@link Spliterator#NONNULL} and
* {@link Spliterator#ORDERED}, with an encounter order that is ascending
* order of the corresponding keys.
*
* collection 受map支持,所以对map的更改可在此 collection 中反映出来,反之亦然。
* <p>The collection is backed by the map, so changes to the map are
* reflected in the collection, and vice-versa. The collection
* collection 支持元素移除,通过 Iterator.remove、Collection.remove、removeAll、
* retainAll 和 clear 操作,可从map中移除相应的映射关系。
* supports element removal, which removes the corresponding
* mapping from the map, via the {@code Iterator.remove},
* {@code Collection.remove}, {@code removeAll},
* {@code retainAll} and {@code clear} operations. It does not
* 它不支持 add 或 addAll 操作。
* support the {@code add} or {@code addAll} operations.
*
* <p>The view's iterators and spliterators are
* <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*/
public Collection<V> values() {
Values<V> vs = values;
return (vs != null) ? vs : (values = new Values<V>(this));
}
/**
* 返回此map中所包含的映射关系的 Set 视图。
* Returns a {@link Set} view of the mappings contained in this map.
*
* set 的迭代器按键的升序返回entries。
* <p>The set's iterator returns the entries in ascending key order. The
* set's spliterator additionally reports {@link Spliterator#CONCURRENT},
* {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and
* {@link Spliterator#ORDERED}, with an encounter order that is ascending
* key order.
*
* collection 受map支持,所以对map的更改可在此 set 中反映出来,反之亦然。
* <p>The set is backed by the map, so changes to the map are
* reflected in the set, and vice-versa. The set supports element
* set 支持元素移除,通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作,
* 可从映射中移除相应的映射关系。
* removal, which removes the corresponding mapping from the map,
* via the {@code Iterator.remove}, {@code Set.remove},
* {@code removeAll}, {@code retainAll} and {@code clear}
* 它不支持 add 或 addAll 操作。
* operations. It does not support the {@code add} or
* {@code addAll} operations.
*
* 这个视图的iterators and spliterators 是弱一致性(next可能在在返回之前被删除了)。
* <p>The view's iterators and spliterators are
* <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* 通过 iterator 或 spliterator 遍历的 Map.Entry 元素 不 支持 setValue 操作。
* <p>The {@code Map.Entry} elements traversed by the {@code iterator}
* or {@code spliterator} do <em>not</em> support the {@code setValue}
* operation.
*
* @return a set view of the mappings contained in this map,
* sorted in ascending key order
*/
public Set<Map.Entry<K, V>> entrySet() {
EntrySet<K, V> es = entrySet;
return (es != null) ? es : (entrySet = new EntrySet<K, V>(this));
}
// 返回此map中所包含映射关系的逆序视图。
public ConcurrentNavigableMap<K, V> descendingMap() {
ConcurrentNavigableMap<K, V> dm = descendingMap;
// new SubMap参数为:ConcurrentSkipListMap<K, V> map, K fromKey, boolean fromInclusive,
// K toKey, boolean toInclusive, boolean isDescending
return (dm != null) ? dm : (descendingMap = new SubMap<K, V>
(this, null, false, null, false, true));
}
// 返回此map中所包含键的逆序 NavigableSet 视图。
public NavigableSet<K> descendingKeySet() {
return descendingMap().navigableKeySet();
}
/* ---------------- AbstractMap Overrides -------------- */
/**
* Compares the specified object with this map for equality.
* Returns {@code true} if the given object is also a map and the
* two maps represent the same mappings. More formally, two maps
* {@code m1} and {@code m2} represent the same mappings if
* {@code m1.entrySet().equals(m2.entrySet())}. This
* operation may return misleading results if either map is
* concurrently modified during execution of this method.
*
* @param o object to be compared for equality with this map
* @return {@code true} if the specified object is equal to this map
*/
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Map))
return false;
Map<?, ?> m = (Map<?, ?>) o;
try {
for (Map.Entry<K, V> e : this.entrySet())
if (!e.getValue().equals(m.get(e.getKey())))
return false;
for (Map.Entry<?, ?> e : m.entrySet()) {
Object k = e.getKey();
Object v = e.getValue();
if (k == null || v == null || !v.equals(get(k)))
return false;
}
return true;
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
}
/* ------ ConcurrentMap API methods ------ */
/**
* {@inheritDoc}
*
* @return the previous value associated with the specified key,
* or {@code null} if there was no mapping for the key
* @throws ClassCastException if the specified key cannot be compared
* with the keys currently in the map
* @throws NullPointerException if the specified key or value is null
*/
public V putIfAbsent(K key, V value) {
if (value == null)
throw new NullPointerException();
// onlyIfAbsent = true,仅当key 不在此map中,才会执行put操作
return doPut(key, value, true);
}
/**
* {@inheritDoc}
*
* @throws ClassCastException if the specified key cannot be compared
* with the keys currently in the map
* @throws NullPointerException if the specified key is null
*/
public boolean remove(Object key, Object value) {
if (key == null)
throw new NullPointerException();
// 仅当key 映射的值为value才会执行删除操作
return value != null && doRemove(key, value) != null;
}
/**
* {@inheritDoc}
*
* @throws ClassCastException if the specified key cannot be compared
* with the keys currently in the map
* @throws NullPointerException if any of the arguments are null
*/
// 仅当当前key映射的值为给定值时,替换value。
public boolean replace(K key, V oldValue, V newValue) {
// 非空检查
if (key == null || oldValue == null || newValue == null)
throw new NullPointerException();
for (; ; ) {
Node<K, V> n;
Object v;
// 返回键为key的节点,如果没有,则返回null,清除沿途看到的所有已删除节点。
if ((n = findNode(key)) == null)
// 没有键为key 的节点,返回false
return false;
// value == null 说明n 节点已经被删除,继续循环,调用findNode方法帮助删除
if ((v = n.value) != null) {
// 如果值和给定的值不相等,那么返回false
if (!oldValue.equals(v))
return false;
// 值和给定的值相等,CAS 更新value
if (n.casValue(v, newValue))
return true;
}
}
}
/**
* {@inheritDoc}
*
* @return the previous value associated with the specified key,
* or {@code null} if there was no mapping for the key
* @throws ClassCastException if the specified key cannot be compared
* with the keys currently in the map
* @throws NullPointerException if the specified key or value is null
*/
public V replace(K key, V value) {
if (key == null || value == null)
throw new NullPointerException();
for (; ; ) {
Node<K, V> n;
Object v;
// 返回键为key的节点,如果没有,则返回null,清除沿途看到的所有已删除节点。
if ((n = findNode(key)) == null)
return null;
// 如果n 节点未删除,使用CAS更新value
if ((v = n.value) != null && n.casValue(v, value)) {
@SuppressWarnings("unchecked") V vv = (V) v;
// 返回key 原来映射的值
return vv;
}
}
}
/* ------ SortedMap API methods ------ */
public Comparator<? super K> comparator() {
return comparator;
}
/**
* @throws NoSuchElementException {@inheritDoc}
*/
// 返回当前集合中的第一个(最小的)key。
public K firstKey() {
// 获取第一个有效的节点
Node<K, V> n = findFirst();
if (n == null)
throw new NoSuchElementException();
// 返回key 值
return n.key;
}
/**
* @throws NoSuchElementException {@inheritDoc}
*/
// 返回当前map中的最后一个(最高的)键。
public K lastKey() {
// 查找最后一个有效节点
Node<K, V> n = findLast();
if (n == null)
// 此map 为空,抛出异常
throw new NoSuchElementException();
// 返回key 值
return n.key;
}
/**
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if {@code fromKey} or {@code toKey} is null
* @throws IllegalArgumentException {@inheritDoc}
*/
public ConcurrentNavigableMap<K, V> subMap(K fromKey,
boolean fromInclusive,
K toKey,
boolean toInclusive) {
if (fromKey == null || toKey == null)
throw new NullPointerException();
return new SubMap<K, V>
(this, fromKey, fromInclusive, toKey, toInclusive, false);
}
/**
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if {@code toKey} is null
* @throws IllegalArgumentException {@inheritDoc}
*/
// 返回此映射的部分视图,其键小于(或等于,如果 inclusive 为 true)toKey。
public ConcurrentNavigableMap<K, V> headMap(K toKey,
boolean inclusive) {
if (toKey == null)
throw new NullPointerException();
// fromKey 传入null,即没有下界限制
return new SubMap<K, V>
(this, null, false, toKey, inclusive, false);
}
/**
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if {@code fromKey} is null
* @throws IllegalArgumentException {@inheritDoc}
*/
// 返回此map的部分视图,其键大于(或等于,如果 inclusive 为 true)fromKey。
public ConcurrentNavigableMap<K, V> tailMap(K fromKey,
boolean inclusive) {
if (fromKey == null)
throw new NullPointerException();
// toKey 传入null,即没有上界限制
return new SubMap<K, V>
(this, fromKey, inclusive, null, false, false);
}
/**
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if {@code fromKey} or {@code toKey} is null
* @throws IllegalArgumentException {@inheritDoc}
*/
// 返回此map的部分视图,其键值的范围从 fromKey(包括)到 toKey(不包括)
public ConcurrentNavigableMap<K, V> subMap(K fromKey, K toKey) {
return subMap(fromKey, true, toKey, false);
}
/**
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if {@code toKey} is null
* @throws IllegalArgumentException {@inheritDoc}
*/
// 返回此map的部分视图,其键值严格小于 toKey。
public ConcurrentNavigableMap<K, V> headMap(K toKey) {
return headMap(toKey, false);
}
/**
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if {@code fromKey} is null
* @throws IllegalArgumentException {@inheritDoc}
*/
// 返回此map的部分视图,其键大于等于 fromKey。
public ConcurrentNavigableMap<K, V> tailMap(K fromKey) {
return tailMap(fromKey, true);
}
/* ---------------- Relational operations -------------- */
/**
* 返回与严格小于给定键的最大键关联的key-value映射关系;如果不存在这样的键,
* 则返回 null。
* Returns a key-value mapping associated with the greatest key
* strictly less than the given key, or {@code null} if there is
* 返回的entry不支持 Entry.setValue 方法。
* no such key. The returned entry does <em>not</em> support the
* {@code Entry.setValue} method.
*
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified key is null
*/
public Map.Entry<K, V> lowerEntry(K key) {
// < key
return getNear(key, LT);
}
/**
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified key is null
*/
// 返回严格小于给定key的最大key,如果没有这样的key,则返回{@code null}。
public K lowerKey(K key) {
Node<K, V> n = findNear(key, LT, comparator);
// 返回key 值
return (n == null) ? null : n.key;
}
/**
* 返回与小于等于给定键的最大键关联的key-value映射关系;如果不存在这样的键,
* 则返回 null。
* Returns a key-value mapping associated with the greatest key
* less than or equal to the given key, or {@code null} if there
* is no such key. The returned entry does <em>not</em> support
* 返回的entry不支持 Entry.setValue 方法。
* the {@code Entry.setValue} method.
*
* @param key the key
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified key is null
*/
public Map.Entry<K, V> floorEntry(K key) {
// <= key
return getNear(key, LT | EQ);
}
/**
* @param key the key
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified key is null
*/
// 返回这个集合中小于或等于给定key的最大key,如果没有这样的key,则返回{@code null}。
public K floorKey(K key) {
// 查找 n.key <= key 的最大节点n
Node<K, V> n = findNear(key, LT | EQ, comparator);
// 返回key 值
return (n == null) ? null : n.key;
}
/**
* 返回与大于等于给定键的最小键关联的key-value映射关系;如果不存在这样的entry,
* 则返回 null。
* Returns a key-value mapping associated with the least key
* greater than or equal to the given key, or {@code null} if
* there is no such entry. The returned entry does <em>not</em>
* 返回的entry不支持 Entry.setValue 方法。
* support the {@code Entry.setValue} method.
*
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified key is null
*/
public Map.Entry<K, V> ceilingEntry(K key) {
return getNear(key, GT | EQ);
}
/**
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified key is null
*/
// 返回大于或等于给定键的最小键,如果没有这样的键,则返回{@code null}。
public K ceilingKey(K key) {
// 查找 n.key >= key 的最小节点n
Node<K, V> n = findNear(key, GT | EQ, comparator);
// 返回key 值
return (n == null) ? null : n.key;
}
/**
* Returns a key-value mapping associated with the least key
* strictly greater than the given key, or {@code null} if there
* is no such key. The returned entry does <em>not</em> support
* the {@code Entry.setValue} method.
*
* @param key the key
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified key is null
*/
public Map.Entry<K, V> higherEntry(K key) {
// 获取大于key 的最小Entry
return getNear(key, GT);
}
/**
* @param key the key
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified key is null
*/
// 返回严格大于给定键的最小键,如果没有这样的键,则返回{@code null}。
public K higherKey(K key) {
// 查找 n.key > key 的最小节点n
Node<K, V> n = findNear(key, GT, comparator);
// 返回key 值
return (n == null) ? null : n.key;
}
/**
* 返回与此map中的最小键关联的 key-value 映射关系;如果该map为空,则返回 null。
* Returns a key-value mapping associated with the least
* key in this map, or {@code null} if the map is empty.
* 返回的entry不 支持 Entry.setValue 方法。
* The returned entry does <em>not</em> support
* the {@code Entry.setValue} method.
*/
public Map.Entry<K, V> firstEntry() {
for (; ; ) {
// 获取第一个有效的节点
Node<K, V> n = findFirst();
if (n == null)
// 此map 为空,返回null
return null;
// 将key 和 value 封装到 SimpleImmutableEntry,若n 是无效节点,返回null
AbstractMap.SimpleImmutableEntry<K, V> e = n.createSnapshot();
if (e != null)
return e;
}
}
/**
* 返回与此map中的最大键关联的key-value映射关系;如果该map为空,则返回 null。
* Returns a key-value mapping associated with the greatest
* key in this map, or {@code null} if the map is empty.
* 返回的entry不支持 Entry.setValue 方法。
* The returned entry does <em>not</em> support
* the {@code Entry.setValue} method.
*/
public Map.Entry<K, V> lastEntry() {
for (; ; ) {
// 查找最后一个有效节点
Node<K, V> n = findLast();
if (n == null)
// 此map 为空,返回null
return null;
// 将key 和 value 封装到 SimpleImmutableEntry,若n 是无效节点,返回null
AbstractMap.SimpleImmutableEntry<K, V> e = n.createSnapshot();
if (e != null)
return e;
}
}
/**
* 删除并返回与此map中与最小键关联的键-值映射,如果map为空,则返回{@code null}。
* Removes and returns a key-value mapping associated with
* the least key in this map, or {@code null} if the map is empty.
* 返回的entry不支持 Entry.setValue 方法
* The returned entry does <em>not</em> support
* the {@code Entry.setValue} method.
*/
public Map.Entry<K, V> pollFirstEntry() {
return doRemoveFirstEntry();
}
/**
* 删除并返回与此map中最大键关联的键-值映射,如果map为空,则返回{@code null}。
* Removes and returns a key-value mapping associated with
* the greatest key in this map, or {@code null} if the map is empty.
* 返回的entry 不支持Entry.setValue 方法。
* The returned entry does <em>not</em> support
* the {@code Entry.setValue} method.
*/
public Map.Entry<K, V> pollLastEntry() {
return doRemoveLastEntry();
}
/* ---------------- Iterators -------------- */
/**
* 迭代器的基类
* Base of iterator classes:
*/
abstract class Iter<T> implements Iterator<T> {
/**
* 通过next()返回的最后一个节点
* the last node returned by next()
*/
Node<K, V> lastReturned;
/**
* 使用next()返回的下一个节点
* the next node to return from next();
*/
Node<K, V> next;
/**
* 缓存下一个value字段以保持弱一致性 (返回时可能已经被删除了)
* Cache of next value field to maintain weak consistency
*/
// (key 值不需要缓存,因为key 值不会更改,从next获取就可以了,value值在节点删除的时候会被设置为null,
// 因此才需要缓存)
V nextValue;
/**
* 为整个范围初始化升序迭代器。
* Initializes ascending iterator for entire range.
*/
Iter() {
// 获取第一个有效的节点
while ((next = findFirst()) != null) {
Object x = next.value;
// 判断next 未删除 且不是删除标记节点
if (x != null && x != next) {
@SuppressWarnings("unchecked") V vv = (V) x;
// 缓存value 值 (key 值不需要缓存,因为key 值不会更改,从next获取就可以了,
// value值在节点删除的时候会被设置为null,因此才需要缓存)
nextValue = vv;
break;
}
}
}
// 判断是否有下一个元素
public final boolean hasNext() {
return next != null;
}
/**
* 前进next 到更高的entry。
* Advances next to higher entry.
*/
final void advance() {
if (next == null)
throw new NoSuchElementException();
// 记录上次返回的节点
lastReturned = next;
while ((next = next.next) != null) {
Object x = next.value;
// 判断next 未删除 且不是删除标记节点
if (x != null && x != next) {
@SuppressWarnings("unchecked") V vv = (V) x;
// 缓存value 值
nextValue = vv;
break;
}
}
}
public void remove() {
Node<K, V> l = lastReturned;
if (l == null)
throw new IllegalStateException();
// 从这里直接断开所有的开销是不值得的。使用remove是足够快的。
// It would not be worth all of the overhead to directly
// unlink from here. Using remove is fast enough.
ConcurrentSkipListMap.this.remove(l.key);
// clean lastReturned
lastReturned = null;
}
}
final class ValueIterator extends Iter<V> {
public V next() {
// 返回的value是缓存的值,如果期间value 被修改了,也不会返回最新的值 (弱一致性)
V v = nextValue;
// 向前遍历一个元素
advance();
return v;
}
}
final class KeyIterator extends Iter<K> {
public K next() {
Node<K, V> n = next;
// 向前遍历一个节点
advance();
// 返回key值
return n.key;
}
}
final class EntryIterator extends Iter<Map.Entry<K, V>> {
public Map.Entry<K, V> next() {
Node<K, V> n = next;
V v = nextValue;
advance();
return new AbstractMap.SimpleImmutableEntry<K, V>(n.key, v);
}
}
// ConcurrentSkipListSet等所需要的迭代器的工厂方法
// Factory methods for iterators needed by ConcurrentSkipListSet etc
Iterator<K> keyIterator() {
// 返回key 迭代器
return new KeyIterator();
}
Iterator<V> valueIterator() {
// 返回value 迭代器
return new ValueIterator();
}
Iterator<Map.Entry<K, V>> entryIterator() {
return new EntryIterator();
}
/* ---------------- View Classes -------------- */
/*
* 视图类是静态的,委托给ConcurrentNavigableMap以允许SubMaps使用,这比迭代器方法需要类型测试的缺点更重要。
* View classes are static, delegating to a ConcurrentNavigableMap
* to allow use by SubMaps, which outweighs the ugliness of
* needing type-tests for Iterator methods.
*/
// 将元素放入ArrayList中
static final <E> List<E> toList(Collection<E> c) {
// Using size() here would be a pessimization.
ArrayList<E> list = new ArrayList<E>();
for (E e : c)
list.add(e);
return list;
}
static final class KeySet<E>
extends AbstractSet<E> implements NavigableSet<E> {
final ConcurrentNavigableMap<E, ?> m;
KeySet(ConcurrentNavigableMap<E, ?> map) {
m = map;
}
// 返回集合的元素个数
public int size() {
return m.size();
}
// 判断集合是否为空
public boolean isEmpty() {
return m.isEmpty();
}
public boolean contains(Object o) {
// 判断map中是否包含指定的key
return m.containsKey(o);
}
public boolean remove(Object o) {
// 删除key 为o 的映射
return m.remove(o) != null;
}
public void clear() {
// 从此map中移除所有映射关系。
m.clear();
}
// 返回这个集合中严格小于给定元素的最大元素,如果没有这样的元素,则返回{@code null}。
public E lower(E e) {
return m.lowerKey(e);
}
// 返回这个集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回{@code null}。
public E floor(E e) {
return m.floorKey(e);
}
// 返回该集合中大于或等于给定元素的最小元素,如果没有这样的元素,则返回{@code null}。
public E ceiling(E e) {
return m.ceilingKey(e);
}
// 返回该集合中严格大于给定元素的最小元素,如果没有这样的元素,则返回{@code null}。
public E higher(E e) {
return m.higherKey(e);
}
public Comparator<? super E> comparator() {
// 返回这个map 的comparator, 如果没有则返回null
return m.comparator();
}
// 返回当前集合中的第一个(最低的)元素。
public E first() {
return m.firstKey();
}
// 返回当前在这个集合中的最后一个(最高的)元素。
public E last() {
return m.lastKey();
}
// 检索并删除第一个(最低的)元素,如果该集合为空,则返回{@code null}。
public E pollFirst() {
Map.Entry<E, ?> e = m.pollFirstEntry();
// 返回key 值
return (e == null) ? null : e.getKey();
}
// 检索并删除最后一个(最高的)元素,如果该集合为空,则返回{@code null}。
public E pollLast() {
Map.Entry<E, ?> e = m.pollLastEntry();
// 返回key 值
return (e == null) ? null : e.getKey();
}
@SuppressWarnings("unchecked")
// 按升序返回在此 set 的元素上进行迭代的迭代器。
public Iterator<E> iterator() {
// 返回key 迭代器
if (m instanceof ConcurrentSkipListMap)
return ((ConcurrentSkipListMap<E, Object>) m).keyIterator();
else
return ((ConcurrentSkipListMap.SubMap<E, Object>) m).keyIterator();
}
public boolean equals(Object o) {
if (o == this)
return true;
// 如果不是set 类型的,返回false
if (!(o instanceof Set))
return false;
Collection<?> c = (Collection<?>) o;
try {
// 判断两个集合中的元素是否完全相同
return containsAll(c) && c.containsAll(this);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
}
public Object[] toArray() {
// toList(this) 将元素放入ArrayList中
return toList(this).toArray();
}
public <T> T[] toArray(T[] a) {
// toList(this) 将元素放入ArrayList中
return toList(this).toArray(a);
}
// 以降序返回在此 set 的元素上进行迭代的迭代器。效果等同于 descendingSet().iterator()。
public Iterator<E> descendingIterator() {
return descendingSet().iterator();
}
// 返回此 set 的部分视图,其元素范围从 fromElement 到 toElement。
public NavigableSet<E> subSet(E fromElement,
boolean fromInclusive,
E toElement,
boolean toInclusive) {
return new KeySet<E>(m.subMap(fromElement, fromInclusive,
toElement, toInclusive));
}
// 返回此 set 的部分视图,其元素小于(或等于,如果 inclusive 为 true)toElement。
public NavigableSet<E> headSet(E toElement, boolean inclusive) {
return new KeySet<E>(m.headMap(toElement, inclusive));
}
// 返回此 set 的部分视图,其元素大于(或等于,如果 inclusive 为 true)fromElement。
public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
return new KeySet<E>(m.tailMap(fromElement, inclusive));
}
// 返回此 set 的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。
public NavigableSet<E> subSet(E fromElement, E toElement) {
return subSet(fromElement, true, toElement, false);
}
// 返回此 set 的部分视图,其元素严格小于 toElement。
public NavigableSet<E> headSet(E toElement) {
return headSet(toElement, false);
}
// 返回此 set 的部分视图,其元素大于等于 fromElement。
public NavigableSet<E> tailSet(E fromElement) {
return tailSet(fromElement, true);
}
// 返回此集合中包含的元素的逆序视图。
public NavigableSet<E> descendingSet() {
return new KeySet<E>(m.descendingMap());
}
@SuppressWarnings("unchecked")
public Spliterator<E> spliterator() {
if (m instanceof ConcurrentSkipListMap)
return ((ConcurrentSkipListMap<E, ?>) m).keySpliterator();
else
return (Spliterator<E>) ((SubMap<E, ?>) m).keyIterator();
}
}
static final class Values<E> extends AbstractCollection<E> {
final ConcurrentNavigableMap<?, E> m;
Values(ConcurrentNavigableMap<?, E> map) {
m = map;
}
@SuppressWarnings("unchecked")
public Iterator<E> iterator() {
if (m instanceof ConcurrentSkipListMap)
return ((ConcurrentSkipListMap<?, E>) m).valueIterator();
else
return ((SubMap<?, E>) m).valueIterator();
}
// 判断是否为空
public boolean isEmpty() {
return m.isEmpty();
}
// 返回size
public int size() {
return m.size();
}
public boolean contains(Object o) {
return m.containsValue(o);
}
// 删除所有元素
public void clear() {
m.clear();
}
public Object[] toArray() {
// toList() 将元素放入ArrayList中
return toList(this).toArray();
}
public <T> T[] toArray(T[] a) {
return toList(this).toArray(a);
}
@SuppressWarnings("unchecked")
public Spliterator<E> spliterator() {
if (m instanceof ConcurrentSkipListMap)
return ((ConcurrentSkipListMap<?, E>) m).valueSpliterator();
else
return (Spliterator<E>) ((SubMap<?, E>) m).valueIterator();
}
}
static final class EntrySet<K1, V1> extends AbstractSet<Map.Entry<K1, V1>> {
final ConcurrentNavigableMap<K1, V1> m;
EntrySet(ConcurrentNavigableMap<K1, V1> map) {
m = map;
}
@SuppressWarnings("unchecked")
public Iterator<Map.Entry<K1, V1>> iterator() {
if (m instanceof ConcurrentSkipListMap)
return ((ConcurrentSkipListMap<K1, V1>) m).entryIterator();
else
return ((SubMap<K1, V1>) m).entryIterator();
}
public boolean contains(Object o) {
// 如果o 不是Map.Entry 类型,返回false
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
// 通过给定entry的key 到此map 中查询key 映射的value 值
V1 v = m.get(e.getKey());
// 如果该 key 存在,且映射的值相等,则返回true,否则返回false
return v != null && v.equals(e.getValue());
}
public boolean remove(Object o) {
// 如果o 不是Map.Entry 类型,返回false
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
// 仅当key 映射的值是e.getValue() 才会执行移除操作
return m.remove(e.getKey(),
e.getValue());
}
// 判断此set 是否为空
public boolean isEmpty() {
return m.isEmpty();
}
// 返回size
public int size() {
return m.size();
}
// 删除所有元素
public void clear() {
m.clear();
}
// 判断此set 是否和给定的o 相等
public boolean equals(Object o) {
if (o == this)
return true;
// 如果o 不是Set 类型,返回false
if (!(o instanceof Set))
return false;
Collection<?> c = (Collection<?>) o;
try {
return containsAll(c) && c.containsAll(this);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
}
public Object[] toArray() {
// toList() 将元素放入ArrayList中
return toList(this).toArray();
}
public <T> T[] toArray(T[] a) {
return toList(this).toArray(a);
}
@SuppressWarnings("unchecked")
public Spliterator<Map.Entry<K1, V1>> spliterator() {
if (m instanceof ConcurrentSkipListMap)
return ((ConcurrentSkipListMap<K1, V1>) m).entrySpliterator();
else
return (Spliterator<Map.Entry<K1, V1>>)
((SubMap<K1, V1>) m).entryIterator();
}
}
/**
* Submaps returned by {@link ConcurrentSkipListMap} submap operations
* represent a subrange of mappings of their underlying
* maps. Instances of this class support all methods of their
* underlying maps, differing in that mappings outside their range are
* ignored, and attempts to add mappings outside their ranges result
* in {@link IllegalArgumentException}. Instances of this class are
* constructed only using the {@code subMap}, {@code headMap}, and
* {@code tailMap} methods of their underlying maps.
*
* @serial include
*/
static final class SubMap<K, V> extends AbstractMap<K, V>
implements ConcurrentNavigableMap<K, V>, Cloneable, Serializable {
private static final long serialVersionUID = -7647078645895051609L;
/**
* 底层map
* Underlying map
*/
private final ConcurrentSkipListMap<K, V> m;
/**
* 下界key,如果从开始处则为null
* lower bound key, or null if from start
*/
private final K lo;
/**
* 上界key,如果到达结束处则为null
* upper bound key, or null if to end
*/
private final K hi;
/**
* lo 的包含标记
* inclusion flag for lo
*/
private final boolean loInclusive;
/**
* hi 的包含标记
* inclusion flag for hi
*/
private final boolean hiInclusive;
/**
* 方向。 是否是降序
* direction
*/
private final boolean isDescending;
// 延迟初始化视图持有者
// Lazily initialized view holders
private transient KeySet<K> keySetView;
private transient Set<Map.Entry<K, V>> entrySetView;
private transient Collection<V> valuesView;
/**
* 创建一个新的submap,初始化所有字段
* Creates a new submap, initializing all fields.
*/
// descendingMap() 方法传入 (this, null, false, null, false, true)
SubMap(ConcurrentSkipListMap<K, V> map,
K fromKey, boolean fromInclusive,
K toKey, boolean toInclusive,
boolean isDescending) {
Comparator<? super K> cmp = map.comparator;
if (fromKey != null && toKey != null &&
cpr(cmp, fromKey, toKey) > 0)
// 如果fromKey > toKey,抛出异常
throw new IllegalArgumentException("inconsistent range");
this.m = map;
this.lo = fromKey;
this.hi = toKey;
this.loInclusive = fromInclusive;
this.hiInclusive = toInclusive;
this.isDescending = isDescending;
}
/* ---------------- Utilities -------------- */
// 判断key 是否小于此subMap 的下界
boolean tooLow(Object key, Comparator<? super K> cmp) {
int c;
// lo -> fromKey
// 如果 key < lo.key || (key == lo.key 但是不包含lo 这个key),则返回true,否则返回false
return (lo != null && ((c = cpr(cmp, key, lo)) < 0 ||
(c == 0 && !loInclusive)));
}
// 判断key 是否大于此subMap 的上界
boolean tooHigh(Object key, Comparator<? super K> cmp) {
int c;
// 如果 key > hi.key || (key == hi.key 但是不包含hi 这个key),则返回true,否则返回false
return (hi != null && ((c = cpr(cmp, key, hi)) > 0 ||
(c == 0 && !hiInclusive)));
}
// 判断key 是否在此subMap的限定范围内
boolean inBounds(Object key, Comparator<? super K> cmp) {
return !tooLow(key, cmp) && !tooHigh(key, cmp);
}
// 检查key 是否在此subMap的限定范围内,如果不在限定范围内,则抛出异常
void checkKeyBounds(K key, Comparator<? super K> cmp) {
if (key == null)
throw new NullPointerException();
if (!inBounds(key, cmp))
throw new IllegalArgumentException("key out of range");
}
/**
* 如果节点键值小于范围的上限,则返回true。
* Returns true if node key is less than upper bound of range.
*/
boolean isBeforeEnd(ConcurrentSkipListMap.Node<K, V> n,
Comparator<? super K> cmp) {
if (n == null)
return false;
if (hi == null)
// hi == null 说明没有上限,返回true
return true;
K k = n.key;
// 如果是标记节点或header 节点,那么返回true (返回true,才能继续往下遍历)
if (k == null) // pass by markers and headers
return true;
int c = cpr(cmp, k, hi);
if (c > 0 || (c == 0 && !hiInclusive))
// k > hi || (k == hi但是此subMap不包含上界) 返回false
return false;
// 验证通过,返回true
return true;
}
/**
* 返回最低的节点。此节点可能不在范围内,因此大多数用法需要检查界限。
* Returns lowest node. This node might not be in range, so
* most usages need to check bounds.
*/
// 查找满足下界的最小有效节点,但此节点可能超出上届
ConcurrentSkipListMap.Node<K, V> loNode(Comparator<? super K> cmp) {
if (lo == null)
// 没有下界,查找第一个有效的节点
return m.findFirst();
else if (loInclusive)
// 包含下界,查找 n.key >= lo 的最小有效节点n
return m.findNear(lo, GT | EQ, cmp);
else
// 不包含下界,返回 n.key > lo 的最小有效节点n
return m.findNear(lo, GT, cmp);
}
/**
* 返回最高的节点。此节点可能不在范围内,因此大多数用法需要检查界限。
* Returns highest node. This node might not be in range, so
* most usages need to check bounds.
*/
// 查找满足上界的最大有效节点,但此节点可能低于下界
ConcurrentSkipListMap.Node<K, V> hiNode(Comparator<? super K> cmp) {
if (hi == null)
// 没有上界,查找最后一个有效的节点
return m.findLast();
else if (hiInclusive)
// 包含上界,查找 n.key <= hi 的最大有效节点n
return m.findNear(hi, LT | EQ, cmp);
else
// 不包含上界,查找 n.key < hi 的最大有效节点n
return m.findNear(hi, LT, cmp);
}
/**
* 返回最低的绝对key(忽略方向(升序/降序))。
* Returns lowest absolute key (ignoring directonality).
*/
K lowestKey() {
Comparator<? super K> cmp = m.comparator;
// loNode() 查找满足下界的最小有效节点,但此节点可能超出上界
ConcurrentSkipListMap.Node<K, V> n = loNode(cmp);
// 判断n 的key 值是否在上界范围内
if (isBeforeEnd(n, cmp))
// 返回key 值
return n.key;
else
// 此subMap为空,抛出异常
throw new NoSuchElementException();
}
/**
* 返回最高的绝对key(忽略方向)。(即忽略升序/降序)
* Returns highest absolute key (ignoring directonality).
*/
K highestKey() {
Comparator<? super K> cmp = m.comparator;
// 查找满足上界的最大有效节点,但此节点可能低于下界
ConcurrentSkipListMap.Node<K, V> n = hiNode(cmp);
if (n != null) {
K last = n.key;
// 判断key 是否在此subMap的限定范围内
if (inBounds(last, cmp))
// 返回key 值
return last;
}
// 此subMap 为空,抛出异常
throw new NoSuchElementException();
}
Map.Entry<K, V> lowestEntry() {
Comparator<? super K> cmp = m.comparator;
for (; ; ) {
// loNode() 查找满足下界的最小有效节点,但此节点可能超出上界
ConcurrentSkipListMap.Node<K, V> n = loNode(cmp);
// isBeforeEnd判断n 的key 值是否在上界范围内
if (!isBeforeEnd(n, cmp))
// 此subMap为空,返回null
return null;
// n.createSnapshot()如果n 节点持有有效值,则返回持有n节点映射的 SimpleImmutableEntry,
// 否则返回null
Map.Entry<K, V> e = n.createSnapshot();
if (e != null)
return e;
// else 该节点已经删除,重新开始
}
}
Map.Entry<K, V> highestEntry() {
Comparator<? super K> cmp = m.comparator;
for (; ; ) {
// 查找满足上界的最大有效节点,但此节点可能低于下界
ConcurrentSkipListMap.Node<K, V> n = hiNode(cmp);
// 如果该subMap为空,或者该节点不在范围内,返回null
if (n == null || !inBounds(n.key, cmp))
return null;
// n.createSnapshot()如果n 节点持有有效值,则返回持有n节点映射的 SimpleImmutableEntry,
// 否则返回null
Map.Entry<K, V> e = n.createSnapshot();
if (e != null)
return e;
// else 该节点已经删除,重新开始
}
}
Map.Entry<K, V> removeLowest() {
Comparator<? super K> cmp = m.comparator;
for (; ; ) {
// 查找满足上界的最大有效节点,但此节点可能低于下界
Node<K, V> n = loNode(cmp);
if (n == null)
// 此subMap 为空,返回null
return null;
K k = n.key;
// 判断key 是否在此subMap的限定范围内
if (!inBounds(k, cmp))
// 不在范围内,说明此subMap 为空,返回null
return null;
// 删除键为k的节点,如果没有这个节点,返回null
V v = m.doRemove(k, null);
if (v != null)
// 将key 和value 封装到SimpleImmutableEntry 返回
return new AbstractMap.SimpleImmutableEntry<K, V>(k, v);
// else,删除失败,重试
}
}
Map.Entry<K, V> removeHighest() {
Comparator<? super K> cmp = m.comparator;
for (; ; ) {
// 查找满足上界的最大有效节点,但此节点可能低于下界
Node<K, V> n = hiNode(cmp);
if (n == null)
// 此subMap 为空,返回null
return null;
K k = n.key;
// 判断key 是否在此subMap的限定范围内
if (!inBounds(k, cmp))
// 不在范围内,说明此subMap 为空,返回null
return null;
// 删除键为k的节点,如果没有这个节点,返回null
V v = m.doRemove(k, null);
if (v != null)
// 将key 和value 封装到SimpleImmutableEntry 返回
return new AbstractMap.SimpleImmutableEntry<K, V>(k, v);
// else,删除失败,重试
}
}
/**
* ConcurrentSkipListMap.getNearEntry的subMap版本
* Submap version of ConcurrentSkipListMap.getNearEntry
*/
Map.Entry<K, V> getNearEntry(K key, int rel) {
Comparator<? super K> cmp = m.comparator;
if (isDescending) { // adjust relation for direction 根据方向调整关系
if ((rel & LT) == 0) // !LT ---> > 或 >=
// 如果rel 是1(>=), 那么rel |= LT结果为11,即 <=;
// 如果rel 是0(>),那么rel |= LT结果为10,即 <
rel |= LT;
else // < (10)或 <= (11)
// 如果rel 是10(<),那么 rel &= ~LT结果为 00,即 >
// 如果rel 是11(<=),那么 rel &= ~LT结果为 01,即 >=
rel &= ~LT; // ~LT -> 01
}
// 判断key 是否小于此subMap 的下界
if (tooLow(key, cmp))
// 判断rel 是否是小于或者小于等于,如果是则返回null,因为低于下界了,
// 如果rel是大于或者大于等于,那么返回此subMap最小的entry
return ((rel & LT) != 0) ? null : lowestEntry();
// 判断key 是否大于此subMap 的上界
if (tooHigh(key, cmp))
// 判断rel 是否是小于或者小于等于,如果是则返回此subMap最大的entry,
// 如果rel是大于或者大于等于,那么返回null,因为超出上界了
return ((rel & LT) != 0) ? highestEntry() : null;
for (; ; ) {
// 查找满足关系最接近的节点
Node<K, V> n = m.findNear(key, rel, cmp);
// inBounds 判断n.key 是否在此subMap的限定范围内
if (n == null || !inBounds(n.key, cmp))
// 此subMap为空,返回null
return null;
K k = n.key;
// 获取n 节点的有效值
V v = n.getValidValue();
if (v != null)
// 把key 和value 封装到SimpleImmutableEntry 返回
return new AbstractMap.SimpleImmutableEntry<K, V>(k, v);
// n节点不是有效节点 或者 n节点已被删除,则重新开始
}
}
// 几乎和getNearEntry一样,除了键
// Almost the same as getNearEntry, except for keys
K getNearKey(K key, int rel) {
Comparator<? super K> cmp = m.comparator;
if (isDescending) { // adjust relation for direction 根据方向调整关系
if ((rel & LT) == 0) // !LT ---> > 或 >=
// 如果rel 是1(>=), 那么rel |= LT结果为11,即 <=;
// 如果rel 是0(>),那么rel |= LT结果为10,即 <
rel |= LT;
else // < (10)或 <= (11)
// 如果rel 是10(<),那么 rel &= ~LT结果为 00,即 >
// 如果rel 是11(<=),那么 rel &= ~LT结果为 01,即 >=
rel &= ~LT;
}
// 判断key 是否小于此subMap 的下界
if (tooLow(key, cmp)) {
// 判断rel 是否是大于或者大于等于,如果是那么返回此subMap最小的key
// 否则返回null,因为低于下界了
if ((rel & LT) == 0) {
// 查找满足下界的最小有效节点,但此节点可能超出上届
ConcurrentSkipListMap.Node<K, V> n = loNode(cmp);
// 如果节点键值小于范围的上限,则返回true。
if (isBeforeEnd(n, cmp))
return n.key;
}
return null;
}
// 判断key 是否大于此subMap 的上界
if (tooHigh(key, cmp)) {
// 判断rel 是否是小于或者小于等于,如果是则返回此subMap最大的key,
// 如果rel是大于或者大于等于,那么返回null,因为超出上界了
if ((rel & LT) != 0) {
// 查找满足上界的最大有效节点,但此节点可能低于下界
ConcurrentSkipListMap.Node<K, V> n = hiNode(cmp);
if (n != null) {
K last = n.key;
// 判断key 是否在此subMap的限定范围内
if (inBounds(last, cmp))
return last;
}
}
return null;
}
for (; ; ) {
// 查找满足关系最接近的节点
Node<K, V> n = m.findNear(key, rel, cmp);
// inBounds 判断n.key 是否在此subMap的限定范围内
if (n == null || !inBounds(n.key, cmp))
// 此subMap为空,返回null
return null;
K k = n.key;
// 获取n 节点的有效值
V v = n.getValidValue();
// 根据value 判断是否是有效值,如果是则返回其key值
if (v != null)
return k;
// n节点不是有效节点 或者 n节点已被删除,则重新开始
}
}
/* ---------------- Map API methods -------------- */
// 判断此subMap 是否包含指定的key
public boolean containsKey(Object key) {
if (key == null) throw new NullPointerException();
// inBounds() 判断key 是否在此subMap的限定范围内
return inBounds(key, m.comparator) && m.containsKey(key);
}
// 获取key 映射的value 值,没有则返回null
public V get(Object key) {
if (key == null) throw new NullPointerException();
// inBounds() 判断key 是否在此subMap的限定范围内,如果不在范围内,直接返回null
return (!inBounds(key, m.comparator)) ? null : m.get(key);
}
public V put(K key, V value) {
// 检查key 是否在此subMap 限定的范围内,不在范围内则抛出异常
checkKeyBounds(key, m.comparator);
// 放入此map中
return m.put(key, value);
}
public V remove(Object key) {
// inBounds() 判断key 是否在此subMap的限定范围内,如果不在范围内,直接返回null。
// 如果key 在限定的范围内,再调用remove()方法进行删除
return (!inBounds(key, m.comparator)) ? null : m.remove(key);
}
// 返回此subMap的元素个数
public int size() {
Comparator<? super K> cmp = m.comparator;
long count = 0;
// loNode() 查找满足下界的最小节点,但此节点可能超出上界
for (ConcurrentSkipListMap.Node<K, V> n = loNode(cmp);
isBeforeEnd(n, cmp); // 判断n 的key 值是否在上界范围内
n = n.next) { // 获取下一个节点
// 判断是否是有效节点
if (n.getValidValue() != null)
// 计数 + 1
++count;
}
// 如果count >= Integer.MAX_VALUE,那么返回 Integer.MAX_VALUE
return count >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) count;
}
public boolean isEmpty() {
Comparator<? super K> cmp = m.comparator;
// loNode() 查找满足下界的最小节点,但可能超出上界
// 如果返回的节点没有超出上界,那么此subMap不为空,否则此subMap 为空
return !isBeforeEnd(loNode(cmp), cmp);
}
// 判断此subMap 是否包含指定的值
public boolean containsValue(Object value) {
// 如果value == null,抛出异常
if (value == null)
throw new NullPointerException();
Comparator<? super K> cmp = m.comparator;
// loNode() 查找满足下界的最小节点,但此节点可能超出上界
for (ConcurrentSkipListMap.Node<K, V> n = loNode(cmp);
isBeforeEnd(n, cmp); // 判断n 的key 值是否在上界范围内
n = n.next) { // 获取下一个节点
// 获取有效值,没有则返回null
V v = n.getValidValue();
if (v != null && value.equals(v))
// 找到目标值,返回true
return true;
}
// 没有找到,返回false
return false;
}
public void clear() {
Comparator<? super K> cmp = m.comparator;
// loNode() 查找满足下界的最小节点,但此节点可能超出上界
for (ConcurrentSkipListMap.Node<K, V> n = loNode(cmp);
isBeforeEnd(n, cmp); // 判断n 的key 值是否在上界范围内
n = n.next) { // 获取下一个节点
// 如果n 节点是一个有效节点,那么调用remove 方法进行删除
if (n.getValidValue() != null)
// 删除节点
m.remove(n.key);
}
}
/* ---------------- ConcurrentMap API methods -------------- */
public V putIfAbsent(K key, V value) {
// 检查key 是否在此subMap的限定范围内,如果不在限定范围内,则抛出异常
checkKeyBounds(key, m.comparator);
return m.putIfAbsent(key, value);
}
public boolean remove(Object key, Object value) {
// 判断key 是否在此subMap的限定范围内,如果在范围内,再执行remove操作
// 仅当key 映射的值为value才会执行删除操作
return inBounds(key, m.comparator) && m.remove(key, value);
}
public boolean replace(K key, V oldValue, V newValue) {
// 检查key 是否在此subMap的限定范围内,如果不在限定范围内,则抛出异常
checkKeyBounds(key, m.comparator);
// 如果key 映射的值为oldValue,则替换为newValue,并返回true,否则返回false
return m.replace(key, oldValue, newValue);
}
public V replace(K key, V value) {
// 检查key 是否在此subMap的限定范围内,如果不在限定范围内,则抛出异常
checkKeyBounds(key, m.comparator);
// 如果键为key 的节点存在,则替换key 映射的值,并返回key 原来映射的值
return m.replace(key, value);
}
/* ---------------- SortedMap API methods -------------- */
public Comparator<? super K> comparator() {
Comparator<? super K> cmp = m.comparator();
if (isDescending)
return Collections.reverseOrder(cmp);
else
return cmp;
}
/**
* 创建submap的实用工具,其中给定的界限覆盖无界的(null) 和/或 检查有界的。
* Utility to create submaps, where given bounds override
* unbounded(null) ones and/or are checked against bounded ones.
*/
SubMap<K, V> newSubMap(K fromKey, boolean fromInclusive,
K toKey, boolean toInclusive) {
Comparator<? super K> cmp = m.comparator;
// 如果是降序的,把参数进行翻转,因此如果此subMap是降序的,传入的fromInclusive
// 必须要大于等于toInclusive,否则在new SubMap() 的时候会抛出异常
if (isDescending) { // flip senses 翻转的感觉
K tk = fromKey;
fromKey = toKey;
toKey = tk;
boolean ti = fromInclusive;
fromInclusive = toInclusive;
toInclusive = ti;
}
// 如果此subMap的下界不为null,在此subMap的基础上再创建subMap,需要检查fromKey不能低于此subMap的下界
if (lo != null) {
if (fromKey == null) {
fromKey = lo;
fromInclusive = loInclusive;
} else {
int c = cpr(cmp, fromKey, lo);
// c < 0 说明 fromKey < lo,即给定的下界低于此subMap 的下界
// fromKey == lo,但是此subMap不包含下界,因此在此subMap的基础上创建subMap也不能包含下界
if (c < 0 || (c == 0 && !loInclusive && fromInclusive))
throw new IllegalArgumentException("key out of range");
}
}
// 如果此subMap的上界不为null,在此subMap的基础上再创建subMap,需要检查toKey不能高于此subMap的上界
if (hi != null) {
if (toKey == null) {
toKey = hi;
toInclusive = hiInclusive;
} else {
int c = cpr(cmp, toKey, hi);
// c > 0 说明toKey > hi,即给定的上界超出此subMap的上界
// toKey == hi,但是此subMap不包含上界,因此的subMap也不能包含上界
if (c > 0 || (c == 0 && !hiInclusive && toInclusive))
throw new IllegalArgumentException("key out of range");
}
}
return new SubMap<K, V>(m, fromKey, fromInclusive,
toKey, toInclusive, isDescending);
}
public SubMap<K, V> subMap(K fromKey, boolean fromInclusive,
K toKey, boolean toInclusive) {
if (fromKey == null || toKey == null)
throw new NullPointerException();
return newSubMap(fromKey, fromInclusive, toKey, toInclusive);
}
// 返回此映射的部分视图,其键小于(或等于,如果 inclusive 为 true)toKey。
public SubMap<K, V> headMap(K toKey, boolean inclusive) {
if (toKey == null)
throw new NullPointerException();
return newSubMap(null, false, toKey, inclusive);
}
// 返回此map的部分视图,其键大于(或等于,如果 inclusive 为 true)fromKey。
public SubMap<K, V> tailMap(K fromKey, boolean inclusive) {
if (fromKey == null)
throw new NullPointerException();
return newSubMap(fromKey, inclusive, null, false);
}
public SubMap<K, V> subMap(K fromKey, K toKey) {
return subMap(fromKey, true, toKey, false);
}
public SubMap<K, V> headMap(K toKey) {
return headMap(toKey, false);
}
public SubMap<K, V> tailMap(K fromKey) {
return tailMap(fromKey, true);
}
// 返回此map中所包含映射关系的逆序视图。
public SubMap<K, V> descendingMap() {
return new SubMap<K, V>(m, lo, loInclusive,
hi, hiInclusive, !isDescending);
}
/* ---------------- Relational methods -------------- */
// 返回大于或等于给定键的最小键相关的键-值映射,如果没有这样的键,则返回{@code null}。
public Map.Entry<K, V> ceilingEntry(K key) {
return getNearEntry(key, GT | EQ);
}
// 返回大于或等于给定键的最小键,如果没有这样的键,则返回{@code null}。
public K ceilingKey(K key) {
return getNearKey(key, GT | EQ);
}
// 返回严格小于给定key的最大键关联的键-值映射,如果没有这样的键,则返回{@code null}。
public Map.Entry<K, V> lowerEntry(K key) {
return getNearEntry(key, LT);
}
// 返回严格小于给定键的最大键,如果没有这样的键,则返回{@code null}。
public K lowerKey(K key) {
return getNearKey(key, LT);
}
// 返回小于或等于给定键的最大键相关联的键-值映射,如果没有这样的键,则返回{@code null}。
public Map.Entry<K, V> floorEntry(K key) {
return getNearEntry(key, LT | EQ);
}
// 返回这个集合中小于或等于给定key的最大key,如果没有这样的key,则返回{@code null}。
public K floorKey(K key) {
return getNearKey(key, LT | EQ);
}
// 返回与严格大于给定键的最小键关联的键-值映射,如果没有这样的键,则返回{@code null}。
public Map.Entry<K, V> higherEntry(K key) {
return getNearEntry(key, GT);
}
// 返回严格大于给定键的最小键,如果没有这样的键,则返回{@code null}。
public K higherKey(K key) {
return getNearKey(key, GT);
}
// 返回当前集合中的第一个(最小的)key。
public K firstKey() {
// 降序返回最大的key,升序返回最小的key
return isDescending ? highestKey() : lowestKey();
}
// 返回当前map中的最后一个(最高的)键。
public K lastKey() {
// 降序返回最小的key,升序返回最大的key
return isDescending ? lowestKey() : highestKey();
}
// 返回与此map中最小键关联的键-值映射,如果映射为空,则返回{@code null}。
public Map.Entry<K, V> firstEntry() {
// 降序返回最大的entry,升序返回最小的entry
return isDescending ? highestEntry() : lowestEntry();
}
// 返回与此map中最大键关联的键-值映射,如果映射为空,则返回{@code null}。
public Map.Entry<K, V> lastEntry() {
// // 降序返回最小的entry,升序返回最大的entry
return isDescending ? lowestEntry() : highestEntry();
}
// 删除并返回与此map中最小键关联的键-值映射,如果map为空,则返回{@code null}。
public Map.Entry<K, V> pollFirstEntry() {
// 若是降序,删除最高的元素,若是升序,删除最低的元素
return isDescending ? removeHighest() : removeLowest();
}
// 删除并返回与此map中最大键关联的键-值映射,如果map为空,则返回{@code null}。
public Map.Entry<K, V> pollLastEntry() {
// 若是降序,删除最低的元素,若是升序,删除最高的元素
return isDescending ? removeLowest() : removeHighest();
}
// ---------------- Submap 视图 ---------------
/* ---------------- Submap Views -------------- */
// 返回此subMap中所包含键的 NavigableSet 视图。
public NavigableSet<K> keySet() {
KeySet<K> ks = keySetView;
return (ks != null) ? ks : (keySetView = new KeySet<K>(this));
}
// 等价于keySet()
public NavigableSet<K> navigableKeySet() {
KeySet<K> ks = keySetView;
return (ks != null) ? ks : (keySetView = new KeySet<K>(this));
}
// 返回在此subMap中所包含值的 Collection 视图。
public Collection<V> values() {
Collection<V> vs = valuesView;
return (vs != null) ? vs : (valuesView = new Values<V>(this));
}
// 返回在此subMap中包含的映射关系的 Set 视图。
public Set<Map.Entry<K, V>> entrySet() {
Set<Map.Entry<K, V>> es = entrySetView;
return (es != null) ? es : (entrySetView = new EntrySet<K, V>(this));
}
// 返回此subMap中所包含键的逆序 NavigableSet 视图。
public NavigableSet<K> descendingKeySet() {
return descendingMap().navigableKeySet();
}
Iterator<K> keyIterator() {
return new SubMapKeyIterator();
}
Iterator<V> valueIterator() {
return new SubMapValueIterator();
}
Iterator<Map.Entry<K, V>> entryIterator() {
return new SubMapEntryIterator();
}
/**
* 主要Iter类的变体,遍历subMap。
* Variant of main Iter class to traverse through submaps.
* 还可以作为视图的备份Spliterator
* Also serves as back-up Spliterator for views
*/
abstract class SubMapIter<T> implements Iterator<T>, Spliterator<T> {
/**
* next()最后返回的node
* the last node returned by next()
*/
Node<K, V> lastReturned;
/**
* next()返回的下一个节点
* the next node to return from next();
*/
Node<K, V> next;
/**
* 缓存next值字段以保持弱一致性
* Cache of next value field to maintain weak consistency
*/
V nextValue;
SubMapIter() {
Comparator<? super K> cmp = m.comparator;
for (; ; ) {
// 降序获取最后一个节点,升序获取第一个节点
next = isDescending ? hiNode(cmp) : loNode(cmp);
if (next == null)
// 没有下一个节点了,此时next = null,结束循环
break;
Object x = next.value;
// 若 x == null (next节点已删除) 或者 x == next (next 是删除标记节点),
// 继续循环,获取下一个节点
if (x != null && x != next) {
// 判断next.key 是否在此subMap的限定范围内
if (!inBounds(next.key, cmp))
// 超出范围,next = null
next = null;
else {
@SuppressWarnings("unchecked") V vv = (V) x;
// 缓存value 值
nextValue = vv;
}
break;
}
}
}
// 判断是否还有下一个节点
public final boolean hasNext() {
return next != null;
}
// 前进一个节点
final void advance() {
if (next == null)
throw new NoSuchElementException();
// 记录lastReturned
lastReturned = next;
if (isDescending)
descend();
else
ascend();
}
private void ascend() {
Comparator<? super K> cmp = m.comparator;
for (; ; ) {
next = next.next;
if (next == null)
// 没有下一个节点了,结束循环,返回
break;
Object x = next.value;
// 若 x == null (next节点已删除) 或者 x == next (next 是删除标记节点),
// 继续循环,获取下一个节点
if (x != null && x != next) {
// 判断key 是否大于此subMap 的上界
if (tooHigh(next.key, cmp))
// 超出上界,next 设置为null
next = null;
else {
@SuppressWarnings("unchecked") V vv = (V) x;
// 缓存next的value值
nextValue = vv;
}
break;
}
}
}
private void descend() {
Comparator<? super K> cmp = m.comparator;
for (; ; ) {
// 获取小于lastReturned.key 的最大节点
next = m.findNear(lastReturned.key, LT, cmp);
if (next == null)
// 没有下一个节点了,结束循环,返回
break;
Object x = next.value;
// 若 x == null (next节点已删除) 或者 x == next (next 是删除标记节点),
// 继续循环,获取下一个节点
if (x != null && x != next) {
// 判断key 是否小于此subMap 的下界
if (tooLow(next.key, cmp))
// 超出下界,next 设置为null
next = null;
else {
@SuppressWarnings("unchecked") V vv = (V) x;
// 缓存next的value值
nextValue = vv;
}
break;
}
}
}
public void remove() {
Node<K, V> l = lastReturned;
if (l == null)
throw new IllegalStateException();
// 删除lastReturned节点
m.remove(l.key);
// 设置lastReturned 为null
lastReturned = null;
}
public Spliterator<T> trySplit() {
// 不支持分割,直接返回null
return null;
}
// 向前遍历一个元素,并执行给定的操作
public boolean tryAdvance(Consumer<? super T> action) {
if (hasNext()) {
// 执行给定的操作并向前遍历一个元素
action.accept(next());
return true;
}
return false;
}
// 遍历剩余的所有元素,并执行给定操作
public void forEachRemaining(Consumer<? super T> action) {
while (hasNext())
action.accept(next());
}
// 直接返回Long.MAX_VALUE
public long estimateSize() {
return Long.MAX_VALUE;
}
}
final class SubMapValueIterator extends SubMapIter<V> {
public V next() {
V v = nextValue;
// 前进一个元素
advance();
// 返回缓存的value 值
return v;
}
public int characteristics() {
return 0;
}
}
final class SubMapKeyIterator extends SubMapIter<K> {
public K next() {
Node<K, V> n = next;
// 前进一个元素
advance();
// 返回key值
return n.key;
}
public int characteristics() {
return Spliterator.DISTINCT | Spliterator.ORDERED |
Spliterator.SORTED;
}
public final Comparator<? super K> getComparator() {
return SubMap.this.comparator();
}
}
final class SubMapEntryIterator extends SubMapIter<Map.Entry<K, V>> {
public Map.Entry<K, V> next() {
Node<K, V> n = next;
V v = nextValue;
// 前进一个元素
advance();
// 返回SimpleImmutableEntry
return new AbstractMap.SimpleImmutableEntry<K, V>(n.key, v);
}
public int characteristics() {
return Spliterator.DISTINCT;
}
}
}
// 默认Map 方法重写, ConcurrentSkipListMap 的方法,不是SubMap
// default Map method overrides
// 遍历所有的元素
public void forEach(BiConsumer<? super K, ? super V> action) {
if (action == null) throw new NullPointerException();
V v;
// findFirst()获取第一个有效的节点
for (Node<K, V> n = findFirst(); n != null; n = n.next) {
// 获取value值,并判断是否是有效节点
if ((v = n.getValidValue()) != null)
// 执行给定的操作,参数传入key 和 value
action.accept(n.key, v);
}
}
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
if (function == null) throw new NullPointerException();
V v;
// findFirst()获取第一个有效的节点
for (Node<K, V> n = findFirst(); n != null; n = n.next) {
// 获取value值,并判断是否是有效节点
while ((v = n.getValidValue()) != null) {
// 执行给定的函数,参数传入key 和 value
V r = function.apply(n.key, v);
// 若执行结果为null,抛出异常
if (r == null) throw new NullPointerException();
// CAS 替换value值
if (n.casValue(v, r))
// CAS 成功,继续获取下一个节点
break;
// CAS 失败,重试
}
}
}
/**
* 为spliterator提供公共结构的基类。
* Base class providing common structure for Spliterators.
* (虽然不是所有的通用功能;与通常的视图类一样,详细信息在key、value和entry子类中
* 变化很大,不值得为内部类进行抽象。
* (Although not all that much common functionality; as usual for
* view classes, details annoyingly vary in key, value, and entry
* subclasses in ways that are not worth abstracting out for
* internal classes.)
* <p>
* 基本的分割策略是递归地从顶层逐行下降,在遇到分离或行结束时下降到下一行。
* The basic split strategy is to recursively descend from top
* level, row by row, descending to next row when either split
* off, or the end of row is encountered. Control of the number of
* 分割次数的控制依赖于一些统计估计:
* splits relies on some statistical estimation: The expected
* 当跨越或向下移动时,跳跃列表中预期剩余的元素数量将减少约25%。
* remaining number of elements of a skip list when advancing
* either across or down decreases by about 25%. To make this
* 为了使这个观察有用,我们需要知道初始大小,而我们不知道。但我们可以用Integer.MAX_VALUE,
* 这样我们就不会在分割时过早地归零。
* observation useful, we need to know initial size, which we
* don't. But we can just use Integer.MAX_VALUE so that we
* don't prematurely zero out while splitting.
*/
abstract static class CSLMSpliterator<K, V> {
final Comparator<? super K> comparator;
// keys的上界(不包含),如果到结束则为空
final K fence; // exclusive upper bound for keys, or null if to end
Index<K, V> row; // the level to split out 分割的层级
// 当前遍历节点;初始在起点
Node<K, V> current; // current traversal node; initialize at origin
int est; // pseudo-size estimate 估计的虚假size
CSLMSpliterator(Comparator<? super K> comparator, Index<K, V> row,
Node<K, V> origin, K fence, int est) {
this.comparator = comparator;
this.row = row;
this.current = origin;
this.fence = fence;
this.est = est;
}
public final long estimateSize() {
return (long) est;
}
}
static final class KeySpliterator<K, V> extends CSLMSpliterator<K, V>
implements Spliterator<K> {
KeySpliterator(Comparator<? super K> comparator, Index<K, V> row,
Node<K, V> origin, K fence, int est) {
super(comparator, row, origin, fence, est);
}
public Spliterator<K> trySplit() {
Node<K, V> e;
K ek;
Comparator<? super K> cmp = comparator;
// keys的上界(不包含),如果到结束则为null
K f = fence;
// (e = current) != null 判断此Spliterator 是否为空
// head 节点和删除标记节点的key 为null,但是在这里e 不会是head节点,
// 因此(ek = e.key) != null 判断e 节点是否是删除标记节点 (如果是删除标记节点,那么不能继续分割)
if ((e = current) != null && (ek = e.key) != null) {
for (Index<K, V> q = row; q != null; q = row = q.down) {
Index<K, V> s;
Node<K, V> b, n;
K sk;
// 1、(s = q.right) != null -> q 的下一个索引节点不为null
// 2、下一个索引节点上的节点不是最后一个节点且未被删除
// 3、(sk = n.key) != null 判断n 不是删除标记节点 (判断的是下一个索引节点对应的节点,
// 所以若删除了向下一层后下一个索引节点对应的节点可能就不是删除节点了)
// 4、cpr(cmp, sk, ek) > 0 -> ek是当前遍历节点的key,判断此Spliterator 当前遍历的节点是否
// 已超过sk,如果已超过,那么继续循环,row 会向下一层 (当前层ek > sk,那么下落一层后,
// ek 绝对大于sk,因此继续循环也没有用,这里应该是一个bug,但如果是sk >= f,那么要继续分割确实要
// 往下一层,往下一层可能就不会超出上界了)
// 5、s 节点的下一个节点n 的key未到达上界
if ((s = q.right) != null && (b = s.node) != null &&
(n = b.next) != null && n.value != null &&
(sk = n.key) != null && cpr(cmp, sk, ek) > 0 &&
(f == null || cpr(cmp, sk, f) < 0)) {
// current 设置为n (s.node.next)
current = n;
Index<K, V> r = q.down;
// row 分割的层级,如果s还有下一个索引节点则指向下一个索引节点(还能分割),否则向下一层
row = (s.right != null) ? s : s.down;
// 分割之后,元素数量将减少约25%。
est -= est >>> 2;
// 创建一个新的KeySpliterator, 从current 开始,到上界(不包含),并且row 为原KeySpliterator 向下一层
// (向下一层新的KeySpliterator 才能更好地进行分割,否则只能在该KeySpliterator范围内插入新的索引节点才能再分割,
// 或者下落一层才能再分割)
// sk -> b.next.key(上界)
return new KeySpliterator<K, V>(cmp, r, e, sk, est);
}
}
}
return null;
}
// 遍历剩下的元素,并执行给定的操作
public void forEachRemaining(Consumer<? super K> action) {
if (action == null) throw new NullPointerException();
Comparator<? super K> cmp = comparator;
K f = fence;
Node<K, V> e = current;
current = null;
for (; e != null; e = e.next) {
K k;
Object v;
// (k = e.key) != null 判断e 不是删除标记节点,e 不是删除节点,再判断是否到达上界
if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0)
// 到达上界,结束循环
break;
// e 未被删除,且不是删除标记节点
if ((v = e.value) != null && v != e)
// 执行给定的操作,参数传入key 值
action.accept(k);
}
}
// 如果还有剩下元素,执行给定的操作,然后返回true; 否则返回false (向前遍历一个元素,并执行给定的操作)。
public boolean tryAdvance(Consumer<? super K> action) {
if (action == null) throw new NullPointerException();
Comparator<? super K> cmp = comparator;
K f = fence;
Node<K, V> e = current;
// 如果e 已删除或者e 是一个删除标记节点,则获取下一个节点(没有帮助删除操作)
for (; e != null; e = e.next) {
K k;
Object v;
// (k = e.key) != null 判断e 不是删除标记节点
// cpr(cmp, f, k) <= 0 即 f <= k,即到达上界了(但是此Spliterator不包含上界)
if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) {
// e 设为null,因为e 需要赋值给current
e = null;
// 结束循环,把e 赋值给current,然后返回false
break;
}
// (v = e.value) != null 判断e 节点是否已删除
// v != e 判断e 节点是否是删除标记节点
if ((v = e.value) != null && v != e) {
// current 指向下一个节点
current = e.next;
// 执行执行的操作,参数传入key
action.accept(k);
// 返回true
return true;
}
}
current = e; // 'e' is always null, 所以等价于 current = null
return false;
}
public int characteristics() {
return Spliterator.DISTINCT | Spliterator.SORTED |
Spliterator.ORDERED | Spliterator.CONCURRENT |
Spliterator.NONNULL;
}
public final Comparator<? super K> getComparator() {
return comparator;
}
}
// -------- KeySpliterator end -------------
// KeySpliterator 的工厂方法
// factory method for KeySpliterator
final KeySpliterator<K, V> keySpliterator() {
Comparator<? super K> cmp = comparator;
for (; ; ) { // ensure h corresponds to origin p 确保h对应于起点p
HeadIndex<K, V> h;
Node<K, V> p;
Node<K, V> b = (h = head).node;
// b.next == null 说明此subMap 为空
// p.value != null 判断 p 节点未被删除
// b 是head节点(虚假节点),所以遍历需要从b.next 开始
if ((p = b.next) == null || p.value != null)
// Comparator<? super K> comparator, Index<K, V> row, Node<K, V> origin, K fence, int est
return new KeySpliterator<K, V>(cmp, h, p, null, (p == null) ?
0 : Integer.MAX_VALUE);
// p != null && p.value == null, 帮助删除p 节点
p.helpDelete(b, p.next);
}
}
static final class ValueSpliterator<K, V> extends CSLMSpliterator<K, V>
implements Spliterator<V> {
ValueSpliterator(Comparator<? super K> comparator, Index<K, V> row,
Node<K, V> origin, K fence, int est) {
super(comparator, row, origin, fence, est);
}
public Spliterator<V> trySplit() {
Node<K, V> e;
K ek;
Comparator<? super K> cmp = comparator;
// keys的上界(不包含),如果到结束则为null
K f = fence;
// (e = current) != null 判断此Spliterator 是否为空
// head 节点和删除标记节点的key 为null,但是在这里e 不会是head节点,
// 因此(ek = e.key) != null 判断e 节点是否是删除标记节点 (如果是删除标记节点,那么不能继续分割)
if ((e = current) != null && (ek = e.key) != null) {
for (Index<K, V> q = row; q != null; q = row = q.down) {
Index<K, V> s;
Node<K, V> b, n;
K sk;
// 1、(s = q.right) != null -> q 的下一个索引节点不为null
// 2、下一个索引节点上的节点不是最后一个节点且未被删除
// 3、(sk = n.key) != null 判断n 不是删除标记节点 (判断的是下一个索引节点对应的节点,
// 所以若删除了向下一层后下一个索引节点对应的节点可能就不是删除节点了)
// 4、cpr(cmp, sk, ek) > 0 -> ek是当前遍历节点的key,判断此Spliterator 当前遍历的节点是否
// 已超过sk,如果已超过,那么继续循环,row 会向下一层 (当前层ek > sk,那么下落一层后,
// ek 绝对大于sk,因此继续循环也没有用,这里应该是一个bug,但如果是sk >= f,那么要继续分割确实
// 得往下一层,往下一层可能就不会超出上界了)
// 5、s 节点的下一个节点n 的key未到达上界
if ((s = q.right) != null && (b = s.node) != null &&
(n = b.next) != null && n.value != null &&
(sk = n.key) != null && cpr(cmp, sk, ek) > 0 &&
(f == null || cpr(cmp, sk, f) < 0)) {
// current 设置为n (s.node.next)
current = n;
Index<K, V> r = q.down;
// row 分割的层级,如果s还有下一个索引节点则指向下一个索引节点(还能分割),否则向下一层
row = (s.right != null) ? s : s.down;
// 分割之后,元素数量将减少约25%。
est -= est >>> 2;
// 创建一个新的ValueSpliterator, 从current 开始,到上界(不包含),并且row 为原ValueSpliterator 向下一层
// (向下一层新的ValueSpliterator 才能更好地进行分割,否则只能在该ValueSpliterator范围内插入新的索引节点才能再分割,
// 或者下落一层才能再分割)
// sk -> b.next.key(上界)
return new ValueSpliterator<K, V>(cmp, r, e, sk, est);
}
}
}
return null;
}
// 遍历剩下的元素,并执行给定的操作
public void forEachRemaining(Consumer<? super V> action) {
if (action == null) throw new NullPointerException();
Comparator<? super K> cmp = comparator;
K f = fence;
Node<K, V> e = current;
current = null;
for (; e != null; e = e.next) {
K k;
Object v;
// (k = e.key) != null 判断e 不是删除标记节点,若e 不是删除节点,再判断是否到达上界
if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0)
// 到达上界,结束循环
break;
// e 未被删除,且不是删除标记节点
if ((v = e.value) != null && v != e) {
@SuppressWarnings("unchecked") V vv = (V) v;
// 执行给定的操作,传入value值
action.accept(vv);
}
}
}
// 如果还有剩下元素,执行给定的操作,然后返回true; 否则返回false
public boolean tryAdvance(Consumer<? super V> action) {
if (action == null) throw new NullPointerException();
Comparator<? super K> cmp = comparator;
K f = fence;
Node<K, V> e = current;
// 如果e 已删除或者e 是一个删除标记节点,则获取下一个节点(没有帮助删除操作)
for (; e != null; e = e.next) {
K k;
Object v;
// (k = e.key) != null 判断e 不是删除标记节点
// cpr(cmp, f, k) <= 0 即 f <= k,即到达上界了(但是此Spliterator不包含上界)
if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) {
// e 设为null,因为e 需要赋值给current
e = null;
// 结束循环,把e 赋值给current,然后返回false
break;
}
// (v = e.value) != null 判断e 节点是否已删除
// v != e 判断e 节点是否是删除标记节点
if ((v = e.value) != null && v != e) {
// current 指向下一个节点
current = e.next;
@SuppressWarnings("unchecked") V vv = (V) v;
// 执行执行的操作,参数传入value
action.accept(vv);
return true;
}
}
current = e; // 'e' is always null, 所以等价于 current = null
return false;
}
public int characteristics() {
return Spliterator.CONCURRENT | Spliterator.ORDERED |
Spliterator.NONNULL;
}
}
// ------- ValueSpliterator end --------------
// Almost the same as keySpliterator() 几乎与keySpliterator()相同
final ValueSpliterator<K, V> valueSpliterator() {
Comparator<? super K> cmp = comparator;
for (; ; ) {
HeadIndex<K, V> h;
Node<K, V> p;
Node<K, V> b = (h = head).node;
// b.next == null 说明此subMap 为空
// p.value != null 判断 p 节点未被删除
// b 是head节点(虚假节点),所以遍历需要从b.next 开始
if ((p = b.next) == null || p.value != null)
return new ValueSpliterator<K, V>(cmp, h, p, null, (p == null) ?
0 : Integer.MAX_VALUE);
// p != null && p.value == null, 帮助删除p 节点
p.helpDelete(b, p.next);
}
}
static final class EntrySpliterator<K, V> extends CSLMSpliterator<K, V>
implements Spliterator<Map.Entry<K, V>> {
EntrySpliterator(Comparator<? super K> comparator, Index<K, V> row,
Node<K, V> origin, K fence, int est) {
super(comparator, row, origin, fence, est);
}
public Spliterator<Map.Entry<K, V>> trySplit() {
Node<K, V> e;
K ek;
Comparator<? super K> cmp = comparator;
// keys的上界(不包含),如果到结束则为null
K f = fence;
// (e = current) != null 判断此Spliterator 是否为空
// head 节点和删除标记节点的key 为null,但是在这里e 不会是head节点,
// 因此(ek = e.key) != null 判断e 节点是否是删除标记节点 (如果是删除标记节点,那么不能继续分割)
if ((e = current) != null && (ek = e.key) != null) {
// 以索引节点作为粒度进行分割
for (Index<K, V> q = row; q != null; q = row = q.down) {
Index<K, V> s;
Node<K, V> b, n;
K sk;
// 1、(s = q.right) != null -> q 的下一个索引节点不为null
// 2、下一个索引节点上的节点不是最后一个节点且未被删除
// 3、(sk = n.key) != null 判断n 不是删除标记节点 (判断的是下一个索引节点对应的节点,
// 所以若删除了向下一层后下一个索引节点对应的节点可能就不是删除节点了)
// 4、cpr(cmp, sk, ek) > 0 -> ek是当前遍历节点的key,判断此Spliterator 当前遍历的节点是否
// 已超过sk,如果已超过,那么继续循环,row 会向下一层 (当前层ek > sk,那么下落一层后,
// ek 绝对大于sk,因此继续循环也没有用,这里应该是一个bug,但如果是sk >= f,那么要继续分割确实
// 得往下一层,往下一层可能就不会超出上界了)
// 5、s 节点的下一个节点n 的key未到达上界
if ((s = q.right) != null && (b = s.node) != null &&
(n = b.next) != null && n.value != null &&
(sk = n.key) != null && cpr(cmp, sk, ek) > 0 &&
(f == null || cpr(cmp, sk, f) < 0)) {
// current 设置为n (s.node.next)
current = n;
Index<K, V> r = q.down;
// row 分割的层级,如果s还有下一个索引节点则指向下一个索引节点(还能分割),否则向下一层
row = (s.right != null) ? s : s.down;
// 分割之后,元素数量将减少约25%。
est -= est >>> 2;
// 创建一个新的EntrySpliterator, 从current 开始,到上界(不包含),并且row 为原EntrySpliterator 向下一层
// (向下一层新的EntrySpliterator 才能更好地进行分割,否则只能在该EntrySpliterator范围内插入新的索引节点才能再分割,
// 或者下落一层才能再分割)
// sk -> b.next.key(上界)
return new EntrySpliterator<K, V>(cmp, r, e, sk, est);
}
}
}
return null;
}
// 遍历剩下的元素,并执行给定的操作
public void forEachRemaining(Consumer<? super Map.Entry<K, V>> action) {
if (action == null) throw new NullPointerException();
Comparator<? super K> cmp = comparator;
K f = fence;
Node<K, V> e = current;
current = null;
for (; e != null; e = e.next) {
K k;
Object v;
// (k = e.key) != null 判断e 不是删除标记节点,若e 不是删除节点,再判断是否到达上界
if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0)
// 到达上界,结束循环
break;
// e 未被删除,且不是删除标记节点
if ((v = e.value) != null && v != e) {
@SuppressWarnings("unchecked") V vv = (V) v;
// 将key 和value 封装到SimpleImmutableEntry,然后作为参数传入
action.accept
(new AbstractMap.SimpleImmutableEntry<K, V>(k, vv));
}
}
}
// 如果还有剩下元素,执行给定的操作,然后返回true; 否则返回false
public boolean tryAdvance(Consumer<? super Map.Entry<K, V>> action) {
if (action == null) throw new NullPointerException();
Comparator<? super K> cmp = comparator;
K f = fence;
Node<K, V> e = current;
// 如果e 已删除或者e 是一个删除标记节点,则获取下一个节点(没有帮助删除操作)
for (; e != null; e = e.next) {
K k;
Object v;
// (k = e.key) != null 判断e 不是删除标记节点
// cpr(cmp, f, k) <= 0 即 f <= k,即到达上界了(但是此Spliterator不包含上界)
if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) {
// e 设为null,因为e 需要赋值给current
e = null;
// 结束循环,把e 赋值给current,然后返回false
break;
}
// (v = e.value) != null 判断e 节点是否已删除
// v != e 判断e 节点是否是删除标记节点
if ((v = e.value) != null && v != e) {
// current 指向下一个节点
current = e.next;
@SuppressWarnings("unchecked") V vv = (V) v;
// 执行给定的操作
action.accept
(new AbstractMap.SimpleImmutableEntry<K, V>(k, vv));
return true;
}
}
current = e; // 'e' is always null, 所以等价于 current = null
return false;
}
public int characteristics() {
return Spliterator.DISTINCT | Spliterator.SORTED |
Spliterator.ORDERED | Spliterator.CONCURRENT |
Spliterator.NONNULL;
}
public final Comparator<Map.Entry<K, V>> getComparator() {
// Adapt or create a key-based comparator
if (comparator != null) {
return Map.Entry.comparingByKey(comparator);
} else {
return (Comparator<Map.Entry<K, V>> & Serializable) (e1, e2) -> {
@SuppressWarnings("unchecked")
Comparable<? super K> k1 = (Comparable<? super K>) e1.getKey();
return k1.compareTo(e2.getKey());
};
}
}
}
// Almost the same as keySpliterator()
final EntrySpliterator<K, V> entrySpliterator() {
Comparator<? super K> cmp = comparator;
for (; ; ) { // almost same as key version
HeadIndex<K, V> h;
Node<K, V> p;
Node<K, V> b = (h = head).node;
if ((p = b.next) == null || p.value != null)
return new EntrySpliterator<K, V>(cmp, h, p, null, (p == null) ?
0 : Integer.MAX_VALUE);
p.helpDelete(b, p.next);
}
}
// Unsafe mechanics
private static final sun.misc.Unsafe UNSAFE;
private static final long headOffset;
private static final long SECONDARY;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> k = ConcurrentSkipListMap.class;
headOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("head"));
Class<?> tk = Thread.class;
SECONDARY = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSecondarySeed"));
} catch (Exception e) {
throw new Error(e);
}
}
}