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.16 by dl, Wed Sep 14 23:49:59 2005 UTC vs.
Revision 1.21 by dl, Fri Sep 16 23:17:05 2005 UTC

# Line 491 | Line 491 | public class ArrayDeque<E> extends Abstr
491       */
492      private boolean delete(int i) {
493          int mask = elements.length - 1;
494 +        int front = (i - head) & mask;
495 +        int back  = (tail - i) & mask;
496  
497          // Invariant: head <= i < tail mod circularity
498 <        if (((i - head) & mask) >= ((tail - head) & mask))
498 >        if (front >= ((tail - head) & mask))
499              throw new ConcurrentModificationException();
500  
501 <        // Case 1: Deque doesn't wrap
502 <        // Case 2: Deque does wrap and removed element is in the head portion
503 <        if (i >= head) {
504 <            System.arraycopy(elements, head, elements, head + 1, i - head);
505 <            elements[head] = null;
506 <            head = (head + 1) & mask;
501 >        // Optimize for least element motion
502 >        if (front < back) {
503 >            if (head <= i) {
504 >                System.arraycopy(elements, head, elements, head + 1, front);
505 >            } else { // Wrap around
506 >                elements[0] = elements[mask];
507 >                System.arraycopy(elements, 0, elements, 1, i);
508 >                System.arraycopy(elements, head, elements, head + 1, mask - head);
509 >            }
510 >            elements[head] = null;
511 >            head = (head + 1) & mask;
512              return false;
513 <        }
514 <
515 <        // Case 3: Deque wraps and removed element is in the tail portion
516 <        tail--;
517 <        System.arraycopy(elements, i + 1, elements, i, tail - i);
518 <        elements[tail] = null;
519 <        return true;
513 >        } else {
514 >            int t = tail;
515 >            tail = (tail - 1) & mask;
516 >            if (i < t) { // Copy the null tail as well
517 >                System.arraycopy(elements, i + 1, elements, i, back);
518 >            } else {     // Wrap around
519 >                elements[mask] = elements[0];
520 >                System.arraycopy(elements, i + 1, elements, i, mask - i);
521 >                System.arraycopy(elements, 1, elements, 0, t);
522 >            }
523 >            return true;
524 >        }
525      }
526  
527      // *** Collection Methods ***
# Line 538 | Line 550 | public class ArrayDeque<E> extends Abstr
550       * order that elements would be dequeued (via successive calls to
551       * {@link #remove} or popped (via successive calls to {@link #pop}).
552       *
553 <     * @return an <tt>Iterator</tt> over the elements in this deque
553 >     * @return an iterator over the elements in this deque
554       */
555      public Iterator<E> iterator() {
556          return new DeqIterator();
557      }
558  
547    /**
548     * Returns an iterator over the elements in this deque in reverse
549     * sequential order.  The elements will be returned in order from
550     * last (tail) to first (head).
551     *
552     * @return an iterator over the elements in this deque in reverse
553     * sequence
554     */
559      public Iterator<E> descendingIterator() {
560          return new DescendingIterator();
561      }
# Line 594 | Line 598 | public class ArrayDeque<E> extends Abstr
598          public void remove() {
599              if (lastRet < 0)
600                  throw new IllegalStateException();
601 <            if (delete(lastRet))
602 <                cursor--;
601 >            if (delete(lastRet)) // if left-shifted, undo increment in next()
602 >                cursor = (cursor - 1) & (elements.length - 1);
603              lastRet = -1;
604              fence = tail;
605          }
# Line 603 | Line 607 | public class ArrayDeque<E> extends Abstr
607  
608  
609      private class DescendingIterator implements Iterator<E> {
610 <        /*
611 <         * This class is nearly a mirror-image of DeqIterator. It
612 <         * shares the same structure, but not many actual lines of
613 <         * code. The only asymmetric part is that to simplify some
614 <         * checks, indices are anded with length mask only on array
615 <         * access rather than on each update.
610 >        /*
611 >         * This class is nearly a mirror-image of DeqIterator, using
612 >         * (tail-1) instead of head for initial cursor, (head-1)
613 >         * instead of tail for fence, and elements.length instead of -1
614 >         * for sentinel. It shares the same structure, but not many
615 >         * actual lines of code.
616           */
617 <        private int cursor = tail - 1;
618 <        private int fence = head - 1;
617 >        private int cursor = (tail - 1) & (elements.length - 1);
618 >        private int fence =  (head - 1) & (elements.length - 1);
619          private int lastRet = elements.length;
620  
621          public boolean hasNext() {
# Line 622 | Line 626 | public class ArrayDeque<E> extends Abstr
626              E result;
627              if (cursor == fence)
628                  throw new NoSuchElementException();
629 <            if ((head - 1) != fence ||
630 <                (result = elements[cursor & (elements.length-1)]) == null)
629 >            if (((head - 1) & (elements.length - 1)) != fence ||
630 >                (result = elements[cursor]) == null)
631                  throw new ConcurrentModificationException();
632              lastRet = cursor;
633 <            cursor--;
633 >            cursor = (cursor - 1) & (elements.length - 1);
634              return result;
635          }
636  
637          public void remove() {
638              if (lastRet >= elements.length)
639                  throw new IllegalStateException();
640 <            if (delete(lastRet & (elements.length-1)))
641 <                cursor++;
640 >            if (!delete(lastRet))
641 >                cursor = (cursor + 1) & (elements.length - 1);
642              lastRet = elements.length;
643 <            fence = head - 1;
643 >            fence = (head - 1) & (elements.length - 1);
644          }
645      }
646  
# Line 798 | Line 802 | public class ArrayDeque<E> extends Abstr
802          s.defaultWriteObject();
803  
804          // Write out size
805 <        int size = size();
802 <        s.writeInt(size);
805 >        s.writeInt(size());
806  
807          // Write out elements in order.
805        int i = head;
808          int mask = elements.length - 1;
809 <        for (int j = 0; j < size; j++) {
809 >        for (int i = head; i != tail; i = (i + 1) & mask)
810              s.writeObject(elements[i]);
809            i = (i + 1) & mask;
810        }
811      }
812  
813      /**

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines