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

Comparing jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java (file contents):
Revision 1.103 by jsr166, Fri Apr 12 18:44:19 2013 UTC vs.
Revision 1.104 by jsr166, Fri Apr 12 20:23:03 2013 UTC

# Line 498 | Line 498 | public class CopyOnWriteArrayList<E>
498       * @return {@code true} if this list contained the specified element
499       */
500      public boolean remove(Object o) {
501 +        Object[] snapshot = getArray();
502 +        int index = indexOf(o, snapshot, 0, snapshot.length);
503 +        return (index < 0) ? false : remove(o, snapshot, index);
504 +    }
505 +
506 +    /**
507 +     * A version of remove(Object) using the strong hint that given
508 +     * recent snapshot contains o at the given index.
509 +     */
510 +    private boolean remove(Object o, Object[] snapshot, int index) {
511          final ReentrantLock lock = this.lock;
512          lock.lock();
513          try {
514 <            Object[] elements = getArray();
515 <            int len = elements.length;
516 <            if (len != 0) {
517 <                // Copy while searching for element to remove
518 <                // This wins in the normal case of element being present
519 <                int newlen = len - 1;
520 <                Object[] newElements = new Object[newlen];
521 <
522 <                for (int i = 0; i < newlen; ++i) {
513 <                    if (eq(o, elements[i])) {
514 <                        // found one;  copy remaining and exit
515 <                        for (int k = i + 1; k < len; ++k)
516 <                            newElements[k-1] = elements[k];
517 <                        setArray(newElements);
518 <                        return true;
519 <                    } else
520 <                        newElements[i] = elements[i];
521 <                }
522 <
523 <                // special handling for last cell
524 <                if (eq(o, elements[newlen])) {
525 <                    setArray(newElements);
526 <                    return true;
514 >            Object[] current = getArray();
515 >            int len = current.length;
516 >            if (snapshot != current) findIndex: {
517 >                int prefix = Math.min(index, len);
518 >                for (int i = 0; i < prefix; i++) {
519 >                    if (current[i] != snapshot[i] && eq(o, current[i])) {
520 >                        index = i;
521 >                        break findIndex;
522 >                    }
523                  }
524 +                if (index >= len)
525 +                    return false;
526 +                if (current[index] == o)
527 +                    break findIndex;
528 +                index = indexOf(o, current, index, len);
529 +                if (index < 0)
530 +                    return false;
531              }
532 <            return false;
532 >            Object[] newElements = new Object[len - 1];
533 >            System.arraycopy(current, 0, newElements, 0, index);
534 >            System.arraycopy(current, index + 1,
535 >                             newElements, index,
536 >                             len - index - 1);
537 >            setArray(newElements);
538 >            return true;
539          } finally {
540              lock.unlock();
541          }
# Line 576 | Line 585 | public class CopyOnWriteArrayList<E>
585       * @return {@code true} if the element was added
586       */
587      public boolean addIfAbsent(E e) {
588 +        Object[] snapshot = getArray();
589 +        return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
590 +            addIfAbsent(e, snapshot);
591 +    }
592 +
593 +    /**
594 +     * A version of addIfAbsent using the strong hint that given
595 +     * recent snapshot does not contain e.
596 +     */
597 +    private boolean addIfAbsent(E e, Object[] snapshot) {
598          final ReentrantLock lock = this.lock;
599          lock.lock();
600          try {
601 <            Object[] elements = getArray();
602 <            int len = elements.length;
603 <            for (int i = 0; i < len; ++i) {
604 <                if (eq(e, elements[i]))
605 <                    return false;
601 >            Object[] current = getArray();
602 >            int len = current.length;
603 >            if (snapshot != current) {
604 >                // Optimize for lost race to another addXXX operation
605 >                int common = Math.min(snapshot.length, len);
606 >                for (int i = 0; i < common; i++)
607 >                    if (current[i] != snapshot[i] && eq(e, current[i]))
608 >                        return false;
609 >                if (indexOf(e, current, common, len) >= 0)
610 >                        return false;
611              }
612 <            Object[] newElements = Arrays.copyOf(elements, len + 1);
612 >            Object[] newElements = Arrays.copyOf(current, len + 1);
613              newElements[len] = e;
614              setArray(newElements);
615              return true;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines