ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/ArrayDeque.java
(Generate patch)

Comparing jsr166/src/main/java/util/ArrayDeque.java (file contents):
Revision 1.112 by jsr166, Tue Nov 8 18:23:10 2016 UTC vs.
Revision 1.113 by jsr166, Sun Nov 13 02:10:09 2016 UTC

# Line 950 | Line 950 | public class ArrayDeque<E> extends Abstr
950               ; i = 0, to = end) {
951              for (; i < to; i++)
952                  if (filter.test(elementAt(es, i)))
953 <                    return bulkRemoveModified(filter, i, to);
953 >                    return bulkRemoveModified(filter, i);
954              if (to == end) {
955                  if (end != tail) throw new ConcurrentModificationException();
956                  break;
# Line 959 | Line 959 | public class ArrayDeque<E> extends Abstr
959          return false;
960      }
961  
962 +    // A tiny bit set implementation
963 +
964 +    private static long[] nBits(int n) {
965 +        return new long[((n - 1) >> 6) + 1];
966 +    }
967 +    private static void setBit(long[] bits, int i) {
968 +        bits[i >> 6] |= 1L << i;
969 +    }
970 +    private static boolean isClear(long[] bits, int i) {
971 +        return (bits[i >> 6] & (1L << i)) == 0;
972 +    }
973 +
974      /**
975       * Helper for bulkRemove, in case of at least one deletion.
976 <     * @param i valid index of first element to be deleted
976 >     * Tolerate predicates that reentrantly access the collection for
977 >     * read (but writers still get CME), so traverse once to find
978 >     * elements to delete, a second pass to physically expunge.
979 >     *
980 >     * @param beg valid index of first element to be deleted
981       */
982      private boolean bulkRemoveModified(
983 <        Predicate<? super E> filter, int i, int to) {
983 >        Predicate<? super E> filter, final int beg) {
984          final Object[] es = elements;
985          final int capacity = es.length;
970        // a two-finger algorithm, with hare i reading, tortoise j writing
971        int j = i++;
986          final int end = tail;
987 <        try {
988 <            for (;; j = 0) {    // j rejoins i on second leg
989 <                E e;
990 <                // In this loop, i and j are on the same leg, with i > j
991 <                for (; i < to; i++)
992 <                    if (!filter.test(e = elementAt(es, i)))
993 <                        es[j++] = e;
994 <                if (to == end) break;
995 <                // In this loop, j is on the first leg, i on the second
996 <                for (i = 0, to = end; i < to && j < capacity; i++)
997 <                    if (!filter.test(e = elementAt(es, i)))
998 <                        es[j++] = e;
999 <                if (i >= to) {
1000 <                    if (j == capacity) j = 0; // "corner" case
1001 <                    break;
1002 <                }
987 >        final long[] deathRow = nBits(sub(end, beg, capacity));
988 >        deathRow[0] = 1L;   // set bit 0
989 >        for (int i = beg + 1, to = (i <= end) ? end : es.length, k = beg;
990 >             ; i = 0, to = end, k -= capacity) {
991 >            for (; i < to; i++)
992 >                if (filter.test(elementAt(es, i)))
993 >                    setBit(deathRow, i - k);
994 >            if (to == end) break;
995 >        }
996 >        // a two-finger traversal, with hare i reading, tortoise w writing
997 >        int w = beg;
998 >        for (int i = beg + 1, to = (i <= end) ? end : es.length, k = beg;
999 >             ; w = 0) { // w rejoins i on second leg
1000 >            // In this loop, i and w are on the same leg, with i > w
1001 >            for (; i < to; i++)
1002 >                if (isClear(deathRow, i - k))
1003 >                    es[w++] = es[i];
1004 >            if (to == end) break;
1005 >            // In this loop, w is on the first leg, i on the second
1006 >            for (i = 0, to = end, k -= capacity; i < to && w < capacity; i++)
1007 >                if (isClear(deathRow, i - k))
1008 >                    es[w++] = es[i];
1009 >            if (i >= to) {
1010 >                if (w == capacity) w = 0; // "corner" case
1011 >                break;
1012              }
990            return true;
991        } catch (Throwable ex) {
992            // copy remaining elements
993            for (; i != end; i = inc(i, capacity), j = inc(j, capacity))
994                es[j] = es[i];
995            throw ex;
996        } finally {
997            if (end != tail) throw new ConcurrentModificationException();
998            circularClear(es, tail = j, end);
999            // checkInvariants();
1013          }
1014 +        if (end != tail) throw new ConcurrentModificationException();
1015 +        circularClear(es, tail = w, end);
1016 +        // checkInvariants();
1017 +        return true;
1018      }
1019  
1020      /**

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines