328 |
|
/** Lazily initialized values collection */ |
329 |
|
private transient Values values; |
330 |
|
/** Lazily initialized descending key set */ |
331 |
< |
private transient DescendingKeySet descendingKeySet; |
332 |
< |
/** Lazily initialized descending entry set */ |
333 |
< |
private transient DescendingEntrySet descendingEntrySet; |
331 |
> |
private transient ConcurrentNavigableMap<K,V> descendingMap; |
332 |
|
|
333 |
|
/** |
334 |
|
* Initializes or resets state. Needed by constructors, clone, |
339 |
|
keySet = null; |
340 |
|
entrySet = null; |
341 |
|
values = null; |
342 |
< |
descendingEntrySet = null; |
345 |
< |
descendingKeySet = null; |
342 |
> |
descendingMap = null; |
343 |
|
randomSeed = seedGenerator.nextInt() | 0x0100; // ensure nonzero |
344 |
|
head = new HeadIndex<K,V>(new Node<K,V>(null, BASE_HEADER, null), |
345 |
|
null, null, 1); |
1056 |
|
* associated with key |
1057 |
|
* @return the node, or null if not found |
1058 |
|
*/ |
1059 |
< |
private V doRemove(Object okey, Object value) { |
1059 |
> |
final V doRemove(Object okey, Object value) { |
1060 |
|
Comparable<? super K> key = comparable(okey); |
1061 |
|
for (;;) { |
1062 |
|
Node<K,V> b = findPredecessor(key); |
1133 |
|
casHead(d, h); // try to backout |
1134 |
|
} |
1135 |
|
|
1139 |
– |
/** |
1140 |
– |
* Version of remove with boolean return. Needed by view classes |
1141 |
– |
*/ |
1142 |
– |
boolean removep(Object key) { |
1143 |
– |
return doRemove(key, null) != null; |
1144 |
– |
} |
1145 |
– |
|
1136 |
|
/* ---------------- Finding and removing first element -------------- */ |
1137 |
|
|
1138 |
|
/** |
1152 |
|
} |
1153 |
|
|
1154 |
|
/** |
1165 |
– |
* Removes first entry; returns its key. Note: The |
1166 |
– |
* mostly-redundant methods for removing first and last keys vs |
1167 |
– |
* entries exist to avoid needless creation of Entry nodes when |
1168 |
– |
* only the key is needed. The minor reduction in overhead is |
1169 |
– |
* worth the minor code duplication. |
1170 |
– |
* @return null if empty, else key of first entry |
1171 |
– |
*/ |
1172 |
– |
K pollFirstKey() { |
1173 |
– |
for (;;) { |
1174 |
– |
Node<K,V> b = head.node; |
1175 |
– |
Node<K,V> n = b.next; |
1176 |
– |
if (n == null) |
1177 |
– |
return null; |
1178 |
– |
Node<K,V> f = n.next; |
1179 |
– |
if (n != b.next) |
1180 |
– |
continue; |
1181 |
– |
Object v = n.value; |
1182 |
– |
if (v == null) { |
1183 |
– |
n.helpDelete(b, f); |
1184 |
– |
continue; |
1185 |
– |
} |
1186 |
– |
if (!n.casValue(v, null)) |
1187 |
– |
continue; |
1188 |
– |
if (!n.appendMarker(f) || !b.casNext(n, f)) |
1189 |
– |
findFirst(); // retry |
1190 |
– |
clearIndexToFirst(); |
1191 |
– |
return n.key; |
1192 |
– |
} |
1193 |
– |
} |
1194 |
– |
|
1195 |
– |
/** |
1155 |
|
* Removes first entry; returns its snapshot. |
1156 |
|
* @return null if empty, else snapshot of first entry |
1157 |
|
*/ |
1278 |
|
} |
1279 |
|
|
1280 |
|
/** |
1322 |
– |
* Removes last entry; returns key or null if empty. |
1323 |
– |
* @return null if empty, else key of last entry |
1324 |
– |
*/ |
1325 |
– |
K pollLastKey() { |
1326 |
– |
for (;;) { |
1327 |
– |
Node<K,V> b = findPredecessorOfLast(); |
1328 |
– |
Node<K,V> n = b.next; |
1329 |
– |
if (n == null) { |
1330 |
– |
if (b.isBaseHeader()) // empty |
1331 |
– |
return null; |
1332 |
– |
else |
1333 |
– |
continue; // all b's successors are deleted; retry |
1334 |
– |
} |
1335 |
– |
for (;;) { |
1336 |
– |
Node<K,V> f = n.next; |
1337 |
– |
if (n != b.next) // inconsistent read |
1338 |
– |
break; |
1339 |
– |
Object v = n.value; |
1340 |
– |
if (v == null) { // n is deleted |
1341 |
– |
n.helpDelete(b, f); |
1342 |
– |
break; |
1343 |
– |
} |
1344 |
– |
if (v == n || b.value == null) // b is deleted |
1345 |
– |
break; |
1346 |
– |
if (f != null) { |
1347 |
– |
b = n; |
1348 |
– |
n = f; |
1349 |
– |
continue; |
1350 |
– |
} |
1351 |
– |
if (!n.casValue(v, null)) |
1352 |
– |
break; |
1353 |
– |
K key = n.key; |
1354 |
– |
Comparable<? super K> ck = comparable(key); |
1355 |
– |
if (!n.appendMarker(f) || !b.casNext(n, f)) |
1356 |
– |
findNode(ck); // Retry via findNode |
1357 |
– |
else { |
1358 |
– |
findPredecessor(ck); // Clean index |
1359 |
– |
if (head.right == null) |
1360 |
– |
tryReduceLevel(); |
1361 |
– |
} |
1362 |
– |
return key; |
1363 |
– |
} |
1364 |
– |
} |
1365 |
– |
} |
1366 |
– |
|
1367 |
– |
/** |
1281 |
|
* Removes last entry; returns its snapshot. |
1282 |
|
* Specialized variant of doRemove. |
1283 |
|
* @return null if empty, else snapshot of last entry |
1385 |
|
} |
1386 |
|
} |
1387 |
|
|
1475 |
– |
/** |
1476 |
– |
* Returns ceiling, or first node if key is <tt>null</tt>. |
1477 |
– |
*/ |
1478 |
– |
Node<K,V> findCeiling(K key) { |
1479 |
– |
return (key == null)? findFirst() : findNear(key, GT|EQ); |
1480 |
– |
} |
1481 |
– |
|
1482 |
– |
/** |
1483 |
– |
* Returns lower node, or last node if key is <tt>null</tt>. |
1484 |
– |
*/ |
1485 |
– |
Node<K,V> findLower(K key) { |
1486 |
– |
return (key == null)? findLast() : findNear(key, LT); |
1487 |
– |
} |
1488 |
– |
|
1489 |
– |
/** |
1490 |
– |
* Returns key for results of findNear after screening to ensure |
1491 |
– |
* result is in given range. Needed by submaps. |
1492 |
– |
* @param key the key |
1493 |
– |
* @param rel the relation -- OR'ed combination of EQ, LT, GT |
1494 |
– |
* @param least minimum allowed key value |
1495 |
– |
* @param fence key greater than maximum allowed key value |
1496 |
– |
* @return Key fitting relation, or <tt>null</tt> if no such |
1497 |
– |
*/ |
1498 |
– |
K getNearKey(K key, int rel, K least, K fence) { |
1499 |
– |
// Don't return keys less than least |
1500 |
– |
if ((rel & LT) == 0) { |
1501 |
– |
if (compare(key, least) < 0) { |
1502 |
– |
key = least; |
1503 |
– |
rel = rel | EQ; |
1504 |
– |
} |
1505 |
– |
} |
1506 |
– |
|
1507 |
– |
for (;;) { |
1508 |
– |
Node<K,V> n = findNear(key, rel); |
1509 |
– |
if (n == null || !inHalfOpenRange(n.key, least, fence)) |
1510 |
– |
return null; |
1511 |
– |
K k = n.key; |
1512 |
– |
V v = n.getValidValue(); |
1513 |
– |
if (v != null) |
1514 |
– |
return k; |
1515 |
– |
} |
1516 |
– |
} |
1517 |
– |
|
1518 |
– |
|
1519 |
– |
/** |
1520 |
– |
* Returns SimpleImmutableEntry for results of findNear after |
1521 |
– |
* screening to ensure result is in given range. Needed by |
1522 |
– |
* submaps. |
1523 |
– |
* @param key the key |
1524 |
– |
* @param rel the relation -- OR'ed combination of EQ, LT, GT |
1525 |
– |
* @param least minimum allowed key value |
1526 |
– |
* @param fence key greater than maximum allowed key value |
1527 |
– |
* @return Entry fitting relation, or <tt>null</tt> if no such |
1528 |
– |
*/ |
1529 |
– |
Map.Entry<K,V> getNearEntry(K key, int rel, K least, K fence) { |
1530 |
– |
// Don't return keys less than least |
1531 |
– |
if ((rel & LT) == 0) { |
1532 |
– |
if (compare(key, least) < 0) { |
1533 |
– |
key = least; |
1534 |
– |
rel = rel | EQ; |
1535 |
– |
} |
1536 |
– |
} |
1537 |
– |
|
1538 |
– |
for (;;) { |
1539 |
– |
Node<K,V> n = findNear(key, rel); |
1540 |
– |
if (n == null || !inHalfOpenRange(n.key, least, fence)) |
1541 |
– |
return null; |
1542 |
– |
K k = n.key; |
1543 |
– |
V v = n.getValidValue(); |
1544 |
– |
if (v != null) |
1545 |
– |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
1546 |
– |
} |
1547 |
– |
} |
1548 |
– |
|
1549 |
– |
/** |
1550 |
– |
* Finds and removes least element of subrange. |
1551 |
– |
* @param least minimum allowed key value |
1552 |
– |
* @param fence key greater than maximum allowed key value |
1553 |
– |
* @return least Entry, or <tt>null</tt> if no such |
1554 |
– |
*/ |
1555 |
– |
Map.Entry<K,V> removeFirstEntryOfSubrange(K least, K fence) { |
1556 |
– |
for (;;) { |
1557 |
– |
Node<K,V> n = findCeiling(least); |
1558 |
– |
if (n == null) |
1559 |
– |
return null; |
1560 |
– |
K k = n.key; |
1561 |
– |
if (fence != null && compare(k, fence) >= 0) |
1562 |
– |
return null; |
1563 |
– |
V v = doRemove(k, null); |
1564 |
– |
if (v != null) |
1565 |
– |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
1566 |
– |
} |
1567 |
– |
} |
1568 |
– |
|
1569 |
– |
/** |
1570 |
– |
* Finds and removes greatest element of subrange. |
1571 |
– |
* @param least minimum allowed key value |
1572 |
– |
* @param fence key greater than maximum allowed key value |
1573 |
– |
* @return least Entry, or <tt>null</tt> if no such |
1574 |
– |
*/ |
1575 |
– |
Map.Entry<K,V> removeLastEntryOfSubrange(K least, K fence) { |
1576 |
– |
for (;;) { |
1577 |
– |
Node<K,V> n = findLower(fence); |
1578 |
– |
if (n == null) |
1579 |
– |
return null; |
1580 |
– |
K k = n.key; |
1581 |
– |
if (least != null && compare(k, least) < 0) |
1582 |
– |
return null; |
1583 |
– |
V v = doRemove(k, null); |
1584 |
– |
if (v != null) |
1585 |
– |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
1586 |
– |
} |
1587 |
– |
} |
1588 |
– |
|
1589 |
– |
|
1590 |
– |
|
1388 |
|
/* ---------------- Constructors -------------- */ |
1389 |
|
|
1390 |
|
/** |
1732 |
|
initialize(); |
1733 |
|
} |
1734 |
|
|
1735 |
+ |
/* ---------------- View methods -------------- */ |
1736 |
+ |
|
1737 |
+ |
/* |
1738 |
+ |
* Note: Lazy initialization works for views because view classes |
1739 |
+ |
* are stateless/immutable so it doesn't matter wrt correctness if |
1740 |
+ |
* more than one is created (which will only rarely happen). Even |
1741 |
+ |
* so, the following idiom conservatively ensures that the method |
1742 |
+ |
* returns the one it created if it does so, not one created by |
1743 |
+ |
* another racing thread. |
1744 |
+ |
*/ |
1745 |
+ |
|
1746 |
|
/** |
1747 |
|
* Returns a {@link Set} view of the keys contained in this map. |
1748 |
|
* The set's iterator returns the keys in ascending order. |
1764 |
|
* ascending order |
1765 |
|
*/ |
1766 |
|
public Set<K> keySet() { |
1959 |
– |
/* |
1960 |
– |
* Note: Lazy initialization works here and for other views |
1961 |
– |
* because view classes are stateless/immutable so it doesn't |
1962 |
– |
* matter wrt correctness if more than one is created (which |
1963 |
– |
* will only rarely happen). Even so, the following idiom |
1964 |
– |
* conservatively ensures that the method returns the one it |
1965 |
– |
* created if it does so, not one created by another racing |
1966 |
– |
* thread. |
1967 |
– |
*/ |
1767 |
|
KeySet ks = keySet; |
1768 |
< |
return (ks != null) ? ks : (keySet = new KeySet()); |
1768 |
> |
return (ks != null) ? ks : (keySet = new KeySet(this)); |
1769 |
|
} |
1770 |
|
|
1771 |
|
/** |
1772 |
< |
* Returns a {@link Set} view of the keys contained in this map. |
1773 |
< |
* The set's iterator returns the keys in descending order. |
1772 |
> |
* Returns a {@link NavigableSet} view of the keys contained in this map. |
1773 |
> |
* The set's iterator returns the keys in ascending order. |
1774 |
|
* The set is backed by the map, so changes to the map are |
1775 |
|
* reflected in the set, and vice-versa. The set supports element |
1776 |
|
* removal, which removes the corresponding mapping from the map, |
1784 |
|
* and guarantees to traverse elements as they existed upon |
1785 |
|
* construction of the iterator, and may (but is not guaranteed to) |
1786 |
|
* reflect any modifications subsequent to construction. |
1787 |
+ |
* |
1788 |
+ |
* @return a set view of the keys contained in this map, sorted in |
1789 |
+ |
* ascending order |
1790 |
|
*/ |
1791 |
< |
public Set<K> descendingKeySet() { |
1792 |
< |
/* |
1793 |
< |
* Note: Lazy initialization works here and for other views |
1992 |
< |
* because view classes are stateless/immutable so it doesn't |
1993 |
< |
* matter wrt correctness if more than one is created (which |
1994 |
< |
* will only rarely happen). Even so, the following idiom |
1995 |
< |
* conservatively ensures that the method returns the one it |
1996 |
< |
* created if it does so, not one created by another racing |
1997 |
< |
* thread. |
1998 |
< |
*/ |
1999 |
< |
DescendingKeySet ks = descendingKeySet; |
2000 |
< |
return (ks != null) ? ks : (descendingKeySet = new DescendingKeySet()); |
1791 |
> |
public NavigableSet<K> navigableKeySet() { |
1792 |
> |
KeySet ks = keySet; |
1793 |
> |
return (ks != null) ? ks : (keySet = new KeySet(this)); |
1794 |
|
} |
1795 |
|
|
1796 |
|
/** |
1813 |
|
*/ |
1814 |
|
public Collection<V> values() { |
1815 |
|
Values vs = values; |
1816 |
< |
return (vs != null) ? vs : (values = new Values()); |
1816 |
> |
return (vs != null) ? vs : (values = new Values(this)); |
1817 |
|
} |
1818 |
|
|
1819 |
|
/** |
1842 |
|
*/ |
1843 |
|
public Set<Map.Entry<K,V>> entrySet() { |
1844 |
|
EntrySet es = entrySet; |
1845 |
< |
return (es != null) ? es : (entrySet = new EntrySet()); |
1845 |
> |
return (es != null) ? es : (entrySet = new EntrySet(this)); |
1846 |
|
} |
1847 |
|
|
1848 |
< |
/** |
1849 |
< |
* Returns a {@link Set} view of the mappings contained in this map. |
1850 |
< |
* The set's iterator returns the entries in descending key order. |
1851 |
< |
* The set is backed by the map, so changes to the map are |
1852 |
< |
* reflected in the set, and vice-versa. The set supports element |
1853 |
< |
* removal, which removes the corresponding mapping from the map, |
1854 |
< |
* via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, |
1855 |
< |
* <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt> |
2063 |
< |
* operations. It does not support the <tt>add</tt> or |
2064 |
< |
* <tt>addAll</tt> operations. |
2065 |
< |
* |
2066 |
< |
* <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator |
2067 |
< |
* that will never throw {@link ConcurrentModificationException}, |
2068 |
< |
* and guarantees to traverse elements as they existed upon |
2069 |
< |
* construction of the iterator, and may (but is not guaranteed to) |
2070 |
< |
* reflect any modifications subsequent to construction. |
2071 |
< |
* |
2072 |
< |
* <p>The <tt>Map.Entry</tt> elements returned by |
2073 |
< |
* <tt>iterator.next()</tt> do <em>not</em> support the |
2074 |
< |
* <tt>setValue</tt> operation. |
2075 |
< |
*/ |
2076 |
< |
public Set<Map.Entry<K,V>> descendingEntrySet() { |
2077 |
< |
DescendingEntrySet es = descendingEntrySet; |
2078 |
< |
return (es != null) ? es : (descendingEntrySet = new DescendingEntrySet()); |
1848 |
> |
public ConcurrentNavigableMap<K,V> descendingMap() { |
1849 |
> |
ConcurrentNavigableMap<K,V> dm = descendingMap; |
1850 |
> |
return (dm != null) ? dm : (descendingMap = new SubMap<K,V> |
1851 |
> |
(this, null, false, null, false, true)); |
1852 |
> |
} |
1853 |
> |
|
1854 |
> |
public NavigableSet<K> descendingKeySet() { |
1855 |
> |
return descendingMap().navigableKeySet(); |
1856 |
|
} |
1857 |
|
|
1858 |
|
/* ---------------- AbstractMap Overrides -------------- */ |
2004 |
|
* @throws NullPointerException if <tt>fromKey</tt> or <tt>toKey</tt> is null |
2005 |
|
* @throws IllegalArgumentException {@inheritDoc} |
2006 |
|
*/ |
2007 |
< |
public ConcurrentNavigableMap<K,V> navigableSubMap(K fromKey, K toKey) { |
2007 |
> |
public ConcurrentNavigableMap<K,V> navigableSubMap(K fromKey, |
2008 |
> |
boolean fromInclusive, |
2009 |
> |
K toKey, |
2010 |
> |
boolean toInclusive) { |
2011 |
|
if (fromKey == null || toKey == null) |
2012 |
|
throw new NullPointerException(); |
2013 |
< |
return new ConcurrentSkipListSubMap<K,V>(this, fromKey, toKey); |
2013 |
> |
return new SubMap<K,V> |
2014 |
> |
(this, fromKey, fromInclusive, toKey, toInclusive, false); |
2015 |
|
} |
2016 |
|
|
2017 |
|
/** |
2019 |
|
* @throws NullPointerException if <tt>toKey</tt> is null |
2020 |
|
* @throws IllegalArgumentException {@inheritDoc} |
2021 |
|
*/ |
2022 |
< |
public ConcurrentNavigableMap<K,V> navigableHeadMap(K toKey) { |
2022 |
> |
public ConcurrentNavigableMap<K,V> navigableHeadMap(K toKey, |
2023 |
> |
boolean inclusive) { |
2024 |
|
if (toKey == null) |
2025 |
|
throw new NullPointerException(); |
2026 |
< |
return new ConcurrentSkipListSubMap<K,V>(this, null, toKey); |
2026 |
> |
return new SubMap<K,V> |
2027 |
> |
(this, null, false, toKey, inclusive, false); |
2028 |
|
} |
2029 |
|
|
2030 |
|
/** |
2032 |
|
* @throws NullPointerException if <tt>fromKey</tt> is null |
2033 |
|
* @throws IllegalArgumentException {@inheritDoc} |
2034 |
|
*/ |
2035 |
< |
public ConcurrentNavigableMap<K,V> navigableTailMap(K fromKey) { |
2035 |
> |
public ConcurrentNavigableMap<K,V> navigableTailMap(K fromKey, |
2036 |
> |
boolean inclusive) { |
2037 |
|
if (fromKey == null) |
2038 |
|
throw new NullPointerException(); |
2039 |
< |
return new ConcurrentSkipListSubMap<K,V>(this, fromKey, null); |
2039 |
> |
return new SubMap<K,V> |
2040 |
> |
(this, fromKey, inclusive, null, false, false); |
2041 |
|
} |
2042 |
|
|
2043 |
|
/** |
2046 |
|
* @throws IllegalArgumentException {@inheritDoc} |
2047 |
|
*/ |
2048 |
|
public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey) { |
2049 |
< |
return navigableSubMap(fromKey, toKey); |
2049 |
> |
return navigableSubMap(fromKey, true, toKey, false); |
2050 |
|
} |
2051 |
|
|
2052 |
|
/** |
2055 |
|
* @throws IllegalArgumentException {@inheritDoc} |
2056 |
|
*/ |
2057 |
|
public ConcurrentNavigableMap<K,V> headMap(K toKey) { |
2058 |
< |
return navigableHeadMap(toKey); |
2058 |
> |
return navigableHeadMap(toKey, false); |
2059 |
|
} |
2060 |
|
|
2061 |
|
/** |
2064 |
|
* @throws IllegalArgumentException {@inheritDoc} |
2065 |
|
*/ |
2066 |
|
public ConcurrentNavigableMap<K,V> tailMap(K fromKey) { |
2067 |
< |
return navigableTailMap(fromKey); |
2067 |
> |
return navigableTailMap(fromKey, true); |
2068 |
|
} |
2069 |
|
|
2070 |
|
/* ---------------- Relational operations -------------- */ |
2219 |
|
/* ---------------- Iterators -------------- */ |
2220 |
|
|
2221 |
|
/** |
2222 |
< |
* Base of ten kinds of iterator classes: |
2438 |
< |
* ascending: {map, submap} X {key, value, entry} |
2439 |
< |
* descending: {map, submap} X {key, entry} |
2222 |
> |
* Base of iterator classes: |
2223 |
|
*/ |
2224 |
< |
abstract class Iter { |
2224 |
> |
abstract class Iter<T> implements Iterator<T> { |
2225 |
|
/** the last node returned by next() */ |
2226 |
|
Node<K,V> last; |
2227 |
|
/** the next node to return from next(); */ |
2229 |
|
/** Cache of next value field to maintain weak consistency */ |
2230 |
|
Object nextValue; |
2231 |
|
|
2449 |
– |
Iter() {} |
2450 |
– |
|
2451 |
– |
public final boolean hasNext() { |
2452 |
– |
return next != null; |
2453 |
– |
} |
2454 |
– |
|
2232 |
|
/** Initializes ascending iterator for entire range. */ |
2233 |
< |
final void initAscending() { |
2233 |
> |
Iter() { |
2234 |
|
for (;;) { |
2235 |
|
next = findFirst(); |
2236 |
|
if (next == null) |
2241 |
|
} |
2242 |
|
} |
2243 |
|
|
2244 |
< |
/** |
2245 |
< |
* Initializes ascending iterator starting at given least key, |
2469 |
< |
* or first node if least is <tt>null</tt>, but not greater or |
2470 |
< |
* equal to fence, or end if fence is <tt>null</tt>. |
2471 |
< |
*/ |
2472 |
< |
final void initAscending(K least, K fence) { |
2473 |
< |
for (;;) { |
2474 |
< |
next = findCeiling(least); |
2475 |
< |
if (next == null) |
2476 |
< |
break; |
2477 |
< |
nextValue = next.value; |
2478 |
< |
if (nextValue != null && nextValue != next) { |
2479 |
< |
if (fence != null && compare(fence, next.key) <= 0) { |
2480 |
< |
next = null; |
2481 |
< |
nextValue = null; |
2482 |
< |
} |
2483 |
< |
break; |
2484 |
< |
} |
2485 |
< |
} |
2486 |
< |
} |
2487 |
< |
/** Advances next to higher entry. */ |
2488 |
< |
final void ascend() { |
2489 |
< |
if ((last = next) == null) |
2490 |
< |
throw new NoSuchElementException(); |
2491 |
< |
for (;;) { |
2492 |
< |
next = next.next; |
2493 |
< |
if (next == null) |
2494 |
< |
break; |
2495 |
< |
nextValue = next.value; |
2496 |
< |
if (nextValue != null && nextValue != next) |
2497 |
< |
break; |
2498 |
< |
} |
2244 |
> |
public final boolean hasNext() { |
2245 |
> |
return next != null; |
2246 |
|
} |
2247 |
|
|
2248 |
< |
/** |
2249 |
< |
* Version of ascend for submaps to stop at fence |
2503 |
< |
*/ |
2504 |
< |
final void ascend(K fence) { |
2248 |
> |
/** Advances next to higher entry. */ |
2249 |
> |
final void advance() { |
2250 |
|
if ((last = next) == null) |
2251 |
|
throw new NoSuchElementException(); |
2252 |
|
for (;;) { |
2254 |
|
if (next == null) |
2255 |
|
break; |
2256 |
|
nextValue = next.value; |
2512 |
– |
if (nextValue != null && nextValue != next) { |
2513 |
– |
if (fence != null && compare(fence, next.key) <= 0) { |
2514 |
– |
next = null; |
2515 |
– |
nextValue = null; |
2516 |
– |
} |
2517 |
– |
break; |
2518 |
– |
} |
2519 |
– |
} |
2520 |
– |
} |
2521 |
– |
|
2522 |
– |
/** Initializes descending iterator for entire range. */ |
2523 |
– |
final void initDescending() { |
2524 |
– |
for (;;) { |
2525 |
– |
next = findLast(); |
2526 |
– |
if (next == null) |
2527 |
– |
break; |
2528 |
– |
nextValue = next.value; |
2529 |
– |
if (nextValue != null && nextValue != next) |
2530 |
– |
break; |
2531 |
– |
} |
2532 |
– |
} |
2533 |
– |
|
2534 |
– |
/** |
2535 |
– |
* Initializes descending iterator starting at key less |
2536 |
– |
* than or equal to given fence key, or |
2537 |
– |
* last node if fence is <tt>null</tt>, but not less than |
2538 |
– |
* least, or beginning if least is <tt>null</tt>. |
2539 |
– |
*/ |
2540 |
– |
final void initDescending(K least, K fence) { |
2541 |
– |
for (;;) { |
2542 |
– |
next = findLower(fence); |
2543 |
– |
if (next == null) |
2544 |
– |
break; |
2545 |
– |
nextValue = next.value; |
2546 |
– |
if (nextValue != null && nextValue != next) { |
2547 |
– |
if (least != null && compare(least, next.key) > 0) { |
2548 |
– |
next = null; |
2549 |
– |
nextValue = null; |
2550 |
– |
} |
2551 |
– |
break; |
2552 |
– |
} |
2553 |
– |
} |
2554 |
– |
} |
2555 |
– |
|
2556 |
– |
/** Advances next to lower entry. */ |
2557 |
– |
final void descend() { |
2558 |
– |
if ((last = next) == null) |
2559 |
– |
throw new NoSuchElementException(); |
2560 |
– |
K k = last.key; |
2561 |
– |
for (;;) { |
2562 |
– |
next = findNear(k, LT); |
2563 |
– |
if (next == null) |
2564 |
– |
break; |
2565 |
– |
nextValue = next.value; |
2257 |
|
if (nextValue != null && nextValue != next) |
2258 |
|
break; |
2259 |
|
} |
2260 |
|
} |
2261 |
|
|
2571 |
– |
/** |
2572 |
– |
* Version of descend for submaps to stop at least |
2573 |
– |
*/ |
2574 |
– |
final void descend(K least) { |
2575 |
– |
if ((last = next) == null) |
2576 |
– |
throw new NoSuchElementException(); |
2577 |
– |
K k = last.key; |
2578 |
– |
for (;;) { |
2579 |
– |
next = findNear(k, LT); |
2580 |
– |
if (next == null) |
2581 |
– |
break; |
2582 |
– |
nextValue = next.value; |
2583 |
– |
if (nextValue != null && nextValue != next) { |
2584 |
– |
if (least != null && compare(least, next.key) > 0) { |
2585 |
– |
next = null; |
2586 |
– |
nextValue = null; |
2587 |
– |
} |
2588 |
– |
break; |
2589 |
– |
} |
2590 |
– |
} |
2591 |
– |
} |
2592 |
– |
|
2262 |
|
public void remove() { |
2263 |
|
Node<K,V> l = last; |
2264 |
|
if (l == null) |
2270 |
|
|
2271 |
|
} |
2272 |
|
|
2273 |
< |
final class ValueIterator extends Iter implements Iterator<V> { |
2605 |
< |
ValueIterator() { |
2606 |
< |
initAscending(); |
2607 |
< |
} |
2608 |
< |
public V next() { |
2609 |
< |
Object v = nextValue; |
2610 |
< |
ascend(); |
2611 |
< |
return (V)v; |
2612 |
< |
} |
2613 |
< |
} |
2614 |
< |
|
2615 |
< |
final class KeyIterator extends Iter implements Iterator<K> { |
2616 |
< |
KeyIterator() { |
2617 |
< |
initAscending(); |
2618 |
< |
} |
2619 |
< |
public K next() { |
2620 |
< |
Node<K,V> n = next; |
2621 |
< |
ascend(); |
2622 |
< |
return n.key; |
2623 |
< |
} |
2624 |
< |
} |
2625 |
< |
|
2626 |
< |
class SubMapValueIterator extends Iter implements Iterator<V> { |
2627 |
< |
final K fence; |
2628 |
< |
SubMapValueIterator(K least, K fence) { |
2629 |
< |
initAscending(least, fence); |
2630 |
< |
this.fence = fence; |
2631 |
< |
} |
2632 |
< |
|
2273 |
> |
final class ValueIterator extends Iter<V> { |
2274 |
|
public V next() { |
2275 |
|
Object v = nextValue; |
2276 |
< |
ascend(fence); |
2276 |
> |
advance(); |
2277 |
|
return (V)v; |
2278 |
|
} |
2279 |
|
} |
2280 |
|
|
2281 |
< |
final class SubMapKeyIterator extends Iter implements Iterator<K> { |
2641 |
< |
final K fence; |
2642 |
< |
SubMapKeyIterator(K least, K fence) { |
2643 |
< |
initAscending(least, fence); |
2644 |
< |
this.fence = fence; |
2645 |
< |
} |
2646 |
< |
|
2647 |
< |
public K next() { |
2648 |
< |
Node<K,V> n = next; |
2649 |
< |
ascend(fence); |
2650 |
< |
return n.key; |
2651 |
< |
} |
2652 |
< |
} |
2653 |
< |
|
2654 |
< |
final class DescendingKeyIterator extends Iter implements Iterator<K> { |
2655 |
< |
DescendingKeyIterator() { |
2656 |
< |
initDescending(); |
2657 |
< |
} |
2281 |
> |
final class KeyIterator extends Iter<K> { |
2282 |
|
public K next() { |
2283 |
|
Node<K,V> n = next; |
2284 |
< |
descend(); |
2284 |
> |
advance(); |
2285 |
|
return n.key; |
2286 |
|
} |
2287 |
|
} |
2288 |
|
|
2289 |
< |
final class DescendingSubMapKeyIterator extends Iter implements Iterator<K> { |
2666 |
< |
final K least; |
2667 |
< |
DescendingSubMapKeyIterator(K least, K fence) { |
2668 |
< |
initDescending(least, fence); |
2669 |
< |
this.least = least; |
2670 |
< |
} |
2671 |
< |
|
2672 |
< |
public K next() { |
2673 |
< |
Node<K,V> n = next; |
2674 |
< |
descend(least); |
2675 |
< |
return n.key; |
2676 |
< |
} |
2677 |
< |
} |
2678 |
< |
|
2679 |
< |
final class EntryIterator extends Iter implements Iterator<Map.Entry<K,V>> { |
2680 |
< |
EntryIterator() { |
2681 |
< |
initAscending(); |
2682 |
< |
} |
2683 |
< |
public Map.Entry<K,V> next() { |
2684 |
< |
Node<K,V> n = next; |
2685 |
< |
V v = (V)nextValue; |
2686 |
< |
ascend(); |
2687 |
< |
return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); |
2688 |
< |
} |
2689 |
< |
} |
2690 |
< |
|
2691 |
< |
final class SubMapEntryIterator extends Iter implements Iterator<Map.Entry<K,V>> { |
2692 |
< |
final K fence; |
2693 |
< |
SubMapEntryIterator(K least, K fence) { |
2694 |
< |
initAscending(least, fence); |
2695 |
< |
this.fence = fence; |
2696 |
< |
} |
2697 |
< |
|
2698 |
< |
public Map.Entry<K,V> next() { |
2699 |
< |
Node<K,V> n = next; |
2700 |
< |
V v = (V)nextValue; |
2701 |
< |
ascend(fence); |
2702 |
< |
return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); |
2703 |
< |
} |
2704 |
< |
} |
2705 |
< |
|
2706 |
< |
final class DescendingEntryIterator extends Iter implements Iterator<Map.Entry<K,V>> { |
2707 |
< |
DescendingEntryIterator() { |
2708 |
< |
initDescending(); |
2709 |
< |
} |
2710 |
< |
public Map.Entry<K,V> next() { |
2711 |
< |
Node<K,V> n = next; |
2712 |
< |
V v = (V)nextValue; |
2713 |
< |
descend(); |
2714 |
< |
return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); |
2715 |
< |
} |
2716 |
< |
} |
2717 |
< |
|
2718 |
< |
final class DescendingSubMapEntryIterator extends Iter implements Iterator<Map.Entry<K,V>> { |
2719 |
< |
final K least; |
2720 |
< |
DescendingSubMapEntryIterator(K least, K fence) { |
2721 |
< |
initDescending(least, fence); |
2722 |
< |
this.least = least; |
2723 |
< |
} |
2724 |
< |
|
2289 |
> |
final class EntryIterator extends Iter<Map.Entry<K,V>> { |
2290 |
|
public Map.Entry<K,V> next() { |
2291 |
|
Node<K,V> n = next; |
2292 |
|
V v = (V)nextValue; |
2293 |
< |
descend(least); |
2293 |
> |
advance(); |
2294 |
|
return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); |
2295 |
|
} |
2296 |
|
} |
2297 |
|
|
2298 |
< |
// Factory methods for iterators needed by submaps and/or |
2734 |
< |
// ConcurrentSkipListSet |
2298 |
> |
// Factory methods for iterators needed by ConcurrentSkipListSet etc |
2299 |
|
|
2300 |
|
Iterator<K> keyIterator() { |
2301 |
|
return new KeyIterator(); |
2302 |
|
} |
2303 |
|
|
2304 |
< |
Iterator<K> descendingKeyIterator() { |
2305 |
< |
return new DescendingKeyIterator(); |
2742 |
< |
} |
2743 |
< |
|
2744 |
< |
SubMapEntryIterator subMapEntryIterator(K least, K fence) { |
2745 |
< |
return new SubMapEntryIterator(least, fence); |
2746 |
< |
} |
2747 |
< |
|
2748 |
< |
DescendingSubMapEntryIterator descendingSubMapEntryIterator(K least, K fence) { |
2749 |
< |
return new DescendingSubMapEntryIterator(least, fence); |
2750 |
< |
} |
2751 |
< |
|
2752 |
< |
SubMapKeyIterator subMapKeyIterator(K least, K fence) { |
2753 |
< |
return new SubMapKeyIterator(least, fence); |
2754 |
< |
} |
2755 |
< |
|
2756 |
< |
DescendingSubMapKeyIterator descendingSubMapKeyIterator(K least, K fence) { |
2757 |
< |
return new DescendingSubMapKeyIterator(least, fence); |
2304 |
> |
Iterator<V> valueIterator() { |
2305 |
> |
return new ValueIterator(); |
2306 |
|
} |
2307 |
|
|
2308 |
< |
SubMapValueIterator subMapValueIterator(K least, K fence) { |
2309 |
< |
return new SubMapValueIterator(least, fence); |
2308 |
> |
Iterator<Map.Entry<K,V>> entryIterator() { |
2309 |
> |
return new EntryIterator(); |
2310 |
|
} |
2311 |
|
|
2312 |
< |
/* ---------------- Views -------------- */ |
2313 |
< |
|
2314 |
< |
class KeySet extends AbstractSet<K> { |
2315 |
< |
public Iterator<K> iterator() { |
2316 |
< |
return new KeyIterator(); |
2317 |
< |
} |
2318 |
< |
public boolean isEmpty() { |
2319 |
< |
return ConcurrentSkipListMap.this.isEmpty(); |
2320 |
< |
} |
2321 |
< |
public int size() { |
2322 |
< |
return ConcurrentSkipListMap.this.size(); |
2323 |
< |
} |
2324 |
< |
public boolean contains(Object o) { |
2325 |
< |
return ConcurrentSkipListMap.this.containsKey(o); |
2326 |
< |
} |
2327 |
< |
public boolean remove(Object o) { |
2328 |
< |
return ConcurrentSkipListMap.this.removep(o); |
2329 |
< |
} |
2330 |
< |
public void clear() { |
2331 |
< |
ConcurrentSkipListMap.this.clear(); |
2312 |
> |
/* ---------------- View Classes -------------- */ |
2313 |
> |
|
2314 |
> |
/* |
2315 |
> |
* View classes are static, delegating to a ConcurrentNavigableMap |
2316 |
> |
* to allow use by SubMaps, which outweighs the ugliness of |
2317 |
> |
* needing type-tests for Iterator methods. |
2318 |
> |
*/ |
2319 |
> |
|
2320 |
> |
static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> { |
2321 |
> |
private final ConcurrentNavigableMap<E,Object> m; |
2322 |
> |
KeySet(ConcurrentNavigableMap<E,Object> map) { m = map; } |
2323 |
> |
public int size() { return m.size(); } |
2324 |
> |
public boolean isEmpty() { return m.isEmpty(); } |
2325 |
> |
public boolean contains(Object o) { return m.containsKey(o); } |
2326 |
> |
public boolean remove(Object o) { return m.remove(o) != null; } |
2327 |
> |
public void clear() { m.clear(); } |
2328 |
> |
public E lower(E e) { return m.lowerKey(e); } |
2329 |
> |
public E floor(E e) { return m.floorKey(e); } |
2330 |
> |
public E ceiling(E e) { return m.ceilingKey(e); } |
2331 |
> |
public E higher(E e) { return m.higherKey(e); } |
2332 |
> |
public Comparator<? super E> comparator() { return m.comparator(); } |
2333 |
> |
public E first() { return m.firstKey(); } |
2334 |
> |
public E last() { return m.lastKey(); } |
2335 |
> |
public E pollFirst() { |
2336 |
> |
Map.Entry<E,Object> e = m.pollFirstEntry(); |
2337 |
> |
return e == null? null : e.getKey(); |
2338 |
> |
} |
2339 |
> |
public E pollLast() { |
2340 |
> |
Map.Entry<E,Object> e = m.pollLastEntry(); |
2341 |
> |
return e == null? null : e.getKey(); |
2342 |
> |
} |
2343 |
> |
public Iterator<E> iterator() { |
2344 |
> |
if (m instanceof ConcurrentSkipListMap) |
2345 |
> |
return ((ConcurrentSkipListMap<E,Object>)m).keyIterator(); |
2346 |
> |
else |
2347 |
> |
return ((ConcurrentSkipListMap.SubMap<E,Object>)m).keyIterator(); |
2348 |
|
} |
2349 |
|
public boolean equals(Object o) { |
2350 |
|
if (o == this) |
2360 |
|
return false; |
2361 |
|
} |
2362 |
|
} |
2363 |
< |
} |
2364 |
< |
|
2365 |
< |
class DescendingKeySet extends KeySet { |
2366 |
< |
public Iterator<K> iterator() { |
2367 |
< |
return new DescendingKeyIterator(); |
2363 |
> |
public Iterator<E> descendingIterator() { |
2364 |
> |
return descendingSet().iterator(); |
2365 |
> |
} |
2366 |
> |
public NavigableSet<E> navigableSubSet(E fromElement, |
2367 |
> |
boolean fromInclusive, |
2368 |
> |
E toElement, |
2369 |
> |
boolean toInclusive) { |
2370 |
> |
return new ConcurrentSkipListSet<E> |
2371 |
> |
(m.navigableSubMap(fromElement, fromInclusive, |
2372 |
> |
toElement, toInclusive)); |
2373 |
> |
} |
2374 |
> |
public NavigableSet<E> navigableHeadSet(E toElement, boolean inclusive) { |
2375 |
> |
return new ConcurrentSkipListSet<E>(m.navigableHeadMap(toElement, inclusive)); |
2376 |
> |
} |
2377 |
> |
public NavigableSet<E> navigableTailSet(E fromElement, boolean inclusive) { |
2378 |
> |
return new ConcurrentSkipListSet<E>(m.navigableTailMap(fromElement, inclusive)); |
2379 |
> |
} |
2380 |
> |
public SortedSet<E> subSet(E fromElement, E toElement) { |
2381 |
> |
return navigableSubSet(fromElement, true, toElement, false); |
2382 |
> |
} |
2383 |
> |
public SortedSet<E> headSet(E toElement) { |
2384 |
> |
return navigableHeadSet(toElement, false); |
2385 |
> |
} |
2386 |
> |
public SortedSet<E> tailSet(E fromElement) { |
2387 |
> |
return navigableTailSet(fromElement, true); |
2388 |
> |
} |
2389 |
> |
public NavigableSet<E> descendingSet() { |
2390 |
> |
return new ConcurrentSkipListSet(m.descendingMap()); |
2391 |
|
} |
2392 |
|
} |
2393 |
|
|
2394 |
< |
final class Values extends AbstractCollection<V> { |
2395 |
< |
public Iterator<V> iterator() { |
2396 |
< |
return new ValueIterator(); |
2394 |
> |
static final class Values<E> extends AbstractCollection<E> { |
2395 |
> |
private final ConcurrentNavigableMap<Object, E> m; |
2396 |
> |
Values(ConcurrentNavigableMap<Object, E> map) { |
2397 |
> |
m = map; |
2398 |
> |
} |
2399 |
> |
public Iterator<E> iterator() { |
2400 |
> |
if (m instanceof ConcurrentSkipListMap) |
2401 |
> |
return ((ConcurrentSkipListMap<Object,E>)m).valueIterator(); |
2402 |
> |
else |
2403 |
> |
return ((SubMap<Object,E>)m).valueIterator(); |
2404 |
|
} |
2405 |
|
public boolean isEmpty() { |
2406 |
< |
return ConcurrentSkipListMap.this.isEmpty(); |
2406 |
> |
return m.isEmpty(); |
2407 |
|
} |
2408 |
|
public int size() { |
2409 |
< |
return ConcurrentSkipListMap.this.size(); |
2409 |
> |
return m.size(); |
2410 |
|
} |
2411 |
|
public boolean contains(Object o) { |
2412 |
< |
return ConcurrentSkipListMap.this.containsValue(o); |
2412 |
> |
return m.containsValue(o); |
2413 |
|
} |
2414 |
|
public void clear() { |
2415 |
< |
ConcurrentSkipListMap.this.clear(); |
2415 |
> |
m.clear(); |
2416 |
|
} |
2417 |
|
} |
2418 |
|
|
2419 |
< |
class EntrySet extends AbstractSet<Map.Entry<K,V>> { |
2420 |
< |
public Iterator<Map.Entry<K,V>> iterator() { |
2421 |
< |
return new EntryIterator(); |
2419 |
> |
static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> { |
2420 |
> |
private final ConcurrentNavigableMap<K1, V1> m; |
2421 |
> |
EntrySet(ConcurrentNavigableMap<K1, V1> map) { |
2422 |
> |
m = map; |
2423 |
> |
} |
2424 |
> |
|
2425 |
> |
public Iterator<Map.Entry<K1,V1>> iterator() { |
2426 |
> |
if (m instanceof ConcurrentSkipListMap) |
2427 |
> |
return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator(); |
2428 |
> |
else |
2429 |
> |
return ((SubMap<K1,V1>)m).entryIterator(); |
2430 |
|
} |
2431 |
+ |
|
2432 |
|
public boolean contains(Object o) { |
2433 |
|
if (!(o instanceof Map.Entry)) |
2434 |
|
return false; |
2435 |
< |
Map.Entry<K,V> e = (Map.Entry<K,V>)o; |
2436 |
< |
V v = ConcurrentSkipListMap.this.get(e.getKey()); |
2435 |
> |
Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o; |
2436 |
> |
V1 v = m.get(e.getKey()); |
2437 |
|
return v != null && v.equals(e.getValue()); |
2438 |
|
} |
2439 |
|
public boolean remove(Object o) { |
2440 |
|
if (!(o instanceof Map.Entry)) |
2441 |
|
return false; |
2442 |
< |
Map.Entry<K,V> e = (Map.Entry<K,V>)o; |
2443 |
< |
return ConcurrentSkipListMap.this.remove(e.getKey(), |
2442 |
> |
Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o; |
2443 |
> |
return m.remove(e.getKey(), |
2444 |
|
e.getValue()); |
2445 |
|
} |
2446 |
|
public boolean isEmpty() { |
2447 |
< |
return ConcurrentSkipListMap.this.isEmpty(); |
2447 |
> |
return m.isEmpty(); |
2448 |
|
} |
2449 |
|
public int size() { |
2450 |
< |
return ConcurrentSkipListMap.this.size(); |
2450 |
> |
return m.size(); |
2451 |
|
} |
2452 |
|
public void clear() { |
2453 |
< |
ConcurrentSkipListMap.this.clear(); |
2453 |
> |
m.clear(); |
2454 |
|
} |
2455 |
|
public boolean equals(Object o) { |
2456 |
|
if (o == this) |
2468 |
|
} |
2469 |
|
} |
2470 |
|
|
2868 |
– |
class DescendingEntrySet extends EntrySet { |
2869 |
– |
public Iterator<Map.Entry<K,V>> iterator() { |
2870 |
– |
return new DescendingEntryIterator(); |
2871 |
– |
} |
2872 |
– |
} |
2873 |
– |
|
2471 |
|
/** |
2472 |
|
* Submaps returned by {@link ConcurrentSkipListMap} submap operations |
2473 |
|
* represent a subrange of mappings of their underlying |
2478 |
|
* constructed only using the <tt>subMap</tt>, <tt>headMap</tt>, and |
2479 |
|
* <tt>tailMap</tt> methods of their underlying maps. |
2480 |
|
*/ |
2481 |
< |
static class ConcurrentSkipListSubMap<K,V> extends AbstractMap<K,V> |
2482 |
< |
implements ConcurrentNavigableMap<K,V>, java.io.Serializable { |
2483 |
< |
|
2481 |
> |
static final class SubMap<K,V> extends AbstractMap<K,V> |
2482 |
> |
implements ConcurrentNavigableMap<K,V>, Cloneable, |
2483 |
> |
java.io.Serializable { |
2484 |
|
private static final long serialVersionUID = -7647078645895051609L; |
2485 |
|
|
2486 |
|
/** Underlying map */ |
2487 |
|
private final ConcurrentSkipListMap<K,V> m; |
2488 |
|
/** lower bound key, or null if from start */ |
2489 |
< |
private final K least; |
2490 |
< |
/** upper fence key, or null if to end */ |
2491 |
< |
private final K fence; |
2489 |
> |
private final K lo; |
2490 |
> |
/** upper bound key, or null if to end */ |
2491 |
> |
private final K hi; |
2492 |
> |
/** inclusion flag for lo */ |
2493 |
> |
private final boolean loInclusive; |
2494 |
> |
/** inclusion flag for hi */ |
2495 |
> |
private final boolean hiInclusive; |
2496 |
> |
/** direction */ |
2497 |
> |
private final boolean isDescending; |
2498 |
> |
|
2499 |
|
// Lazily initialized view holders |
2500 |
< |
private transient Set<K> keySetView; |
2500 |
> |
private transient KeySet<K> keySetView; |
2501 |
|
private transient Set<Map.Entry<K,V>> entrySetView; |
2502 |
|
private transient Collection<V> valuesView; |
2899 |
– |
private transient Set<K> descendingKeySetView; |
2900 |
– |
private transient Set<Map.Entry<K,V>> descendingEntrySetView; |
2503 |
|
|
2504 |
|
/** |
2505 |
< |
* Creates a new submap. |
2506 |
< |
* @param least inclusive least value, or <tt>null</tt> if from start |
2507 |
< |
* @param fence exclusive upper bound or <tt>null</tt> if to end |
2508 |
< |
* @throws IllegalArgumentException if least and fence nonnull |
2509 |
< |
* and least greater than fence |
2510 |
< |
*/ |
2511 |
< |
ConcurrentSkipListSubMap(ConcurrentSkipListMap<K,V> map, |
2512 |
< |
K least, K fence) { |
2911 |
< |
if (least != null && |
2912 |
< |
fence != null && |
2913 |
< |
map.compare(least, fence) > 0) |
2505 |
> |
* Creates a new submap, initializing all fields |
2506 |
> |
*/ |
2507 |
> |
SubMap(ConcurrentSkipListMap<K,V> map, |
2508 |
> |
K fromKey, boolean fromInclusive, |
2509 |
> |
K toKey, boolean toInclusive, |
2510 |
> |
boolean isDescending) { |
2511 |
> |
if (fromKey != null && toKey != null && |
2512 |
> |
map.compare(fromKey, toKey) > 0) |
2513 |
|
throw new IllegalArgumentException("inconsistent range"); |
2514 |
|
this.m = map; |
2515 |
< |
this.least = least; |
2516 |
< |
this.fence = fence; |
2515 |
> |
this.lo = fromKey; |
2516 |
> |
this.hi = toKey; |
2517 |
> |
this.loInclusive = fromInclusive; |
2518 |
> |
this.hiInclusive = toInclusive; |
2519 |
> |
this.isDescending = isDescending; |
2520 |
|
} |
2521 |
|
|
2522 |
|
/* ---------------- Utilities -------------- */ |
2523 |
|
|
2524 |
< |
boolean inHalfOpenRange(K key) { |
2525 |
< |
return m.inHalfOpenRange(key, least, fence); |
2524 |
> |
private boolean tooLow(K key) { |
2525 |
> |
if (lo != null) { |
2526 |
> |
int c = m.compare(key, lo); |
2527 |
> |
if (c < 0 || (c == 0 && !loInclusive)) |
2528 |
> |
return true; |
2529 |
> |
} |
2530 |
> |
return false; |
2531 |
|
} |
2532 |
|
|
2533 |
< |
boolean inOpenRange(K key) { |
2534 |
< |
return m.inOpenRange(key, least, fence); |
2533 |
> |
private boolean tooHigh(K key) { |
2534 |
> |
if (hi != null) { |
2535 |
> |
int c = m.compare(key, hi); |
2536 |
> |
if (c > 0 || (c == 0 && !hiInclusive)) |
2537 |
> |
return true; |
2538 |
> |
} |
2539 |
> |
return false; |
2540 |
|
} |
2541 |
|
|
2542 |
< |
ConcurrentSkipListMap.Node<K,V> firstNode() { |
2543 |
< |
return m.findCeiling(least); |
2542 |
> |
private boolean inBounds(K key) { |
2543 |
> |
return !tooLow(key) && !tooHigh(key); |
2544 |
|
} |
2545 |
|
|
2546 |
< |
ConcurrentSkipListMap.Node<K,V> lastNode() { |
2547 |
< |
return m.findLower(fence); |
2546 |
> |
private void checkKeyBounds(K key) throws IllegalArgumentException { |
2547 |
> |
if (key == null) |
2548 |
> |
throw new NullPointerException(); |
2549 |
> |
if (!inBounds(key)) |
2550 |
> |
throw new IllegalArgumentException("key out of range"); |
2551 |
|
} |
2552 |
|
|
2553 |
< |
boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) { |
2554 |
< |
return (n != null && |
2555 |
< |
(fence == null || |
2556 |
< |
n.key == null || // pass by markers and headers |
2557 |
< |
m.compare(fence, n.key) > 0)); |
2553 |
> |
/** |
2554 |
> |
* Returns true if node key is less than upper bound of range |
2555 |
> |
*/ |
2556 |
> |
private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) { |
2557 |
> |
if (n == null) |
2558 |
> |
return false; |
2559 |
> |
if (hi == null) |
2560 |
> |
return true; |
2561 |
> |
K k = n.key; |
2562 |
> |
if (k == null) // pass by markers and headers |
2563 |
> |
return true; |
2564 |
> |
int c = m.compare(k, hi); |
2565 |
> |
if (c > 0 || (c == 0 && !hiInclusive)) |
2566 |
> |
return false; |
2567 |
> |
return true; |
2568 |
|
} |
2569 |
|
|
2570 |
< |
void checkKey(K key) throws IllegalArgumentException { |
2571 |
< |
if (!inHalfOpenRange(key)) |
2572 |
< |
throw new IllegalArgumentException("key out of range"); |
2570 |
> |
/** |
2571 |
> |
* Returns lowest node. This node might not be in range, so |
2572 |
> |
* most usages need to check bounds |
2573 |
> |
*/ |
2574 |
> |
private ConcurrentSkipListMap.Node<K,V> loNode() { |
2575 |
> |
if (lo == null) |
2576 |
> |
return m.findFirst(); |
2577 |
> |
else if (loInclusive) |
2578 |
> |
return m.findNear(lo, m.GT|m.EQ); |
2579 |
> |
else |
2580 |
> |
return m.findNear(lo, m.GT); |
2581 |
|
} |
2582 |
|
|
2583 |
|
/** |
2584 |
< |
* Returns underlying map. Needed by ConcurrentSkipListSet |
2585 |
< |
* @return the backing map |
2584 |
> |
* Returns highest node. This node might not be in range, so |
2585 |
> |
* most usages need to check bounds |
2586 |
|
*/ |
2587 |
< |
ConcurrentSkipListMap<K,V> getMap() { |
2588 |
< |
return m; |
2587 |
> |
private ConcurrentSkipListMap.Node<K,V> hiNode() { |
2588 |
> |
if (hi == null) |
2589 |
> |
return m.findLast(); |
2590 |
> |
else if (hiInclusive) |
2591 |
> |
return m.findNear(hi, m.LT|m.EQ); |
2592 |
> |
else |
2593 |
> |
return m.findNear(hi, m.LT); |
2594 |
|
} |
2595 |
|
|
2596 |
|
/** |
2597 |
< |
* Returns least key. Needed by ConcurrentSkipListSet |
2598 |
< |
* @return least key or <tt>null</tt> if from start |
2597 |
> |
* Returns lowest absolute key (ignoring directonality) |
2598 |
> |
*/ |
2599 |
> |
private K lowestKey() { |
2600 |
> |
ConcurrentSkipListMap.Node<K,V> n = loNode(); |
2601 |
> |
if (isBeforeEnd(n)) |
2602 |
> |
return n.key; |
2603 |
> |
else |
2604 |
> |
throw new NoSuchElementException(); |
2605 |
> |
} |
2606 |
> |
|
2607 |
> |
/** |
2608 |
> |
* Returns highest absolute key (ignoring directonality) |
2609 |
|
*/ |
2610 |
< |
K getLeast() { |
2611 |
< |
return least; |
2610 |
> |
private K highestKey() { |
2611 |
> |
ConcurrentSkipListMap.Node<K,V> n = hiNode(); |
2612 |
> |
if (n != null) { |
2613 |
> |
K last = n.key; |
2614 |
> |
if (inBounds(last)) |
2615 |
> |
return last; |
2616 |
> |
} |
2617 |
> |
throw new NoSuchElementException(); |
2618 |
> |
} |
2619 |
> |
|
2620 |
> |
private Map.Entry<K,V> lowestEntry() { |
2621 |
> |
for (;;) { |
2622 |
> |
ConcurrentSkipListMap.Node<K,V> n = loNode(); |
2623 |
> |
if (!isBeforeEnd(n)) |
2624 |
> |
return null; |
2625 |
> |
Map.Entry<K,V> e = n.createSnapshot(); |
2626 |
> |
if (e != null) |
2627 |
> |
return e; |
2628 |
> |
} |
2629 |
> |
} |
2630 |
> |
|
2631 |
> |
private Map.Entry<K,V> highestEntry() { |
2632 |
> |
for (;;) { |
2633 |
> |
ConcurrentSkipListMap.Node<K,V> n = hiNode(); |
2634 |
> |
if (n == null || !inBounds(n.key)) |
2635 |
> |
return null; |
2636 |
> |
Map.Entry<K,V> e = n.createSnapshot(); |
2637 |
> |
if (e != null) |
2638 |
> |
return e; |
2639 |
> |
} |
2640 |
> |
} |
2641 |
> |
|
2642 |
> |
private Map.Entry<K,V> removeLowest() { |
2643 |
> |
for (;;) { |
2644 |
> |
Node<K,V> n = loNode(); |
2645 |
> |
if (n == null) |
2646 |
> |
return null; |
2647 |
> |
K k = n.key; |
2648 |
> |
if (!inBounds(k)) |
2649 |
> |
return null; |
2650 |
> |
V v = m.doRemove(k, null); |
2651 |
> |
if (v != null) |
2652 |
> |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
2653 |
> |
} |
2654 |
> |
} |
2655 |
> |
|
2656 |
> |
private Map.Entry<K,V> removeHighest() { |
2657 |
> |
for (;;) { |
2658 |
> |
Node<K,V> n = hiNode(); |
2659 |
> |
if (n == null) |
2660 |
> |
return null; |
2661 |
> |
K k = n.key; |
2662 |
> |
if (!inBounds(k)) |
2663 |
> |
return null; |
2664 |
> |
V v = m.doRemove(k, null); |
2665 |
> |
if (v != null) |
2666 |
> |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
2667 |
> |
} |
2668 |
|
} |
2669 |
|
|
2670 |
|
/** |
2671 |
< |
* Returns fence key. Needed by ConcurrentSkipListSet |
2968 |
< |
* @return fence key or <tt>null</tt> if to end |
2671 |
> |
* Submap version of ConcurrentSkipListMap.getNearEntry |
2672 |
|
*/ |
2673 |
< |
K getFence() { |
2674 |
< |
return fence; |
2673 |
> |
private Map.Entry<K,V> getNearEntry(K key, int rel) { |
2674 |
> |
if (isDescending) { // adjust relation for direction |
2675 |
> |
if ((rel & m.LT) == 0) |
2676 |
> |
rel |= m.LT; |
2677 |
> |
else |
2678 |
> |
rel &= ~m.LT; |
2679 |
> |
} |
2680 |
> |
if (tooLow(key)) |
2681 |
> |
return ((rel & m.LT) != 0)? null : lowestEntry(); |
2682 |
> |
if (tooHigh(key)) |
2683 |
> |
return ((rel & m.LT) != 0)? highestEntry() : null; |
2684 |
> |
for (;;) { |
2685 |
> |
Node<K,V> n = m.findNear(key, rel); |
2686 |
> |
if (n == null || !inBounds(n.key)) |
2687 |
> |
return null; |
2688 |
> |
K k = n.key; |
2689 |
> |
V v = n.getValidValue(); |
2690 |
> |
if (v != null) |
2691 |
> |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
2692 |
> |
} |
2693 |
|
} |
2694 |
|
|
2695 |
+ |
// Almost the the same as getNearEntry, except for keys |
2696 |
+ |
private K getNearKey(K key, int rel) { |
2697 |
+ |
if (isDescending) { // adjust relation for direction |
2698 |
+ |
if ((rel & m.LT) == 0) |
2699 |
+ |
rel |= m.LT; |
2700 |
+ |
else |
2701 |
+ |
rel &= ~m.LT; |
2702 |
+ |
} |
2703 |
+ |
if (tooLow(key)) { |
2704 |
+ |
if ((rel & m.LT) == 0) { |
2705 |
+ |
ConcurrentSkipListMap.Node<K,V> n = loNode(); |
2706 |
+ |
if (isBeforeEnd(n)) |
2707 |
+ |
return n.key; |
2708 |
+ |
} |
2709 |
+ |
return null; |
2710 |
+ |
} |
2711 |
+ |
if (tooHigh(key)) { |
2712 |
+ |
if ((rel & m.LT) != 0) { |
2713 |
+ |
ConcurrentSkipListMap.Node<K,V> n = hiNode(); |
2714 |
+ |
if (n != null) { |
2715 |
+ |
K last = n.key; |
2716 |
+ |
if (inBounds(last)) |
2717 |
+ |
return last; |
2718 |
+ |
} |
2719 |
+ |
} |
2720 |
+ |
return null; |
2721 |
+ |
} |
2722 |
+ |
for (;;) { |
2723 |
+ |
Node<K,V> n = m.findNear(key, rel); |
2724 |
+ |
if (n == null || !inBounds(n.key)) |
2725 |
+ |
return null; |
2726 |
+ |
K k = n.key; |
2727 |
+ |
V v = n.getValidValue(); |
2728 |
+ |
if (v != null) |
2729 |
+ |
return k; |
2730 |
+ |
} |
2731 |
+ |
} |
2732 |
|
|
2733 |
|
/* ---------------- Map API methods -------------- */ |
2734 |
|
|
2735 |
|
public boolean containsKey(Object key) { |
2736 |
+ |
if (key == null) throw new NullPointerException(); |
2737 |
|
K k = (K)key; |
2738 |
< |
return inHalfOpenRange(k) && m.containsKey(k); |
2738 |
> |
return inBounds(k) && m.containsKey(k); |
2739 |
|
} |
2740 |
|
|
2741 |
|
public V get(Object key) { |
2742 |
+ |
if (key == null) throw new NullPointerException(); |
2743 |
|
K k = (K)key; |
2744 |
< |
return ((!inHalfOpenRange(k)) ? null : m.get(k)); |
2744 |
> |
return ((!inBounds(k)) ? null : m.get(k)); |
2745 |
|
} |
2746 |
|
|
2747 |
|
public V put(K key, V value) { |
2748 |
< |
checkKey(key); |
2748 |
> |
checkKeyBounds(key); |
2749 |
|
return m.put(key, value); |
2750 |
|
} |
2751 |
|
|
2752 |
|
public V remove(Object key) { |
2753 |
|
K k = (K)key; |
2754 |
< |
return (!inHalfOpenRange(k))? null : m.remove(k); |
2754 |
> |
return (!inBounds(k))? null : m.remove(k); |
2755 |
|
} |
2756 |
|
|
2757 |
|
public int size() { |
2758 |
|
long count = 0; |
2759 |
< |
for (ConcurrentSkipListMap.Node<K,V> n = firstNode(); |
2759 |
> |
for (ConcurrentSkipListMap.Node<K,V> n = loNode(); |
2760 |
|
isBeforeEnd(n); |
2761 |
|
n = n.next) { |
2762 |
|
if (n.getValidValue() != null) |
2766 |
|
} |
2767 |
|
|
2768 |
|
public boolean isEmpty() { |
2769 |
< |
return !isBeforeEnd(firstNode()); |
2769 |
> |
return !isBeforeEnd(loNode()); |
2770 |
|
} |
2771 |
|
|
2772 |
|
public boolean containsValue(Object value) { |
2773 |
|
if (value == null) |
2774 |
|
throw new NullPointerException(); |
2775 |
< |
for (ConcurrentSkipListMap.Node<K,V> n = firstNode(); |
2775 |
> |
for (ConcurrentSkipListMap.Node<K,V> n = loNode(); |
2776 |
|
isBeforeEnd(n); |
2777 |
|
n = n.next) { |
2778 |
|
V v = n.getValidValue(); |
2783 |
|
} |
2784 |
|
|
2785 |
|
public void clear() { |
2786 |
< |
for (ConcurrentSkipListMap.Node<K,V> n = firstNode(); |
2786 |
> |
for (ConcurrentSkipListMap.Node<K,V> n = loNode(); |
2787 |
|
isBeforeEnd(n); |
2788 |
|
n = n.next) { |
2789 |
|
if (n.getValidValue() != null) |
2794 |
|
/* ---------------- ConcurrentMap API methods -------------- */ |
2795 |
|
|
2796 |
|
public V putIfAbsent(K key, V value) { |
2797 |
< |
checkKey(key); |
2797 |
> |
checkKeyBounds(key); |
2798 |
|
return m.putIfAbsent(key, value); |
2799 |
|
} |
2800 |
|
|
2801 |
|
public boolean remove(Object key, Object value) { |
2802 |
|
K k = (K)key; |
2803 |
< |
return inHalfOpenRange(k) && m.remove(k, value); |
2803 |
> |
return inBounds(k) && m.remove(k, value); |
2804 |
|
} |
2805 |
|
|
2806 |
|
public boolean replace(K key, V oldValue, V newValue) { |
2807 |
< |
checkKey(key); |
2807 |
> |
checkKeyBounds(key); |
2808 |
|
return m.replace(key, oldValue, newValue); |
2809 |
|
} |
2810 |
|
|
2811 |
|
public V replace(K key, V value) { |
2812 |
< |
checkKey(key); |
2812 |
> |
checkKeyBounds(key); |
2813 |
|
return m.replace(key, value); |
2814 |
|
} |
2815 |
|
|
2816 |
|
/* ---------------- SortedMap API methods -------------- */ |
2817 |
|
|
2818 |
|
public Comparator<? super K> comparator() { |
2819 |
< |
return m.comparator(); |
2820 |
< |
} |
2821 |
< |
|
3062 |
< |
public K firstKey() { |
3063 |
< |
ConcurrentSkipListMap.Node<K,V> n = firstNode(); |
3064 |
< |
if (isBeforeEnd(n)) |
3065 |
< |
return n.key; |
2819 |
> |
Comparator<? super K> cmp = m.comparator(); |
2820 |
> |
if (cmp == null || !isDescending) |
2821 |
> |
return cmp; |
2822 |
|
else |
2823 |
< |
throw new NoSuchElementException(); |
2823 |
> |
return Collections.reverseOrder(cmp); |
2824 |
|
} |
2825 |
< |
|
2826 |
< |
public K lastKey() { |
2827 |
< |
ConcurrentSkipListMap.Node<K,V> n = lastNode(); |
2828 |
< |
if (n != null) { |
2829 |
< |
K last = n.key; |
2830 |
< |
if (inHalfOpenRange(last)) |
2831 |
< |
return last; |
2825 |
> |
|
2826 |
> |
/** |
2827 |
> |
* Utility to create submaps, where given bounds override |
2828 |
> |
* unbounded(null) ones and/or are checked against bounded ones. |
2829 |
> |
*/ |
2830 |
> |
private SubMap<K,V> newSubMap(K fromKey, |
2831 |
> |
boolean fromInclusive, |
2832 |
> |
K toKey, |
2833 |
> |
boolean toInclusive) { |
2834 |
> |
if (isDescending) { // flip senses |
2835 |
> |
K tk = fromKey; |
2836 |
> |
fromKey = toKey; |
2837 |
> |
toKey = tk; |
2838 |
> |
boolean ti = fromInclusive; |
2839 |
> |
fromInclusive = toInclusive; |
2840 |
> |
toInclusive = ti; |
2841 |
> |
} |
2842 |
> |
if (lo != null) { |
2843 |
> |
if (fromKey == null) { |
2844 |
> |
fromKey = lo; |
2845 |
> |
fromInclusive = loInclusive; |
2846 |
> |
} |
2847 |
> |
else { |
2848 |
> |
int c = m.compare(fromKey, lo); |
2849 |
> |
if (c < 0 || (c == 0 && !loInclusive && fromInclusive)) |
2850 |
> |
throw new IllegalArgumentException("key out of range"); |
2851 |
> |
} |
2852 |
|
} |
2853 |
< |
throw new NoSuchElementException(); |
2853 |
> |
if (hi != null) { |
2854 |
> |
if (toKey == null) { |
2855 |
> |
toKey = hi; |
2856 |
> |
toInclusive = hiInclusive; |
2857 |
> |
} |
2858 |
> |
else { |
2859 |
> |
int c = m.compare(toKey, hi); |
2860 |
> |
if (c > 0 || (c == 0 && !hiInclusive && toInclusive)) |
2861 |
> |
throw new IllegalArgumentException("key out of range"); |
2862 |
> |
} |
2863 |
> |
} |
2864 |
> |
return new SubMap<K,V>(m, fromKey, fromInclusive, |
2865 |
> |
toKey, toInclusive, isDescending); |
2866 |
|
} |
2867 |
|
|
2868 |
< |
public ConcurrentNavigableMap<K,V> navigableSubMap(K fromKey, K toKey) { |
2868 |
> |
public SubMap<K,V> navigableSubMap(K fromKey, |
2869 |
> |
boolean fromInclusive, |
2870 |
> |
K toKey, |
2871 |
> |
boolean toInclusive) { |
2872 |
|
if (fromKey == null || toKey == null) |
2873 |
|
throw new NullPointerException(); |
2874 |
< |
if (!inOpenRange(fromKey) || !inOpenRange(toKey)) |
3084 |
< |
throw new IllegalArgumentException("key out of range"); |
3085 |
< |
return new ConcurrentSkipListSubMap<K,V>(m, fromKey, toKey); |
2874 |
> |
return newSubMap(fromKey, fromInclusive, toKey, toInclusive); |
2875 |
|
} |
2876 |
< |
|
2877 |
< |
public ConcurrentNavigableMap<K,V> navigableHeadMap(K toKey) { |
2876 |
> |
|
2877 |
> |
public SubMap<K,V> navigableHeadMap(K toKey, |
2878 |
> |
boolean inclusive) { |
2879 |
|
if (toKey == null) |
2880 |
|
throw new NullPointerException(); |
2881 |
< |
if (!inOpenRange(toKey)) |
3092 |
< |
throw new IllegalArgumentException("key out of range"); |
3093 |
< |
return new ConcurrentSkipListSubMap<K,V>(m, least, toKey); |
2881 |
> |
return newSubMap(null, false, toKey, inclusive); |
2882 |
|
} |
2883 |
< |
|
2884 |
< |
public ConcurrentNavigableMap<K,V> navigableTailMap(K fromKey) { |
2883 |
> |
|
2884 |
> |
public SubMap<K,V> navigableTailMap(K fromKey, |
2885 |
> |
boolean inclusive) { |
2886 |
|
if (fromKey == null) |
2887 |
|
throw new NullPointerException(); |
2888 |
< |
if (!inOpenRange(fromKey)) |
2889 |
< |
throw new IllegalArgumentException("key out of range"); |
2890 |
< |
return new ConcurrentSkipListSubMap<K,V>(m, fromKey, fence); |
2888 |
> |
return newSubMap(fromKey, inclusive, null, false); |
2889 |
> |
} |
2890 |
> |
|
2891 |
> |
public SubMap<K,V> subMap(K fromKey, K toKey) { |
2892 |
> |
return navigableSubMap(fromKey, true, toKey, false); |
2893 |
|
} |
2894 |
|
|
2895 |
< |
public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey) { |
2896 |
< |
return navigableSubMap(fromKey, toKey); |
2895 |
> |
public SubMap<K,V> headMap(K toKey) { |
2896 |
> |
return navigableHeadMap(toKey, false); |
2897 |
|
} |
2898 |
|
|
2899 |
< |
public ConcurrentNavigableMap<K,V> headMap(K toKey) { |
2900 |
< |
return navigableHeadMap(toKey); |
2899 |
> |
public SubMap<K,V> tailMap(K fromKey) { |
2900 |
> |
return navigableTailMap(fromKey, true); |
2901 |
|
} |
2902 |
|
|
2903 |
< |
public ConcurrentNavigableMap<K,V> tailMap(K fromKey) { |
2904 |
< |
return navigableTailMap(fromKey); |
2903 |
> |
public SubMap<K,V> descendingMap() { |
2904 |
> |
return new SubMap<K,V>(m, lo, loInclusive, |
2905 |
> |
hi, hiInclusive, !isDescending); |
2906 |
|
} |
2907 |
|
|
2908 |
|
/* ---------------- Relational methods -------------- */ |
2909 |
|
|
2910 |
|
public Map.Entry<K,V> ceilingEntry(K key) { |
2911 |
< |
return m.getNearEntry(key, m.GT|m.EQ, least, fence); |
2911 |
> |
return getNearEntry(key, (m.GT|m.EQ)); |
2912 |
|
} |
2913 |
|
|
2914 |
|
public K ceilingKey(K key) { |
2915 |
< |
return m.getNearKey(key, m.GT|m.EQ, least, fence); |
2915 |
> |
return getNearKey(key, (m.GT|m.EQ)); |
2916 |
|
} |
2917 |
|
|
2918 |
|
public Map.Entry<K,V> lowerEntry(K key) { |
2919 |
< |
return m.getNearEntry(key, m.LT, least, fence); |
2919 |
> |
return getNearEntry(key, (m.LT)); |
2920 |
|
} |
2921 |
|
|
2922 |
|
public K lowerKey(K key) { |
2923 |
< |
return m.getNearKey(key, m.LT, least, fence); |
2923 |
> |
return getNearKey(key, (m.LT)); |
2924 |
|
} |
2925 |
|
|
2926 |
|
public Map.Entry<K,V> floorEntry(K key) { |
2927 |
< |
return m.getNearEntry(key, m.LT|m.EQ, least, fence); |
2927 |
> |
return getNearEntry(key, (m.LT|m.EQ)); |
2928 |
|
} |
2929 |
|
|
2930 |
|
public K floorKey(K key) { |
2931 |
< |
return m.getNearKey(key, m.LT|m.EQ, least, fence); |
2931 |
> |
return getNearKey(key, (m.LT|m.EQ)); |
2932 |
|
} |
2933 |
|
|
2934 |
|
public Map.Entry<K,V> higherEntry(K key) { |
2935 |
< |
return m.getNearEntry(key, m.GT, least, fence); |
2935 |
> |
return getNearEntry(key, (m.GT)); |
2936 |
|
} |
2937 |
|
|
2938 |
|
public K higherKey(K key) { |
2939 |
< |
return m.getNearKey(key, m.GT, least, fence); |
2939 |
> |
return getNearKey(key, (m.GT)); |
2940 |
> |
} |
2941 |
> |
|
2942 |
> |
public K firstKey() { |
2943 |
> |
return isDescending? highestKey() : lowestKey(); |
2944 |
> |
} |
2945 |
> |
|
2946 |
> |
public K lastKey() { |
2947 |
> |
return isDescending? lowestKey() : highestKey(); |
2948 |
|
} |
2949 |
|
|
2950 |
|
public Map.Entry<K,V> firstEntry() { |
2951 |
< |
for (;;) { |
3152 |
< |
ConcurrentSkipListMap.Node<K,V> n = firstNode(); |
3153 |
< |
if (!isBeforeEnd(n)) |
3154 |
< |
return null; |
3155 |
< |
Map.Entry<K,V> e = n.createSnapshot(); |
3156 |
< |
if (e != null) |
3157 |
< |
return e; |
3158 |
< |
} |
2951 |
> |
return isDescending? highestEntry() : lowestEntry(); |
2952 |
|
} |
2953 |
|
|
2954 |
|
public Map.Entry<K,V> lastEntry() { |
2955 |
< |
for (;;) { |
3163 |
< |
ConcurrentSkipListMap.Node<K,V> n = lastNode(); |
3164 |
< |
if (n == null || !inHalfOpenRange(n.key)) |
3165 |
< |
return null; |
3166 |
< |
Map.Entry<K,V> e = n.createSnapshot(); |
3167 |
< |
if (e != null) |
3168 |
< |
return e; |
3169 |
< |
} |
2955 |
> |
return isDescending? lowestEntry() : highestEntry(); |
2956 |
|
} |
2957 |
|
|
2958 |
|
public Map.Entry<K,V> pollFirstEntry() { |
2959 |
< |
return m.removeFirstEntryOfSubrange(least, fence); |
2959 |
> |
return isDescending? removeHighest() : removeLowest(); |
2960 |
|
} |
2961 |
|
|
2962 |
|
public Map.Entry<K,V> pollLastEntry() { |
2963 |
< |
return m.removeLastEntryOfSubrange(least, fence); |
2963 |
> |
return isDescending? removeLowest() : removeHighest(); |
2964 |
|
} |
2965 |
|
|
2966 |
|
/* ---------------- Submap Views -------------- */ |
2967 |
|
|
2968 |
|
public Set<K> keySet() { |
2969 |
< |
Set<K> ks = keySetView; |
2970 |
< |
return (ks != null) ? ks : (keySetView = new KeySetView()); |
2969 |
> |
KeySet<K> ks = keySetView; |
2970 |
> |
return (ks != null) ? ks : (keySetView = new KeySet(this)); |
2971 |
|
} |
2972 |
|
|
2973 |
< |
class KeySetView extends AbstractSet<K> { |
2974 |
< |
public Iterator<K> iterator() { |
2975 |
< |
return m.subMapKeyIterator(least, fence); |
2976 |
< |
} |
3191 |
< |
public int size() { |
3192 |
< |
return ConcurrentSkipListSubMap.this.size(); |
3193 |
< |
} |
3194 |
< |
public boolean isEmpty() { |
3195 |
< |
return ConcurrentSkipListSubMap.this.isEmpty(); |
3196 |
< |
} |
3197 |
< |
public boolean contains(Object k) { |
3198 |
< |
return ConcurrentSkipListSubMap.this.containsKey(k); |
3199 |
< |
} |
3200 |
< |
public boolean equals(Object o) { |
3201 |
< |
if (o == this) |
3202 |
< |
return true; |
3203 |
< |
if (!(o instanceof Set)) |
3204 |
< |
return false; |
3205 |
< |
Collection<?> c = (Collection<?>) o; |
3206 |
< |
try { |
3207 |
< |
return containsAll(c) && c.containsAll(this); |
3208 |
< |
} catch (ClassCastException unused) { |
3209 |
< |
return false; |
3210 |
< |
} catch (NullPointerException unused) { |
3211 |
< |
return false; |
3212 |
< |
} |
3213 |
< |
} |
2973 |
> |
public NavigableSet<K> navigableKeySet() { |
2974 |
> |
KeySet<K> ks = keySetView; |
2975 |
> |
return (ks != null) ? ks : (keySetView = new KeySet(this)); |
2976 |
> |
} |
2977 |
|
|
2978 |
+ |
public Collection<V> values() { |
2979 |
+ |
Collection<V> vs = valuesView; |
2980 |
+ |
return (vs != null) ? vs : (valuesView = new Values(this)); |
2981 |
|
} |
2982 |
|
|
2983 |
< |
public Set<K> descendingKeySet() { |
2984 |
< |
Set<K> ks = descendingKeySetView; |
2985 |
< |
return (ks != null) ? ks : (descendingKeySetView = new DescendingKeySetView()); |
2983 |
> |
public Set<Map.Entry<K,V>> entrySet() { |
2984 |
> |
Set<Map.Entry<K,V>> es = entrySetView; |
2985 |
> |
return (es != null) ? es : (entrySetView = new EntrySet(this)); |
2986 |
|
} |
2987 |
|
|
2988 |
< |
class DescendingKeySetView extends KeySetView { |
2989 |
< |
public Iterator<K> iterator() { |
3224 |
< |
return m.descendingSubMapKeyIterator(least, fence); |
3225 |
< |
} |
2988 |
> |
public NavigableSet<K> descendingKeySet() { |
2989 |
> |
return descendingMap().navigableKeySet(); |
2990 |
|
} |
2991 |
|
|
2992 |
< |
public Collection<V> values() { |
2993 |
< |
Collection<V> vs = valuesView; |
3230 |
< |
return (vs != null) ? vs : (valuesView = new ValuesView()); |
2992 |
> |
Iterator<K> keyIterator() { |
2993 |
> |
return new SubMapKeyIterator(); |
2994 |
|
} |
2995 |
|
|
2996 |
< |
class ValuesView extends AbstractCollection<V> { |
2997 |
< |
public Iterator<V> iterator() { |
3235 |
< |
return m.subMapValueIterator(least, fence); |
3236 |
< |
} |
3237 |
< |
public int size() { |
3238 |
< |
return ConcurrentSkipListSubMap.this.size(); |
3239 |
< |
} |
3240 |
< |
public boolean isEmpty() { |
3241 |
< |
return ConcurrentSkipListSubMap.this.isEmpty(); |
3242 |
< |
} |
3243 |
< |
public boolean contains(Object v) { |
3244 |
< |
return ConcurrentSkipListSubMap.this.containsValue(v); |
3245 |
< |
} |
2996 |
> |
Iterator<V> valueIterator() { |
2997 |
> |
return new SubMapValueIterator(); |
2998 |
|
} |
2999 |
|
|
3000 |
< |
public Set<Map.Entry<K,V>> entrySet() { |
3001 |
< |
Set<Map.Entry<K,V>> es = entrySetView; |
3250 |
< |
return (es != null) ? es : (entrySetView = new EntrySetView()); |
3000 |
> |
Iterator<Map.Entry<K,V>> entryIterator() { |
3001 |
> |
return new SubMapEntryIterator(); |
3002 |
|
} |
3003 |
|
|
3004 |
< |
class EntrySetView extends AbstractSet<Map.Entry<K,V>> { |
3005 |
< |
public Iterator<Map.Entry<K,V>> iterator() { |
3006 |
< |
return m.subMapEntryIterator(least, fence); |
3007 |
< |
} |
3008 |
< |
public int size() { |
3009 |
< |
return ConcurrentSkipListSubMap.this.size(); |
3004 |
> |
/** |
3005 |
> |
* Variant of main Iter class to traverse through submaps. |
3006 |
> |
*/ |
3007 |
> |
abstract class SubMapIter<T> implements Iterator<T> { |
3008 |
> |
/** the last node returned by next() */ |
3009 |
> |
Node<K,V> last; |
3010 |
> |
/** the next node to return from next(); */ |
3011 |
> |
Node<K,V> next; |
3012 |
> |
/** Cache of next value field to maintain weak consistency */ |
3013 |
> |
Object nextValue; |
3014 |
> |
|
3015 |
> |
SubMapIter() { |
3016 |
> |
for (;;) { |
3017 |
> |
next = isDescending? hiNode() : loNode(); |
3018 |
> |
if (next == null) |
3019 |
> |
break; |
3020 |
> |
nextValue = next.value; |
3021 |
> |
if (nextValue != null && nextValue != next) { |
3022 |
> |
if (!inBounds(next.key)) { |
3023 |
> |
next = null; |
3024 |
> |
nextValue = null; |
3025 |
> |
} |
3026 |
> |
break; |
3027 |
> |
} |
3028 |
> |
} |
3029 |
|
} |
3030 |
< |
public boolean isEmpty() { |
3031 |
< |
return ConcurrentSkipListSubMap.this.isEmpty(); |
3030 |
> |
|
3031 |
> |
public final boolean hasNext() { |
3032 |
> |
return next != null; |
3033 |
|
} |
3034 |
< |
public boolean contains(Object o) { |
3035 |
< |
if (!(o instanceof Map.Entry)) |
3036 |
< |
return false; |
3037 |
< |
Map.Entry<K,V> e = (Map.Entry<K,V>) o; |
3038 |
< |
K key = e.getKey(); |
3039 |
< |
if (!inHalfOpenRange(key)) |
3040 |
< |
return false; |
3041 |
< |
V v = m.get(key); |
3271 |
< |
return v != null && v.equals(e.getValue()); |
3034 |
> |
|
3035 |
> |
final void advance() { |
3036 |
> |
if ((last = next) == null) |
3037 |
> |
throw new NoSuchElementException(); |
3038 |
> |
if (isDescending) |
3039 |
> |
descend(); |
3040 |
> |
else |
3041 |
> |
ascend(); |
3042 |
|
} |
3043 |
< |
public boolean remove(Object o) { |
3044 |
< |
if (!(o instanceof Map.Entry)) |
3045 |
< |
return false; |
3046 |
< |
Map.Entry<K,V> e = (Map.Entry<K,V>) o; |
3047 |
< |
K key = e.getKey(); |
3048 |
< |
if (!inHalfOpenRange(key)) |
3049 |
< |
return false; |
3050 |
< |
return m.remove(key, e.getValue()); |
3043 |
> |
|
3044 |
> |
private void ascend() { |
3045 |
> |
for (;;) { |
3046 |
> |
next = next.next; |
3047 |
> |
if (next == null) |
3048 |
> |
break; |
3049 |
> |
nextValue = next.value; |
3050 |
> |
if (nextValue != null && nextValue != next) { |
3051 |
> |
if (tooHigh(next.key)) { |
3052 |
> |
next = null; |
3053 |
> |
nextValue = null; |
3054 |
> |
} |
3055 |
> |
break; |
3056 |
> |
} |
3057 |
> |
} |
3058 |
|
} |
3059 |
< |
public boolean equals(Object o) { |
3060 |
< |
if (o == this) |
3061 |
< |
return true; |
3062 |
< |
if (!(o instanceof Set)) |
3063 |
< |
return false; |
3064 |
< |
Collection<?> c = (Collection<?>) o; |
3065 |
< |
try { |
3066 |
< |
return containsAll(c) && c.containsAll(this); |
3067 |
< |
} catch (ClassCastException unused) { |
3068 |
< |
return false; |
3069 |
< |
} catch (NullPointerException unused) { |
3070 |
< |
return false; |
3059 |
> |
|
3060 |
> |
private void descend() { |
3061 |
> |
for (;;) { |
3062 |
> |
next = m.findNear(last.key, LT); |
3063 |
> |
if (next == null) |
3064 |
> |
break; |
3065 |
> |
nextValue = next.value; |
3066 |
> |
if (nextValue != null && nextValue != next) { |
3067 |
> |
if (tooLow(next.key)) { |
3068 |
> |
next = null; |
3069 |
> |
nextValue = null; |
3070 |
> |
} |
3071 |
> |
break; |
3072 |
> |
} |
3073 |
|
} |
3074 |
|
} |
3075 |
+ |
|
3076 |
+ |
public void remove() { |
3077 |
+ |
Node<K,V> l = last; |
3078 |
+ |
if (l == null) |
3079 |
+ |
throw new IllegalStateException(); |
3080 |
+ |
m.remove(l.key); |
3081 |
+ |
} |
3082 |
+ |
|
3083 |
+ |
} |
3084 |
+ |
|
3085 |
+ |
final class SubMapValueIterator extends SubMapIter<V> { |
3086 |
+ |
public V next() { |
3087 |
+ |
Object v = nextValue; |
3088 |
+ |
advance(); |
3089 |
+ |
return (V)v; |
3090 |
+ |
} |
3091 |
|
} |
3092 |
|
|
3093 |
< |
public Set<Map.Entry<K,V>> descendingEntrySet() { |
3094 |
< |
Set<Map.Entry<K,V>> es = descendingEntrySetView; |
3095 |
< |
return (es != null) ? es : (descendingEntrySetView = new DescendingEntrySetView()); |
3093 |
> |
final class SubMapKeyIterator extends SubMapIter<K> { |
3094 |
> |
public K next() { |
3095 |
> |
Node<K,V> n = next; |
3096 |
> |
advance(); |
3097 |
> |
return n.key; |
3098 |
> |
} |
3099 |
|
} |
3100 |
|
|
3101 |
< |
class DescendingEntrySetView extends EntrySetView { |
3102 |
< |
public Iterator<Map.Entry<K,V>> iterator() { |
3103 |
< |
return m.descendingSubMapEntryIterator(least, fence); |
3101 |
> |
final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> { |
3102 |
> |
public Map.Entry<K,V> next() { |
3103 |
> |
Node<K,V> n = next; |
3104 |
> |
V v = (V)nextValue; |
3105 |
> |
advance(); |
3106 |
> |
return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); |
3107 |
|
} |
3108 |
|
} |
3109 |
|
} |