* portion of the elements, and so may be amenable to parallel
* execution.
*
- * This interface exports a subset of expected JDK8
+ *
This interface exports a subset of expected JDK8
* functionality.
*
*
Sample usage: Here is one (of the several) ways to compute
@@ -287,76 +287,6 @@ public class ConcurrentHashMapV8
Spliterator split();
}
- /**
- * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in
- * which additions may optionally be enabled by mapping to a
- * common value. This class cannot be directly instantiated. See
- * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()},
- * {@link #newKeySet(int)}.
- *
- * The view's {@code iterator} is a "weakly consistent" iterator
- * that will never throw {@link ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
- */
- public static class KeySetView extends CHMView implements Set, java.io.Serializable {
- private static final long serialVersionUID = 7249069246763182397L;
- private final V value;
- KeySetView(ConcurrentHashMapV8 map, V value) { // non-public
- super(map);
- this.value = value;
- }
-
- /**
- * Returns the map backing this view.
- *
- * @return the map backing this view
- */
- public ConcurrentHashMapV8 getMap() { return map; }
-
- /**
- * Returns the default mapped value for additions,
- * or {@code null} if additions are not supported.
- *
- * @return the default mapped value for additions, or {@code null}
- * if not supported.
- */
- public V getMappedValue() { return value; }
-
- // implement Set API
-
- public boolean contains(Object o) { return map.containsKey(o); }
- public boolean remove(Object o) { return map.remove(o) != null; }
- public Iterator iterator() { return new KeyIterator(map); }
- public boolean add(K e) {
- V v;
- if ((v = value) == null)
- throw new UnsupportedOperationException();
- if (e == null)
- throw new NullPointerException();
- return map.internalPutIfAbsent(e, v) == null;
- }
- public boolean addAll(Collection extends K> c) {
- boolean added = false;
- V v;
- if ((v = value) == null)
- throw new UnsupportedOperationException();
- for (K e : c) {
- if (e == null)
- throw new NullPointerException();
- if (map.internalPutIfAbsent(e, v) == null)
- added = true;
- }
- return added;
- }
- public boolean equals(Object o) {
- Set> c;
- return ((o instanceof Set) &&
- ((c = (Set>)o) == this ||
- (containsAll(c) && c.containsAll(this))));
- }
- }
/*
* Overview:
@@ -641,8 +571,8 @@ public class ConcurrentHashMapV8
// views
private transient KeySetView keySet;
- private transient Values values;
- private transient EntrySet entrySet;
+ private transient ValuesView values;
+ private transient EntrySetView entrySet;
/** For serialization compatibility. Null unless serialized; see below */
private Segment[] segments;
@@ -2783,7 +2713,7 @@ public class ConcurrentHashMapV8
* Maps the specified key to the specified value in this table.
* Neither the key nor the value can be null.
*
- * The value can be retrieved by calling the {@code get} method
+ *
The value can be retrieved by calling the {@code get} method
* with a key that is equal to the original key.
*
* @param key key with which the specified value is to be associated
@@ -3080,22 +3010,11 @@ public class ConcurrentHashMapV8
/**
* Returns a {@link Collection} view of the values contained in this map.
* The collection is backed by the map, so changes to the map are
- * reflected in the collection, and vice-versa. The collection
- * supports element removal, which removes the corresponding
- * mapping from this map, via the {@code Iterator.remove},
- * {@code Collection.remove}, {@code removeAll},
- * {@code retainAll}, and {@code clear} operations. It does not
- * support the {@code add} or {@code addAll} operations.
- *
- * The view's {@code iterator} is a "weakly consistent" iterator
- * that will never throw {@link ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * reflected in the collection, and vice-versa.
*/
- public Collection values() {
- Values vs = values;
- return (vs != null) ? vs : (values = new Values(this));
+ public ValuesView values() {
+ ValuesView vs = values;
+ return (vs != null) ? vs : (values = new ValuesView(this));
}
/**
@@ -3115,8 +3034,8 @@ public class ConcurrentHashMapV8
* reflect any modifications subsequent to construction.
*/
public Set> entrySet() {
- EntrySet es = entrySet;
- return (es != null) ? es : (entrySet = new EntrySet(this));
+ EntrySetView es = entrySet;
+ return (es != null) ? es : (entrySet = new EntrySetView(this));
}
/**
@@ -3359,199 +3278,6 @@ public class ConcurrentHashMapV8
}
}
- /* ----------------Views -------------- */
-
- /**
- * Base class for views.
- */
- static abstract class CHMView {
- final ConcurrentHashMapV8 map;
- CHMView(ConcurrentHashMapV8 map) { this.map = map; }
- public final int size() { return map.size(); }
- public final boolean isEmpty() { return map.isEmpty(); }
- public final void clear() { map.clear(); }
-
- // implementations below rely on concrete classes supplying these
- abstract public Iterator> iterator();
- abstract public boolean contains(Object o);
- abstract public boolean remove(Object o);
-
- private static final String oomeMsg = "Required array size too large";
-
- public final Object[] toArray() {
- long sz = map.mappingCount();
- if (sz > (long)(MAX_ARRAY_SIZE))
- throw new OutOfMemoryError(oomeMsg);
- int n = (int)sz;
- Object[] r = new Object[n];
- int i = 0;
- Iterator> it = iterator();
- while (it.hasNext()) {
- if (i == n) {
- if (n >= MAX_ARRAY_SIZE)
- throw new OutOfMemoryError(oomeMsg);
- if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
- n = MAX_ARRAY_SIZE;
- else
- n += (n >>> 1) + 1;
- r = Arrays.copyOf(r, n);
- }
- r[i++] = it.next();
- }
- return (i == n) ? r : Arrays.copyOf(r, i);
- }
-
- @SuppressWarnings("unchecked") public final T[] toArray(T[] a) {
- long sz = map.mappingCount();
- if (sz > (long)(MAX_ARRAY_SIZE))
- throw new OutOfMemoryError(oomeMsg);
- int m = (int)sz;
- T[] r = (a.length >= m) ? a :
- (T[])java.lang.reflect.Array
- .newInstance(a.getClass().getComponentType(), m);
- int n = r.length;
- int i = 0;
- Iterator> it = iterator();
- while (it.hasNext()) {
- if (i == n) {
- if (n >= MAX_ARRAY_SIZE)
- throw new OutOfMemoryError(oomeMsg);
- if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
- n = MAX_ARRAY_SIZE;
- else
- n += (n >>> 1) + 1;
- r = Arrays.copyOf(r, n);
- }
- r[i++] = (T)it.next();
- }
- if (a == r && i < n) {
- r[i] = null; // null-terminate
- return r;
- }
- return (i == n) ? r : Arrays.copyOf(r, i);
- }
-
- public final int hashCode() {
- int h = 0;
- for (Iterator> it = iterator(); it.hasNext();)
- h += it.next().hashCode();
- return h;
- }
-
- public final String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append('[');
- Iterator> it = iterator();
- if (it.hasNext()) {
- for (;;) {
- Object e = it.next();
- sb.append(e == this ? "(this Collection)" : e);
- if (!it.hasNext())
- break;
- sb.append(',').append(' ');
- }
- }
- return sb.append(']').toString();
- }
-
- public final boolean containsAll(Collection> c) {
- if (c != this) {
- for (Iterator> it = c.iterator(); it.hasNext();) {
- Object e = it.next();
- if (e == null || !contains(e))
- return false;
- }
- }
- return true;
- }
-
- public final boolean removeAll(Collection> c) {
- boolean modified = false;
- for (Iterator> it = iterator(); it.hasNext();) {
- if (c.contains(it.next())) {
- it.remove();
- modified = true;
- }
- }
- return modified;
- }
-
- public final boolean retainAll(Collection> c) {
- boolean modified = false;
- for (Iterator> it = iterator(); it.hasNext();) {
- if (!c.contains(it.next())) {
- it.remove();
- modified = true;
- }
- }
- return modified;
- }
-
- }
-
- static final class Values extends CHMView
- implements Collection {
- Values(ConcurrentHashMapV8 map) { super(map); }
- public final boolean contains(Object o) { return map.containsValue(o); }
- public final boolean remove(Object o) {
- if (o != null) {
- Iterator it = new ValueIterator(map);
- while (it.hasNext()) {
- if (o.equals(it.next())) {
- it.remove();
- return true;
- }
- }
- }
- return false;
- }
- public final Iterator iterator() {
- return new ValueIterator(map);
- }
- public final boolean add(V e) {
- throw new UnsupportedOperationException();
- }
- public final boolean addAll(Collection extends V> c) {
- throw new UnsupportedOperationException();
- }
-
- }
-
- static final class EntrySet extends CHMView
- implements Set> {
- EntrySet(ConcurrentHashMapV8 map) { super(map); }
- public final boolean contains(Object o) {
- Object k, v, r; Map.Entry,?> e;
- return ((o instanceof Map.Entry) &&
- (k = (e = (Map.Entry,?>)o).getKey()) != null &&
- (r = map.get(k)) != null &&
- (v = e.getValue()) != null &&
- (v == r || v.equals(r)));
- }
- public final boolean remove(Object o) {
- Object k, v; Map.Entry,?> e;
- return ((o instanceof Map.Entry) &&
- (k = (e = (Map.Entry,?>)o).getKey()) != null &&
- (v = e.getValue()) != null &&
- map.remove(k, v));
- }
- public final Iterator> iterator() {
- return new EntryIterator(map);
- }
- public final boolean add(Entry e) {
- throw new UnsupportedOperationException();
- }
- public final boolean addAll(Collection extends Entry> c) {
- throw new UnsupportedOperationException();
- }
- public boolean equals(Object o) {
- Set> c;
- return ((o instanceof Set) &&
- ((c = (Set>)o) == this ||
- (containsAll(c) && c.containsAll(this))));
- }
- }
-
/* ---------------- Serialization Support -------------- */
/**
@@ -3860,6 +3586,23 @@ public class ConcurrentHashMapV8
}
/**
+ * Returns a non-null result from applying the given search
+ * function on each key, or null if none. Upon success,
+ * further element processing is suppressed and the results of
+ * any other parallel invocations of the search function are
+ * ignored.
+ *
+ * @param searchFunction a function returning a non-null
+ * result on success, else null
+ * @return a non-null result from applying the given search
+ * function on each key, or null if none
+ */
+ public U searchKeys(Fun super K, ? extends U> searchFunction) {
+ return ForkJoinTasks.searchKeys
+ (this, searchFunction).invoke();
+ }
+
+ /**
* Returns the result of accumulating all keys using the given
* reducer to combine values, or null if none.
*
@@ -4205,6 +3948,697 @@ public class ConcurrentHashMapV8
(this, transformer, basis, reducer).invoke();
}
+ /* ----------------Views -------------- */
+
+ /**
+ * Base class for views.
+ */
+ static abstract class CHMView {
+ final ConcurrentHashMapV8 map;
+ CHMView(ConcurrentHashMapV8 map) { this.map = map; }
+
+ /**
+ * Returns the map backing this view.
+ *
+ * @return the map backing this view
+ */
+ public ConcurrentHashMapV8 getMap() { return map; }
+
+ public final int size() { return map.size(); }
+ public final boolean isEmpty() { return map.isEmpty(); }
+ public final void clear() { map.clear(); }
+
+ // implementations below rely on concrete classes supplying these
+ abstract public Iterator> iterator();
+ abstract public boolean contains(Object o);
+ abstract public boolean remove(Object o);
+
+ private static final String oomeMsg = "Required array size too large";
+
+ public final Object[] toArray() {
+ long sz = map.mappingCount();
+ if (sz > (long)(MAX_ARRAY_SIZE))
+ throw new OutOfMemoryError(oomeMsg);
+ int n = (int)sz;
+ Object[] r = new Object[n];
+ int i = 0;
+ Iterator> it = iterator();
+ while (it.hasNext()) {
+ if (i == n) {
+ if (n >= MAX_ARRAY_SIZE)
+ throw new OutOfMemoryError(oomeMsg);
+ if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
+ n = MAX_ARRAY_SIZE;
+ else
+ n += (n >>> 1) + 1;
+ r = Arrays.copyOf(r, n);
+ }
+ r[i++] = it.next();
+ }
+ return (i == n) ? r : Arrays.copyOf(r, i);
+ }
+
+ @SuppressWarnings("unchecked") public final T[] toArray(T[] a) {
+ long sz = map.mappingCount();
+ if (sz > (long)(MAX_ARRAY_SIZE))
+ throw new OutOfMemoryError(oomeMsg);
+ int m = (int)sz;
+ T[] r = (a.length >= m) ? a :
+ (T[])java.lang.reflect.Array
+ .newInstance(a.getClass().getComponentType(), m);
+ int n = r.length;
+ int i = 0;
+ Iterator> it = iterator();
+ while (it.hasNext()) {
+ if (i == n) {
+ if (n >= MAX_ARRAY_SIZE)
+ throw new OutOfMemoryError(oomeMsg);
+ if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
+ n = MAX_ARRAY_SIZE;
+ else
+ n += (n >>> 1) + 1;
+ r = Arrays.copyOf(r, n);
+ }
+ r[i++] = (T)it.next();
+ }
+ if (a == r && i < n) {
+ r[i] = null; // null-terminate
+ return r;
+ }
+ return (i == n) ? r : Arrays.copyOf(r, i);
+ }
+
+ public final int hashCode() {
+ int h = 0;
+ for (Iterator> it = iterator(); it.hasNext();)
+ h += it.next().hashCode();
+ return h;
+ }
+
+ public final String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append('[');
+ Iterator> it = iterator();
+ if (it.hasNext()) {
+ for (;;) {
+ Object e = it.next();
+ sb.append(e == this ? "(this Collection)" : e);
+ if (!it.hasNext())
+ break;
+ sb.append(',').append(' ');
+ }
+ }
+ return sb.append(']').toString();
+ }
+
+ public final boolean containsAll(Collection> c) {
+ if (c != this) {
+ for (Iterator> it = c.iterator(); it.hasNext();) {
+ Object e = it.next();
+ if (e == null || !contains(e))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public final boolean removeAll(Collection> c) {
+ boolean modified = false;
+ for (Iterator> it = iterator(); it.hasNext();) {
+ if (c.contains(it.next())) {
+ it.remove();
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ public final boolean retainAll(Collection> c) {
+ boolean modified = false;
+ for (Iterator> it = iterator(); it.hasNext();) {
+ if (!c.contains(it.next())) {
+ it.remove();
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ }
+
+ /**
+ * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in
+ * which additions may optionally be enabled by mapping to a
+ * common value. This class cannot be directly instantiated. See
+ * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()},
+ * {@link #newKeySet(int)}.
+ */
+ public static class KeySetView extends CHMView implements Set, java.io.Serializable {
+ private static final long serialVersionUID = 7249069246763182397L;
+ private final V value;
+ KeySetView(ConcurrentHashMapV8 map, V value) { // non-public
+ super(map);
+ this.value = value;
+ }
+
+ /**
+ * Returns the default mapped value for additions,
+ * or {@code null} if additions are not supported.
+ *
+ * @return the default mapped value for additions, or {@code null}
+ * if not supported.
+ */
+ public V getMappedValue() { return value; }
+
+ // implement Set API
+
+ public boolean contains(Object o) { return map.containsKey(o); }
+ public boolean remove(Object o) { return map.remove(o) != null; }
+
+ /**
+ * Returns a "weakly consistent" iterator that will never
+ * throw {@link ConcurrentModificationException}, and
+ * guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not
+ * guaranteed to) reflect any modifications subsequent to
+ * construction.
+ *
+ * @return an iterator over the keys of this map
+ */
+ public Iterator iterator() { return new KeyIterator(map); }
+ public boolean add(K e) {
+ V v;
+ if ((v = value) == null)
+ throw new UnsupportedOperationException();
+ if (e == null)
+ throw new NullPointerException();
+ return map.internalPutIfAbsent(e, v) == null;
+ }
+ public boolean addAll(Collection extends K> c) {
+ boolean added = false;
+ V v;
+ if ((v = value) == null)
+ throw new UnsupportedOperationException();
+ for (K e : c) {
+ if (e == null)
+ throw new NullPointerException();
+ if (map.internalPutIfAbsent(e, v) == null)
+ added = true;
+ }
+ return added;
+ }
+ public boolean equals(Object o) {
+ Set> c;
+ return ((o instanceof Set) &&
+ ((c = (Set>)o) == this ||
+ (containsAll(c) && c.containsAll(this))));
+ }
+
+ /**
+ * Performs the given action for each key.
+ *
+ * @param action the action
+ */
+ public void forEach(Action action) {
+ ForkJoinTasks.forEachKey
+ (map, action).invoke();
+ }
+
+ /**
+ * Performs the given action for each non-null transformation
+ * of each key.
+ *
+ * @param transformer a function returning the transformation
+ * for an element, or null of there is no transformation (in
+ * which case the action is not applied).
+ * @param action the action
+ */
+ public void forEach(Fun super K, ? extends U> transformer,
+ Action action) {
+ ForkJoinTasks.forEachKey
+ (map, transformer, action).invoke();
+ }
+
+ /**
+ * Returns a non-null result from applying the given search
+ * function on each key, or null if none. Upon success,
+ * further element processing is suppressed and the results of
+ * any other parallel invocations of the search function are
+ * ignored.
+ *
+ * @param searchFunction a function returning a non-null
+ * result on success, else null
+ * @return a non-null result from applying the given search
+ * function on each key, or null if none
+ */
+ public U search(Fun super K, ? extends U> searchFunction) {
+ return ForkJoinTasks.searchKeys
+ (map, searchFunction).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating all keys using the given
+ * reducer to combine values, or null if none.
+ *
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating all keys using the given
+ * reducer to combine values, or null if none
+ */
+ public K reduce(BiFun super K, ? super K, ? extends K> reducer) {
+ return ForkJoinTasks.reduceKeys
+ (map, reducer).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating the given transformation
+ * of all keys using the given reducer to combine values, and
+ * the given basis as an identity value.
+ *
+ * @param transformer a function returning the transformation
+ * for an element
+ * @param basis the identity (initial default value) for the reduction
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating the given transformation
+ * of all keys
+ */
+ public double reduceToDouble(ObjectToDouble super K> transformer,
+ double basis,
+ DoubleByDoubleToDouble reducer) {
+ return ForkJoinTasks.reduceKeysToDouble
+ (map, transformer, basis, reducer).invoke();
+ }
+
+
+ /**
+ * Returns the result of accumulating the given transformation
+ * of all keys using the given reducer to combine values, and
+ * the given basis as an identity value.
+ *
+ * @param transformer a function returning the transformation
+ * for an element
+ * @param basis the identity (initial default value) for the reduction
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating the given transformation
+ * of all keys
+ */
+ public long reduceToLong(ObjectToLong super K> transformer,
+ long basis,
+ LongByLongToLong reducer) {
+ return ForkJoinTasks.reduceKeysToLong
+ (map, transformer, basis, reducer).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating the given transformation
+ * of all keys using the given reducer to combine values, and
+ * the given basis as an identity value.
+ *
+ * @param transformer a function returning the transformation
+ * for an element
+ * @param basis the identity (initial default value) for the reduction
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating the given transformation
+ * of all keys
+ */
+ public int reduceToInt(ObjectToInt super K> transformer,
+ int basis,
+ IntByIntToInt reducer) {
+ return ForkJoinTasks.reduceKeysToInt
+ (map, transformer, basis, reducer).invoke();
+ }
+
+ }
+
+ /**
+ * A view of a ConcurrentHashMapV8 as a {@link Collection} of
+ * values, in which additions are disabled. This class cannot be
+ * directly instantiated. See {@link #values},
+ *
+ * The view's {@code iterator} is a "weakly consistent" iterator
+ * that will never throw {@link ConcurrentModificationException},
+ * and guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not guaranteed to)
+ * reflect any modifications subsequent to construction.
+ */
+ public static final class ValuesView extends CHMView
+ implements Collection {
+ ValuesView(ConcurrentHashMapV8 map) { super(map); }
+ public final boolean contains(Object o) { return map.containsValue(o); }
+ public final boolean remove(Object o) {
+ if (o != null) {
+ Iterator it = new ValueIterator(map);
+ while (it.hasNext()) {
+ if (o.equals(it.next())) {
+ it.remove();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a "weakly consistent" iterator that will never
+ * throw {@link ConcurrentModificationException}, and
+ * guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not
+ * guaranteed to) reflect any modifications subsequent to
+ * construction.
+ *
+ * @return an iterator over the values of this map
+ */
+ public final Iterator iterator() {
+ return new ValueIterator(map);
+ }
+ public final boolean add(V e) {
+ throw new UnsupportedOperationException();
+ }
+ public final boolean addAll(Collection extends V> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Performs the given action for each value.
+ *
+ * @param action the action
+ */
+ public void forEach(Action action) {
+ ForkJoinTasks.forEachValue
+ (map, action).invoke();
+ }
+
+ /**
+ * Performs the given action for each non-null transformation
+ * of each value.
+ *
+ * @param transformer a function returning the transformation
+ * for an element, or null of there is no transformation (in
+ * which case the action is not applied).
+ */
+ public void forEach(Fun super V, ? extends U> transformer,
+ Action action) {
+ ForkJoinTasks.forEachValue
+ (map, transformer, action).invoke();
+ }
+
+ /**
+ * Returns a non-null result from applying the given search
+ * function on each value, or null if none. Upon success,
+ * further element processing is suppressed and the results of
+ * any other parallel invocations of the search function are
+ * ignored.
+ *
+ * @param searchFunction a function returning a non-null
+ * result on success, else null
+ * @return a non-null result from applying the given search
+ * function on each value, or null if none
+ *
+ */
+ public U search(Fun super V, ? extends U> searchFunction) {
+ return ForkJoinTasks.searchValues
+ (map, searchFunction).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating all values using the
+ * given reducer to combine values, or null if none.
+ *
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating all values
+ */
+ public V reduce(BiFun super V, ? super V, ? extends V> reducer) {
+ return ForkJoinTasks.reduceValues
+ (map, reducer).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating the given transformation
+ * of all values using the given reducer to combine values, or
+ * null if none.
+ *
+ * @param transformer a function returning the transformation
+ * for an element, or null of there is no transformation (in
+ * which case it is not combined).
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating the given transformation
+ * of all values
+ */
+ public U reduce(Fun super V, ? extends U> transformer,
+ BiFun super U, ? super U, ? extends U> reducer) {
+ return ForkJoinTasks.reduceValues
+ (map, transformer, reducer).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating the given transformation
+ * of all values using the given reducer to combine values,
+ * and the given basis as an identity value.
+ *
+ * @param transformer a function returning the transformation
+ * for an element
+ * @param basis the identity (initial default value) for the reduction
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating the given transformation
+ * of all values
+ */
+ public double reduceToDouble(ObjectToDouble super V> transformer,
+ double basis,
+ DoubleByDoubleToDouble reducer) {
+ return ForkJoinTasks.reduceValuesToDouble
+ (map, transformer, basis, reducer).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating the given transformation
+ * of all values using the given reducer to combine values,
+ * and the given basis as an identity value.
+ *
+ * @param transformer a function returning the transformation
+ * for an element
+ * @param basis the identity (initial default value) for the reduction
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating the given transformation
+ * of all values
+ */
+ public long reduceToLong(ObjectToLong super V> transformer,
+ long basis,
+ LongByLongToLong reducer) {
+ return ForkJoinTasks.reduceValuesToLong
+ (map, transformer, basis, reducer).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating the given transformation
+ * of all values using the given reducer to combine values,
+ * and the given basis as an identity value.
+ *
+ * @param transformer a function returning the transformation
+ * for an element
+ * @param basis the identity (initial default value) for the reduction
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating the given transformation
+ * of all values
+ */
+ public int reduceToInt(ObjectToInt super V> transformer,
+ int basis,
+ IntByIntToInt reducer) {
+ return ForkJoinTasks.reduceValuesToInt
+ (map, transformer, basis, reducer).invoke();
+ }
+
+ }
+
+ /**
+ * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value)
+ * entries. This class cannot be directly instantiated. See
+ * {@link #entrySet}.
+ */
+ public static final class EntrySetView extends CHMView
+ implements Set> {
+ EntrySetView(ConcurrentHashMapV8 map) { super(map); }
+ public final boolean contains(Object o) {
+ Object k, v, r; Map.Entry,?> e;
+ return ((o instanceof Map.Entry) &&
+ (k = (e = (Map.Entry,?>)o).getKey()) != null &&
+ (r = map.get(k)) != null &&
+ (v = e.getValue()) != null &&
+ (v == r || v.equals(r)));
+ }
+ public final boolean remove(Object o) {
+ Object k, v; Map.Entry,?> e;
+ return ((o instanceof Map.Entry) &&
+ (k = (e = (Map.Entry,?>)o).getKey()) != null &&
+ (v = e.getValue()) != null &&
+ map.remove(k, v));
+ }
+
+ /**
+ * Returns a "weakly consistent" iterator that will never
+ * throw {@link ConcurrentModificationException}, and
+ * guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not
+ * guaranteed to) reflect any modifications subsequent to
+ * construction.
+ *
+ * @return an iterator over the entries of this map
+ */
+ public final Iterator> iterator() {
+ return new EntryIterator(map);
+ }
+
+ public final boolean add(Entry e) {
+ K key = e.getKey();
+ V value = e.getValue();
+ if (key == null || value == null)
+ throw new NullPointerException();
+ return map.internalPut(key, value) == null;
+ }
+ public final boolean addAll(Collection extends Entry> c) {
+ boolean added = false;
+ for (Entry e : c) {
+ if (add(e))
+ added = true;
+ }
+ return added;
+ }
+ public boolean equals(Object o) {
+ Set> c;
+ return ((o instanceof Set) &&
+ ((c = (Set>)o) == this ||
+ (containsAll(c) && c.containsAll(this))));
+ }
+
+ /**
+ * Performs the given action for each entry.
+ *
+ * @param action the action
+ */
+ public void forEach(Action> action) {
+ ForkJoinTasks.forEachEntry
+ (map, action).invoke();
+ }
+
+ /**
+ * Performs the given action for each non-null transformation
+ * of each entry.
+ *
+ * @param transformer a function returning the transformation
+ * for an element, or null of there is no transformation (in
+ * which case the action is not applied).
+ * @param action the action
+ */
+ public void forEach(Fun, ? extends U> transformer,
+ Action action) {
+ ForkJoinTasks.forEachEntry
+ (map, transformer, action).invoke();
+ }
+
+ /**
+ * Returns a non-null result from applying the given search
+ * function on each entry, or null if none. Upon success,
+ * further element processing is suppressed and the results of
+ * any other parallel invocations of the search function are
+ * ignored.
+ *
+ * @param searchFunction a function returning a non-null
+ * result on success, else null
+ * @return a non-null result from applying the given search
+ * function on each entry, or null if none
+ */
+ public U search(Fun, ? extends U> searchFunction) {
+ return ForkJoinTasks.searchEntries
+ (map, searchFunction).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating all entries using the
+ * given reducer to combine values, or null if none.
+ *
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating all entries
+ */
+ public Map.Entry reduce(BiFun, Map.Entry, ? extends Map.Entry> reducer) {
+ return ForkJoinTasks.reduceEntries
+ (map, reducer).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating the given transformation
+ * of all entries using the given reducer to combine values,
+ * or null if none.
+ *
+ * @param transformer a function returning the transformation
+ * for an element, or null of there is no transformation (in
+ * which case it is not combined).
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating the given transformation
+ * of all entries
+ */
+ public U reduce(Fun, ? extends U> transformer,
+ BiFun super U, ? super U, ? extends U> reducer) {
+ return ForkJoinTasks.reduceEntries
+ (map, transformer, reducer).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating the given transformation
+ * of all entries using the given reducer to combine values,
+ * and the given basis as an identity value.
+ *
+ * @param transformer a function returning the transformation
+ * for an element
+ * @param basis the identity (initial default value) for the reduction
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating the given transformation
+ * of all entries
+ */
+ public double reduceToDouble(ObjectToDouble> transformer,
+ double basis,
+ DoubleByDoubleToDouble reducer) {
+ return ForkJoinTasks.reduceEntriesToDouble
+ (map, transformer, basis, reducer).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating the given transformation
+ * of all entries using the given reducer to combine values,
+ * and the given basis as an identity value.
+ *
+ * @param transformer a function returning the transformation
+ * for an element
+ * @param basis the identity (initial default value) for the reduction
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating the given transformation
+ * of all entries
+ */
+ public long reduceToLong(ObjectToLong> transformer,
+ long basis,
+ LongByLongToLong reducer) {
+ return ForkJoinTasks.reduceEntriesToLong
+ (map, transformer, basis, reducer).invoke();
+ }
+
+ /**
+ * Returns the result of accumulating the given transformation
+ * of all entries using the given reducer to combine values,
+ * and the given basis as an identity value.
+ *
+ * @param transformer a function returning the transformation
+ * for an element
+ * @param basis the identity (initial default value) for the reduction
+ * @param reducer a commutative associative combining function
+ * @return the result of accumulating the given transformation
+ * of all entries
+ */
+ public int reduceToInt(ObjectToInt> transformer,
+ int basis,
+ IntByIntToInt reducer) {
+ return ForkJoinTasks.reduceEntriesToInt
+ (map, transformer, basis, reducer).invoke();
+ }
+
+ }
+
// ---------------------------------------------------------------------
/**
@@ -4906,26 +5340,6 @@ public class ConcurrentHashMapV8
}
}
- // FJ methods
-
- /**
- * Propagates completion. Note that all reduce actions
- * bypass this method to combine while completing.
- */
- final void tryComplete() {
- BulkTask a = this, s = a;
- for (int c;;) {
- if ((c = a.pending) == 0) {
- if ((a = (s = a).parent) == null) {
- s.quietlyComplete();
- break;
- }
- }
- else if (U.compareAndSwapInt(a, PENDING, c, c - 1))
- break;
- }
- }
-
/**
* Forces root task to complete.
* @param ex if null, complete normally, else exceptionally
@@ -4973,7 +5387,7 @@ public class ConcurrentHashMapV8
baseLimit = baseSize = t.length;
if (t != null) {
long n = m.counter.sum();
- int par = (pool = getPool()) == null?
+ int par = ((pool = getPool()) == null) ?
ForkJoinPool.getCommonPoolParallelism() :
pool.getParallelism();
int sp = par << 3; // slack of 8
@@ -5004,6 +5418,50 @@ public class ConcurrentHashMapV8
}
}
+ /**
+ * Base class for non-reductive actions
+ */
+ @SuppressWarnings("serial") static abstract class BulkAction extends BulkTask {
+ BulkAction nextTask;
+ BulkAction(ConcurrentHashMapV8 map, BulkTask parent,
+ int batch, BulkAction nextTask) {
+ super(map, parent, batch);
+ this.nextTask = nextTask;
+ }
+
+ /**
+ * Try to complete task and upward parents. Upon hitting
+ * non-completed parent, if a non-FJ task, try to help out the
+ * computation.
+ */
+ final void tryComplete(BulkAction subtasks) {
+ BulkTask a = this, s = a;
+ for (int c;;) {
+ if ((c = a.pending) == 0) {
+ if ((a = (s = a).parent) == null) {
+ s.quietlyComplete();
+ break;
+ }
+ }
+ else if (a.casPending(c, c - 1)) {
+ if (subtasks != null && !inForkJoinPool()) {
+ while ((s = a.parent) != null)
+ a = s;
+ while (!a.isDone()) {
+ BulkAction next = subtasks.nextTask;
+ if (subtasks.tryUnfork())
+ subtasks.exec();
+ if ((subtasks = next) == null)
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ }
+
/*
* Task classes. Coded in a regular but ugly format/style to
* simplify checks that each variant differs in the right way from
@@ -5011,172 +5469,146 @@ public class ConcurrentHashMapV8
*/
@SuppressWarnings("serial") static final class ForEachKeyTask
- extends BulkTask {
+ extends BulkAction {
final Action action;
- ForEachKeyTask nextRight;
ForEachKeyTask
(ConcurrentHashMapV8 m, BulkTask p, int b,
- ForEachKeyTask nextRight,
+ ForEachKeyTask nextTask,
Action action) {
- super(m, p, b);
- this.nextRight = nextRight;
+ super(m, p, b, nextTask);
this.action = action;
}
@SuppressWarnings("unchecked") public final boolean exec() {
final Action action = this.action;
if (action == null)
return abortOnNullFunction();
- ForEachKeyTask rights = null;
+ ForEachKeyTask subtasks = null;
try {
int b = batch(), c;
while (b > 1 && baseIndex != baseLimit) {
do {} while (!casPending(c = pending, c+1));
- (rights = new ForEachKeyTask
- (map, this, b >>>= 1, rights, action)).fork();
+ (subtasks = new ForEachKeyTask
+ (map, this, b >>>= 1, subtasks, action)).fork();
}
while (advance() != null)
action.apply((K)nextKey);
- tryComplete();
} catch (Throwable ex) {
return tryCompleteComputation(ex);
}
- while (rights != null && rights.tryUnfork()) {
- rights.exec();
- rights = rights.nextRight;
- }
+ tryComplete(subtasks);
return false;
}
}
@SuppressWarnings("serial") static final class ForEachValueTask
- extends BulkTask {
- ForEachValueTask nextRight;
+ extends BulkAction {
final Action action;
ForEachValueTask
(ConcurrentHashMapV8 m, BulkTask p, int b,
- ForEachValueTask nextRight,
+ ForEachValueTask nextTask,
Action action) {
- super(m, p, b);
- this.nextRight = nextRight;
+ super(m, p, b, nextTask);
this.action = action;
}
@SuppressWarnings("unchecked") public final boolean exec() {
final Action action = this.action;
if (action == null)
return abortOnNullFunction();
- ForEachValueTask rights = null;
+ ForEachValueTask subtasks = null;
try {
int b = batch(), c;
while (b > 1 && baseIndex != baseLimit) {
do {} while (!casPending(c = pending, c+1));
- (rights = new ForEachValueTask
- (map, this, b >>>= 1, rights, action)).fork();
+ (subtasks = new ForEachValueTask
+ (map, this, b >>>= 1, subtasks, action)).fork();
}
Object v;
while ((v = advance()) != null)
action.apply((V)v);
- tryComplete();
} catch (Throwable ex) {
return tryCompleteComputation(ex);
}
- while (rights != null && rights.tryUnfork()) {
- rights.exec();
- rights = rights.nextRight;
- }
+ tryComplete(subtasks);
return false;
}
}
@SuppressWarnings("serial") static final class ForEachEntryTask
- extends BulkTask {
- ForEachEntryTask nextRight;
+ extends BulkAction {
final Action> action;
ForEachEntryTask
(ConcurrentHashMapV8 m, BulkTask p, int b,
- ForEachEntryTask nextRight,
+ ForEachEntryTask nextTask,
Action> action) {
- super(m, p, b);
- this.nextRight = nextRight;
+ super(m, p, b, nextTask);
this.action = action;
}
@SuppressWarnings("unchecked") public final boolean exec() {
final Action> action = this.action;
if (action == null)
return abortOnNullFunction();
- ForEachEntryTask rights = null;
+ ForEachEntryTask subtasks = null;
try {
int b = batch(), c;
while (b > 1 && baseIndex != baseLimit) {
do {} while (!casPending(c = pending, c+1));
- (rights = new ForEachEntryTask
- (map, this, b >>>= 1, rights, action)).fork();
+ (subtasks = new ForEachEntryTask
+ (map, this, b >>>= 1, subtasks, action)).fork();
}
Object v;
while ((v = advance()) != null)
action.apply(entryFor((K)nextKey, (V)v));
- tryComplete();
} catch (Throwable ex) {
return tryCompleteComputation(ex);
}
- while (rights != null && rights.tryUnfork()) {
- rights.exec();
- rights = rights.nextRight;
- }
+ tryComplete(subtasks);
return false;
}
}
@SuppressWarnings("serial") static final class ForEachMappingTask
- extends BulkTask {
- ForEachMappingTask nextRight;
+ extends BulkAction {
final BiAction action;
ForEachMappingTask
(ConcurrentHashMapV8 m, BulkTask p, int b,
- ForEachMappingTask nextRight,
+ ForEachMappingTask nextTask,
BiAction action) {
- super(m, p, b);
- this.nextRight = nextRight;
+ super(m, p, b, nextTask);
this.action = action;
}
@SuppressWarnings("unchecked") public final boolean exec() {
final BiAction action = this.action;
if (action == null)
return abortOnNullFunction();
- ForEachMappingTask rights = null;
+ ForEachMappingTask subtasks = null;
try {
int b = batch(), c;
while (b > 1 && baseIndex != baseLimit) {
do {} while (!casPending(c = pending, c+1));
- (rights = new ForEachMappingTask
- (map, this, b >>>= 1, rights, action)).fork();
+ (subtasks = new ForEachMappingTask
+ (map, this, b >>>= 1, subtasks, action)).fork();
}
Object v;
while ((v = advance()) != null)
action.apply((K)nextKey, (V)v);
- tryComplete();
} catch (Throwable ex) {
return tryCompleteComputation(ex);
}
- while (rights != null && rights.tryUnfork()) {
- rights.exec();
- rights = rights.nextRight;
- }
+ tryComplete(subtasks);
return false;
}
}
@SuppressWarnings("serial") static final class ForEachTransformedKeyTask
- extends BulkTask {
- ForEachTransformedKeyTask nextRight;
+ extends BulkAction {
final Fun super K, ? extends U> transformer;
final Action action;
ForEachTransformedKeyTask
(ConcurrentHashMapV8 m, BulkTask p, int b,
- ForEachTransformedKeyTask nextRight,
+ ForEachTransformedKeyTask nextTask,
Fun super K, ? extends U> transformer,
Action action) {
- super(m, p, b);
- this.nextRight = nextRight;
+ super(m, p, b, nextTask);
this.transformer = transformer;
this.action = action;
@@ -5187,43 +5619,37 @@ public class ConcurrentHashMapV8
final Action action = this.action;
if (transformer == null || action == null)
return abortOnNullFunction();
- ForEachTransformedKeyTask rights = null;
+ ForEachTransformedKeyTask subtasks = null;
try {
int b = batch(), c;
while (b > 1 && baseIndex != baseLimit) {
do {} while (!casPending(c = pending, c+1));
- (rights = new ForEachTransformedKeyTask
- (map, this, b >>>= 1, rights, transformer, action)).fork();
+ (subtasks = new ForEachTransformedKeyTask
+ (map, this, b >>>= 1, subtasks, transformer, action)).fork();
}
U u;
while (advance() != null) {
if ((u = transformer.apply((K)nextKey)) != null)
action.apply(u);
}
- tryComplete();
} catch (Throwable ex) {
return tryCompleteComputation(ex);
}
- while (rights != null && rights.tryUnfork()) {
- rights.exec();
- rights = rights.nextRight;
- }
+ tryComplete(subtasks);
return false;
}
}
@SuppressWarnings("serial") static final class ForEachTransformedValueTask
- extends BulkTask {
- ForEachTransformedValueTask nextRight;
+ extends BulkAction {
final Fun super V, ? extends U> transformer;
final Action action;
ForEachTransformedValueTask
(ConcurrentHashMapV8 m, BulkTask p, int b,
- ForEachTransformedValueTask nextRight,
+ ForEachTransformedValueTask nextTask,
Fun super V, ? extends U> transformer,
Action action) {
- super(m, p, b);
- this.nextRight = nextRight;
+ super(m, p, b, nextTask);
this.transformer = transformer;
this.action = action;
@@ -5234,43 +5660,37 @@ public class ConcurrentHashMapV8
final Action action = this.action;
if (transformer == null || action == null)
return abortOnNullFunction();
- ForEachTransformedValueTask rights = null;
+ ForEachTransformedValueTask subtasks = null;
try {
int b = batch(), c;
while (b > 1 && baseIndex != baseLimit) {
do {} while (!casPending(c = pending, c+1));
- (rights = new ForEachTransformedValueTask
- (map, this, b >>>= 1, rights, transformer, action)).fork();
+ (subtasks = new ForEachTransformedValueTask
+ (map, this, b >>>= 1, subtasks, transformer, action)).fork();
}
Object v; U u;
while ((v = advance()) != null) {
if ((u = transformer.apply((V)v)) != null)
action.apply(u);
}
- tryComplete();
} catch (Throwable ex) {
return tryCompleteComputation(ex);
}
- while (rights != null && rights.tryUnfork()) {
- rights.exec();
- rights = rights.nextRight;
- }
+ tryComplete(subtasks);
return false;
}
}
@SuppressWarnings("serial") static final class ForEachTransformedEntryTask
- extends BulkTask {
- ForEachTransformedEntryTask nextRight;
+ extends BulkAction {
final Fun, ? extends U> transformer;
final Action action;
ForEachTransformedEntryTask
(ConcurrentHashMapV8 m, BulkTask p, int b,
- ForEachTransformedEntryTask nextRight,
+ ForEachTransformedEntryTask nextTask,
Fun, ? extends U> transformer,
Action action) {
- super(m, p, b);
- this.nextRight = nextRight;
+ super(m, p, b, nextTask);
this.transformer = transformer;
this.action = action;
@@ -5281,43 +5701,37 @@ public class ConcurrentHashMapV8
final Action action = this.action;
if (transformer == null || action == null)
return abortOnNullFunction();
- ForEachTransformedEntryTask rights = null;
+ ForEachTransformedEntryTask subtasks = null;
try {
int b = batch(), c;
while (b > 1 && baseIndex != baseLimit) {
do {} while (!casPending(c = pending, c+1));
- (rights = new ForEachTransformedEntryTask
- (map, this, b >>>= 1, rights, transformer, action)).fork();
+ (subtasks = new ForEachTransformedEntryTask
+ (map, this, b >>>= 1, subtasks, transformer, action)).fork();
}
Object v; U u;
while ((v = advance()) != null) {
if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
action.apply(u);
}
- tryComplete();
} catch (Throwable ex) {
return tryCompleteComputation(ex);
}
- while (rights != null && rights.tryUnfork()) {
- rights.exec();
- rights = rights.nextRight;
- }
+ tryComplete(subtasks);
return false;
}
}
@SuppressWarnings("serial") static final class ForEachTransformedMappingTask
- extends BulkTask {
- ForEachTransformedMappingTask nextRight;
+ extends BulkAction {
final BiFun super K, ? super V, ? extends U> transformer;
final Action action;
ForEachTransformedMappingTask
(ConcurrentHashMapV8 m, BulkTask p, int b,
- ForEachTransformedMappingTask nextRight,
+ ForEachTransformedMappingTask nextTask,
BiFun super K, ? super V, ? extends U> transformer,
Action action) {
- super(m, p, b);
- this.nextRight = nextRight;
+ super(m, p, b, nextTask);
this.transformer = transformer;
this.action = action;
@@ -5328,43 +5742,37 @@ public class ConcurrentHashMapV8
final Action action = this.action;
if (transformer == null || action == null)
return abortOnNullFunction();
- ForEachTransformedMappingTask rights = null;
+ ForEachTransformedMappingTask subtasks = null;
try {
int b = batch(), c;
while (b > 1 && baseIndex != baseLimit) {
do {} while (!casPending(c = pending, c+1));
- (rights = new ForEachTransformedMappingTask
- (map, this, b >>>= 1, rights, transformer, action)).fork();
+ (subtasks = new ForEachTransformedMappingTask
+ (map, this, b >>>= 1, subtasks, transformer, action)).fork();
}
Object v; U u;
while ((v = advance()) != null) {
if ((u = transformer.apply((K)nextKey, (V)v)) != null)
action.apply(u);
}
- tryComplete();
} catch (Throwable ex) {
return tryCompleteComputation(ex);
}
- while (rights != null && rights.tryUnfork()) {
- rights.exec();
- rights = rights.nextRight;
- }
+ tryComplete(subtasks);
return false;
}
}
@SuppressWarnings("serial") static final class SearchKeysTask