|
|
核心的数据结构是TreeNode和TreeBin,其余与HashMap相同
|
|
|
|
|
|
# TreeNode
|
|
|
|
|
|
treeNode就是红黑树结构
|
|
|
|
|
|
# TreeBin
|
|
|
|
|
|
是TreeNode的容器,提供转换黑红树的一些条件和锁的控制。通过读写锁来实现线程安全。
|
|
|
```java
|
|
|
static final class TreeBin<K,V> extends Node<K,V> {
|
|
|
TreeNode<K,V> root;
|
|
|
volatile TreeNode<K,V> first;
|
|
|
volatile Thread waiter;
|
|
|
volatile int lockState;
|
|
|
// values for lockState
|
|
|
static final int WRITER = 1; // 持有写锁
|
|
|
static final int WAITER = 2; // 等待写锁
|
|
|
static final int READER = 4; // 读锁
|
|
|
|
|
|
/**
|
|
|
* Tie-breaking utility for ordering insertions when equal
|
|
|
* hashCodes and non-comparable. We don't require a total
|
|
|
* order, just a consistent insertion rule to maintain
|
|
|
* equivalence across rebalancings. Tie-breaking further than
|
|
|
* necessary simplifies testing a bit.
|
|
|
*/
|
|
|
static int tieBreakOrder(Object a, Object b) {
|
|
|
int d;
|
|
|
if (a == null || b == null ||
|
|
|
(d = a.getClass().getName().
|
|
|
compareTo(b.getClass().getName())) == 0)
|
|
|
d = (System.identityHashCode(a) <= System.identityHashCode(b) ?
|
|
|
-1 : 1);
|
|
|
return d;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Creates bin with initial set of nodes headed by b.
|
|
|
*/
|
|
|
TreeBin(TreeNode<K,V> b) {
|
|
|
super(TREEBIN, null, null, null);
|
|
|
this.first = b;
|
|
|
TreeNode<K,V> r = null;
|
|
|
for (TreeNode<K,V> x = b, next; x != null; x = next) {
|
|
|
next = (TreeNode<K,V>)x.next;
|
|
|
x.left = x.right = null;
|
|
|
if (r == null) {
|
|
|
x.parent = null;
|
|
|
x.red = false;
|
|
|
r = x;
|
|
|
}
|
|
|
else {
|
|
|
K k = x.key;
|
|
|
int h = x.hash;
|
|
|
Class<?> kc = null;
|
|
|
for (TreeNode<K,V> p = r;;) {
|
|
|
int dir, ph;
|
|
|
K pk = p.key;
|
|
|
if ((ph = p.hash) > h)
|
|
|
dir = -1;
|
|
|
else if (ph < h)
|
|
|
dir = 1;
|
|
|
else if ((kc == null &&
|
|
|
(kc = comparableClassFor(k)) == null) ||
|
|
|
(dir = compareComparables(kc, k, pk)) == 0)
|
|
|
dir = tieBreakOrder(k, pk);
|
|
|
TreeNode<K,V> xp = p;
|
|
|
if ((p = (dir <= 0) ? p.left : p.right) == null) {
|
|
|
x.parent = xp;
|
|
|
if (dir <= 0)
|
|
|
xp.left = x;
|
|
|
else
|
|
|
xp.right = x;
|
|
|
r = balanceInsertion(r, x);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
this.root = r;
|
|
|
assert checkInvariants(root);
|
|
|
}
|
|
|
``` |