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.77 by jsr166, Tue Oct 18 00:33:05 2016 UTC vs.
Revision 1.89 by jsr166, Mon Oct 24 23:40:56 2016 UTC

# Line 134 | Line 134 | public class ArrayDeque<E> extends Abstr
134       * to ensure that it can hold at least the given number of elements.
135       *
136       * @param minCapacity the desired minimum capacity
137 <     * @since 9
137 >     * @since TBD
138       */
139 <    public void ensureCapacity(int minCapacity) {
139 >    /* public */ void ensureCapacity(int minCapacity) {
140          if (minCapacity > elements.length)
141              grow(minCapacity - elements.length);
142          // checkInvariants();
# Line 145 | Line 145 | public class ArrayDeque<E> extends Abstr
145      /**
146       * Minimizes the internal storage of this collection.
147       *
148 <     * @since 9
148 >     * @since TBD
149       */
150 <    public void trimToSize() {
150 >    /* public */ void trimToSize() {
151          if (size < elements.length) {
152              elements = toArray();
153              head = 0;
# Line 187 | Line 187 | public class ArrayDeque<E> extends Abstr
187          Object[] elements = c.toArray();
188          // defend against c.toArray (incorrectly) not returning Object[]
189          // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
190 +        size = elements.length;
191          if (elements.getClass() != Object[].class)
192              elements = Arrays.copyOf(elements, size, Object[].class);
193          for (Object obj : elements)
194              Objects.requireNonNull(obj);
194        size = elements.length;
195          this.elements = elements;
196      }
197  
198      /**
199 <     * Returns the array index of the last element.
200 <     * May return invalid index -1 if there are no elements.
199 >     * Increments i, mod modulus.
200 >     * Precondition and postcondition: 0 <= i < modulus.
201       */
202 <    final int tail() {
203 <        return add(head, size - 1, elements.length);
202 >    static final int inc(int i, int modulus) {
203 >        if (++i >= modulus) i = 0;
204 >        return i;
205      }
206  
207      /**
208 <     * Adds i and j, mod modulus.
209 <     * Precondition and postcondition: 0 <= i < modulus, 0 <= j <= modulus.
208 >     * Decrements i, mod modulus.
209 >     * Precondition and postcondition: 0 <= i < modulus.
210       */
211 <    static final int add(int i, int j, int modulus) {
212 <        if ((i += j) - modulus >= 0) i -= modulus;
211 >    static final int dec(int i, int modulus) {
212 >        if (--i < 0) i = modulus - 1;
213          return i;
214      }
215  
216      /**
217 <     * Increments i, mod modulus.
218 <     * Precondition and postcondition: 0 <= i < modulus.
217 >     * Adds i and j, mod modulus.
218 >     * Precondition and postcondition: 0 <= i < modulus, 0 <= j <= modulus.
219       */
220 <    static final int inc(int i, int modulus) {
221 <        if (++i == modulus) i = 0;
220 >    static final int add(int i, int j, int modulus) {
221 >        if ((i += j) - modulus >= 0) i -= modulus;
222          return i;
223      }
224  
225      /**
226 <     * Decrements i, mod modulus.
227 <     * Precondition and postcondition: 0 <= i < modulus.
226 >     * Returns the array index of the last element.
227 >     * May return invalid index -1 if there are no elements.
228       */
229 <    static final int dec(int i, int modulus) {
230 <        if (--i < 0) i += modulus;
230 <        return i;
229 >    final int tail() {
230 >        return add(head, size - 1, elements.length);
231      }
232  
233      /**
234       * Returns element at array index i.
235       */
236      @SuppressWarnings("unchecked")
237 <    final E elementAt(int i) {
237 >    private E elementAt(int i) {
238          return (E) elements[i];
239      }
240  
# Line 264 | Line 264 | public class ArrayDeque<E> extends Abstr
264          // checkInvariants();
265          Objects.requireNonNull(e);
266          Object[] elements;
267 <        int capacity, s = size;
268 <        while (s == (capacity = (elements = this.elements).length))
267 >        int capacity, h;
268 >        final int s;
269 >        if ((s = size) == (capacity = (elements = this.elements).length)) {
270              grow(1);
271 <        elements[head = dec(head, capacity)] = e;
271 >            capacity = (elements = this.elements).length;
272 >        }
273 >        if ((h = head - 1) < 0) h = capacity - 1;
274 >        elements[head = h] = e;
275          size = s + 1;
276 +        // checkInvariants();
277      }
278  
279      /**
# Line 283 | Line 288 | public class ArrayDeque<E> extends Abstr
288          // checkInvariants();
289          Objects.requireNonNull(e);
290          Object[] elements;
291 <        int capacity, s = size;
292 <        while (s == (capacity = (elements = this.elements).length))
291 >        int capacity;
292 >        final int s;
293 >        if ((s = size) == (capacity = (elements = this.elements).length)) {
294              grow(1);
295 +            capacity = (elements = this.elements).length;
296 +        }
297          elements[add(head, s, capacity)] = e;
298          size = s + 1;
299 +        // checkInvariants();
300      }
301  
302      /**
# Line 301 | Line 310 | public class ArrayDeque<E> extends Abstr
310       * @throws NullPointerException if the specified collection or any
311       *         of its elements are null
312       */
304    @Override
313      public boolean addAll(Collection<? extends E> c) {
314 +        final int s = size, needed = c.size() - (elements.length - s);
315 +        if (needed > 0)
316 +            grow(needed);
317 +        c.forEach((e) -> addLast(e));
318          // checkInvariants();
319 <        Object[] a, elements;
308 <        int len, capacity, s = size;
309 <        if ((len = (a = c.toArray()).length) == 0)
310 <            return false;
311 <        while ((capacity = (elements = this.elements).length) - s < len)
312 <            grow(len - (capacity - s));
313 <        int i = add(head, s, capacity);
314 <        for (Object x : a) {
315 <            Objects.requireNonNull(x);
316 <            elements[i] = x;
317 <            i = inc(i, capacity);
318 <            size++;
319 <        }
320 <        return true;
319 >        return size > s;
320      }
321  
322      /**
# Line 349 | Line 348 | public class ArrayDeque<E> extends Abstr
348       */
349      public E removeFirst() {
350          // checkInvariants();
351 <        E x = pollFirst();
352 <        if (x == null)
351 >        E e = pollFirst();
352 >        if (e == null)
353              throw new NoSuchElementException();
354 <        return x;
354 >        return e;
355      }
356  
357      /**
# Line 360 | Line 359 | public class ArrayDeque<E> extends Abstr
359       */
360      public E removeLast() {
361          // checkInvariants();
362 <        E x = pollLast();
363 <        if (x == null)
362 >        E e = pollLast();
363 >        if (e == null)
364              throw new NoSuchElementException();
365 <        return x;
365 >        return e;
366      }
367  
368      public E pollFirst() {
369          // checkInvariants();
370 <        final int s, h;
370 >        int s, h;
371          if ((s = size) == 0)
372              return null;
373          final Object[] elements = this.elements;
374          @SuppressWarnings("unchecked") E e = (E) elements[h = head];
375          elements[h] = null;
376 <        head = inc(h, elements.length);
376 >        if (++h >= elements.length) h = 0;
377 >        head = h;
378          size = s - 1;
379          return e;
380      }
# Line 433 | Line 433 | public class ArrayDeque<E> extends Abstr
433       * @return {@code true} if the deque contained the specified element
434       */
435      public boolean removeFirstOccurrence(Object o) {
436        // checkInvariants();
436          if (o != null) {
437              final Object[] elements = this.elements;
438              final int capacity = elements.length;
439 <            for (int k = size, i = head; --k >= 0; i = inc(i, capacity)) {
440 <                if (o.equals(elements[i])) {
441 <                    delete(i);
442 <                    return true;
443 <                }
439 >            int from, end, to, leftover;
440 >            leftover = (end = (from = head) + size)
441 >                - (to = (capacity - end >= 0) ? end : capacity);
442 >            for (;; from = 0, to = leftover, leftover = 0) {
443 >                for (int i = from; i < to; i++)
444 >                    if (o.equals(elements[i])) {
445 >                        delete(i);
446 >                        return true;
447 >                    }
448 >                if (leftover == 0) break;
449              }
450          }
451          return false;
# Line 463 | Line 467 | public class ArrayDeque<E> extends Abstr
467          if (o != null) {
468              final Object[] elements = this.elements;
469              final int capacity = elements.length;
470 <            for (int k = size, i = add(head, k - 1, capacity);
471 <                 --k >= 0; i = dec(i, capacity)) {
472 <                if (o.equals(elements[i])) {
473 <                    delete(i);
474 <                    return true;
475 <                }
470 >            int from, to, end, leftover;
471 >            leftover = (to = ((end = (from = tail()) - size) >= -1) ? end : -1) - end;
472 >            for (;; from = capacity - 1, to = capacity - 1 - leftover, leftover = 0) {
473 >                for (int i = from; i > to; i--)
474 >                    if (o.equals(elements[i])) {
475 >                        delete(i);
476 >                        return true;
477 >                    }
478 >                if (leftover == 0) break;
479              }
480          }
481          return false;
# Line 616 | Line 623 | public class ArrayDeque<E> extends Abstr
623                  System.arraycopy(elements, h, elements, h + 1, front - (i + 1));
624              }
625              elements[h] = null;
626 <            head = inc(h, capacity);
626 >            if ((head = (h + 1)) >= capacity) head = 0;
627              size--;
628              // checkInvariants();
629              return false;
# Line 689 | Line 696 | public class ArrayDeque<E> extends Abstr
696  
697          DeqIterator() { cursor = head; }
698  
692        int advance(int i, int modulus) {
693            return inc(i, modulus);
694        }
695
696        void doRemove() {
697            if (delete(lastRet))
698                // if left-shifted, undo advance in next()
699                cursor = dec(cursor, elements.length);
700        }
701
699          public final boolean hasNext() {
700              return remaining > 0;
701          }
702  
703 <        public final E next() {
703 >        public E next() {
704              if (remaining == 0)
705                  throw new NoSuchElementException();
706 +            final Object[] elements = ArrayDeque.this.elements;
707              E e = checkedElementAt(elements, cursor);
708              lastRet = cursor;
709 <            cursor = advance(cursor, elements.length);
709 >            if (++cursor >= elements.length) cursor = 0;
710              remaining--;
711              return e;
712          }
713  
714 +        void postDelete(boolean leftShifted) {
715 +            if (leftShifted)
716 +                if (--cursor < 0) cursor = elements.length - 1;
717 +        }
718 +
719          public final void remove() {
720              if (lastRet < 0)
721                  throw new IllegalStateException();
722 <            doRemove();
722 >            postDelete(delete(lastRet));
723              lastRet = -1;
724          }
725  
726 <        public final void forEachRemaining(Consumer<? super E> action) {
727 <            Objects.requireNonNull(action);
728 <            final Object[] elements = ArrayDeque.this.elements;
729 <            final int capacity = elements.length;
730 <            int k = remaining;
731 <            remaining = 0;
732 <            for (int i = cursor; --k >= 0; i = advance(i, capacity))
733 <                action.accept(checkedElementAt(elements, i));
726 >        public void forEachRemaining(Consumer<? super E> action) {
727 >            int k;
728 >            if ((k = remaining) > 0) {
729 >                remaining = 0;
730 >                ArrayDeque.forEachRemaining(action, elements, cursor, k);
731 >                if ((lastRet = cursor + k - 1) >= elements.length)
732 >                    lastRet -= elements.length;
733 >            }
734          }
735      }
736  
737      private class DescendingIterator extends DeqIterator {
738          DescendingIterator() { cursor = tail(); }
739  
740 <        @Override int advance(int i, int modulus) {
741 <            return dec(i, modulus);
740 >        public final E next() {
741 >            if (remaining == 0)
742 >                throw new NoSuchElementException();
743 >            final Object[] elements = ArrayDeque.this.elements;
744 >            E e = checkedElementAt(elements, cursor);
745 >            lastRet = cursor;
746 >            if (--cursor < 0) cursor = elements.length - 1;
747 >            remaining--;
748 >            return e;
749          }
750  
751 <        @Override void doRemove() {
752 <            if (!delete(lastRet))
753 <                // if right-shifted, undo advance in next
754 <                cursor = inc(cursor, elements.length);
751 >        void postDelete(boolean leftShifted) {
752 >            if (!leftShifted)
753 >                if (++cursor >= elements.length) cursor = 0;
754 >        }
755 >
756 >        public final void forEachRemaining(Consumer<? super E> action) {
757 >            int k;
758 >            if ((k = remaining) > 0) {
759 >                remaining = 0;
760 >                forEachRemainingDescending(action, elements, cursor, k);
761 >                if ((lastRet = cursor - (k - 1)) < 0)
762 >                    lastRet += elements.length;
763 >            }
764          }
765      }
766  
# Line 798 | Line 817 | public class ArrayDeque<E> extends Abstr
817          }
818  
819          public void forEachRemaining(Consumer<? super E> action) {
820 <            Objects.requireNonNull(action);
802 <            final Object[] elements = ArrayDeque.this.elements;
803 <            final int capacity = elements.length;
804 <            int k = remaining();
820 >            int k = remaining(); // side effect!
821              remaining = 0;
822 <            for (int i = cursor; --k >= 0; i = inc(i, capacity))
807 <                action.accept(checkedElementAt(elements, i));
822 >            ArrayDeque.forEachRemaining(action, elements, cursor, k);
823          }
824  
825          public boolean tryAdvance(Consumer<? super E> action) {
# Line 812 | Line 827 | public class ArrayDeque<E> extends Abstr
827              if (remaining() == 0)
828                  return false;
829              action.accept(checkedElementAt(elements, cursor));
830 <            cursor = inc(cursor, elements.length);
830 >            if (++cursor >= elements.length) cursor = 0;
831              remaining--;
832              return true;
833          }
# Line 829 | Line 844 | public class ArrayDeque<E> extends Abstr
844          }
845      }
846  
847 <    @Override
847 >    @SuppressWarnings("unchecked")
848      public void forEach(Consumer<? super E> action) {
834        // checkInvariants();
849          Objects.requireNonNull(action);
850          final Object[] elements = this.elements;
851          final int capacity = elements.length;
852 <        for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
853 <            action.accept(elementAt(i));
852 >        int from, end, to, leftover;
853 >        leftover = (end = (from = head) + size)
854 >            - (to = (capacity - end >= 0) ? end : capacity);
855 >        for (;; from = 0, to = leftover, leftover = 0) {
856 >            for (int i = from; i < to; i++)
857 >                action.accept((E) elements[i]);
858 >            if (leftover == 0) break;
859 >        }
860          // checkInvariants();
861      }
862  
863      /**
864 +     * A variant of forEach that also checks for concurrent
865 +     * modification, for use in iterators.
866 +     */
867 +    static <E> void forEachRemaining(
868 +        Consumer<? super E> action, Object[] elements, int from, int size) {
869 +        Objects.requireNonNull(action);
870 +        final int capacity = elements.length;
871 +        int end, to, leftover;
872 +        leftover = (end = from + size)
873 +            - (to = (capacity - end >= 0) ? end : capacity);
874 +        for (;; from = 0, to = leftover, leftover = 0) {
875 +            for (int i = from; i < to; i++) {
876 +                @SuppressWarnings("unchecked") E e = (E) elements[i];
877 +                if (e == null)
878 +                    throw new ConcurrentModificationException();
879 +                action.accept(e);
880 +            }
881 +            if (leftover == 0) break;
882 +        }
883 +    }
884 +
885 +    static <E> void forEachRemainingDescending(
886 +        Consumer<? super E> action, Object[] elements, int from, int size) {
887 +        Objects.requireNonNull(action);
888 +        final int capacity = elements.length;
889 +        int end, to, leftover;
890 +        leftover = (to = ((end = from - size) >= -1) ? end : -1) - end;
891 +        for (;; from = capacity - 1, to = capacity - 1 - leftover, leftover = 0) {
892 +            for (int i = from; i > to; i--) {
893 +                @SuppressWarnings("unchecked") E e = (E) elements[i];
894 +                if (e == null)
895 +                    throw new ConcurrentModificationException();
896 +                action.accept(e);
897 +            }
898 +            if (leftover == 0) break;
899 +        }
900 +    }
901 +
902 +    /**
903       * Replaces each element of this deque with the result of applying the
904       * operator to that element, as specified by {@link List#replaceAll}.
905       *
906       * @param operator the operator to apply to each element
907 <     * @since 9
907 >     * @since TBD
908       */
909 <    public void replaceAll(UnaryOperator<E> operator) {
909 >    /* public */ void replaceAll(UnaryOperator<E> operator) {
910          Objects.requireNonNull(operator);
911          final Object[] elements = this.elements;
912          final int capacity = elements.length;
913 <        for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
914 <            elements[i] = operator.apply(elementAt(i));
913 >        int from, end, to, leftover;
914 >        leftover = (end = (from = head) + size)
915 >            - (to = (capacity - end >= 0) ? end : capacity);
916 >        for (;; from = 0, to = leftover, leftover = 0) {
917 >            for (int i = from; i < to; i++)
918 >                elements[i] = operator.apply(elementAt(i));
919 >            if (leftover == 0) break;
920 >        }
921          // checkInvariants();
922      }
923  
924      /**
925       * @throws NullPointerException {@inheritDoc}
926       */
862    @Override
927      public boolean removeIf(Predicate<? super E> filter) {
928          Objects.requireNonNull(filter);
929          return bulkRemove(filter);
# Line 868 | Line 932 | public class ArrayDeque<E> extends Abstr
932      /**
933       * @throws NullPointerException {@inheritDoc}
934       */
871    @Override
935      public boolean removeAll(Collection<?> c) {
936          Objects.requireNonNull(c);
937          return bulkRemove(e -> c.contains(e));
# Line 877 | Line 940 | public class ArrayDeque<E> extends Abstr
940      /**
941       * @throws NullPointerException {@inheritDoc}
942       */
880    @Override
943      public boolean retainAll(Collection<?> c) {
944          Objects.requireNonNull(c);
945          return bulkRemove(e -> !c.contains(e));
# Line 890 | Line 952 | public class ArrayDeque<E> extends Abstr
952          final int capacity = elements.length;
953          int i = head, j = i, remaining = size, deleted = 0;
954          try {
955 <            for (; remaining > 0; remaining--, i = inc(i, capacity)) {
955 >            for (; remaining > 0; remaining--) {
956                  @SuppressWarnings("unchecked") E e = (E) elements[i];
957                  if (filter.test(e))
958                      deleted++;
959                  else {
960                      if (j != i)
961                          elements[j] = e;
962 <                    j = inc(j, capacity);
962 >                    if (++j >= capacity) j = 0;
963                  }
964 +                if (++i >= capacity) i = 0;
965              }
966              return deleted > 0;
967          } catch (Throwable ex) {
968 <            for (; remaining > 0;
969 <                 remaining--, i = inc(i, capacity), j = inc(j, capacity))
970 <                elements[j] = elements[i];
968 >            if (deleted > 0)
969 >                for (; remaining > 0; remaining--) {
970 >                    elements[j] = elements[i];
971 >                    if (++i >= capacity) i = 0;
972 >                    if (++j >= capacity) j = 0;
973 >                }
974              throw ex;
975          } finally {
976              size -= deleted;
977 <            for (; --deleted >= 0; j = inc(j, capacity))
912 <                elements[j] = null;
977 >            clearSlice(elements, j, deleted);
978              // checkInvariants();
979          }
980      }
# Line 926 | Line 991 | public class ArrayDeque<E> extends Abstr
991          if (o != null) {
992              final Object[] elements = this.elements;
993              final int capacity = elements.length;
994 <            for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
995 <                if (o.equals(elements[i]))
996 <                    return true;
994 >            int from, end, to, leftover;
995 >            leftover = (end = (from = head) + size)
996 >                - (to = (capacity - end >= 0) ? end : capacity);
997 >            for (;; from = 0, to = leftover, leftover = 0) {
998 >                for (int i = from; i < to; i++)
999 >                    if (o.equals(elements[i]))
1000 >                        return true;
1001 >                if (leftover == 0) break;
1002 >            }
1003          }
1004          return false;
1005      }
# Line 955 | Line 1026 | public class ArrayDeque<E> extends Abstr
1026       * The deque will be empty after this call returns.
1027       */
1028      public void clear() {
1029 <        final Object[] elements = this.elements;
959 <        final int capacity = elements.length;
960 <        final int h = this.head;
961 <        final int s = size;
962 <        if (capacity - h >= s)
963 <            Arrays.fill(elements, h, h + s, null);
964 <        else {
965 <            Arrays.fill(elements, h, capacity, null);
966 <            Arrays.fill(elements, 0, s - capacity + h, null);
967 <        }
1029 >        clearSlice(elements, head, size);
1030          size = head = 0;
1031          // checkInvariants();
1032      }
1033  
1034      /**
1035 +     * Nulls out size elements, starting at head.
1036 +     */
1037 +    private static void clearSlice(Object[] elements, int head, int size) {
1038 +        final int capacity = elements.length, end = head + size;
1039 +        final int leg = (capacity - end >= 0) ? end : capacity;
1040 +        Arrays.fill(elements, head, leg, null);
1041 +        if (leg != end)
1042 +            Arrays.fill(elements, 0, end - capacity, null);
1043 +    }
1044 +
1045 +    /**
1046       * Returns an array containing all of the elements in this deque
1047       * in proper sequence (from first to last element).
1048       *
# Line 983 | Line 1056 | public class ArrayDeque<E> extends Abstr
1056       * @return an array containing all of the elements in this deque
1057       */
1058      public Object[] toArray() {
1059 <        final int head = this.head;
1060 <        final int firstLeg;
1061 <        Object[] a = Arrays.copyOfRange(elements, head, head + size);
1062 <        if ((firstLeg = elements.length - head) < size)
1063 <            System.arraycopy(elements, 0, a, firstLeg, size - firstLeg);
1059 >        return toArray(Object[].class);
1060 >    }
1061 >
1062 >    private <T> T[] toArray(Class<T[]> klazz) {
1063 >        final Object[] elements = this.elements;
1064 >        final int capacity = elements.length;
1065 >        final int head = this.head, end = head + size;
1066 >        final T[] a;
1067 >        if (end >= 0) {
1068 >            a = Arrays.copyOfRange(elements, head, end, klazz);
1069 >        } else {
1070 >            // integer overflow!
1071 >            a = Arrays.copyOfRange(elements, 0, size, klazz);
1072 >            System.arraycopy(elements, head, a, 0, capacity - head);
1073 >        }
1074 >        if (end - capacity > 0)
1075 >            System.arraycopy(elements, 0, a, capacity - head, end - capacity);
1076          return a;
1077      }
1078  
# Line 1029 | Line 1114 | public class ArrayDeque<E> extends Abstr
1114       */
1115      @SuppressWarnings("unchecked")
1116      public <T> T[] toArray(T[] a) {
1117 +        final int size = this.size;
1118 +        if (size > a.length)
1119 +            return toArray((Class<T[]>) a.getClass());
1120          final Object[] elements = this.elements;
1121 <        final int head = this.head;
1122 <        final int firstLeg;
1123 <        boolean wrap = (firstLeg = elements.length - head) < size;
1124 <        if (size > a.length) {
1125 <            a = (T[]) Arrays.copyOfRange(elements, head, head + size,
1126 <                                         a.getClass());
1127 <        } else {
1128 <            System.arraycopy(elements, head, a, 0, wrap ? firstLeg : size);
1041 <            if (size < a.length)
1042 <                a[size] = null;
1043 <        }
1044 <        if (wrap)
1045 <            System.arraycopy(elements, 0, a, firstLeg, size - firstLeg);
1121 >        final int capacity = elements.length;
1122 >        final int head = this.head, end = head + size;
1123 >        final int front = (capacity - end >= 0) ? size : capacity - head;
1124 >        System.arraycopy(elements, head, a, 0, front);
1125 >        if (front != size)
1126 >            System.arraycopy(elements, 0, a, capacity - head, end - capacity);
1127 >        if (size < a.length)
1128 >            a[size] = null;
1129          return a;
1130      }
1131  
# Line 1085 | Line 1168 | public class ArrayDeque<E> extends Abstr
1168          // Write out elements in order.
1169          final Object[] elements = this.elements;
1170          final int capacity = elements.length;
1171 <        for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
1172 <            s.writeObject(elements[i]);
1171 >        int from, end, to, leftover;
1172 >        leftover = (end = (from = head) + size)
1173 >            - (to = (capacity - end >= 0) ? end : capacity);
1174 >        for (;; from = 0, to = leftover, leftover = 0) {
1175 >            for (int i = from; i < to; i++)
1176 >                s.writeObject(elements[i]);
1177 >            if (leftover == 0) break;
1178 >        }
1179      }
1180  
1181      /**
# Line 1109 | Line 1198 | public class ArrayDeque<E> extends Abstr
1198      }
1199  
1200      /** debugging */
1201 <    private void checkInvariants() {
1201 >    void checkInvariants() {
1202          try {
1203              int capacity = elements.length;
1204 <            assert size >= 0 && size <= capacity;
1205 <            assert head >= 0 && ((capacity == 0 && head == 0 && size == 0)
1206 <                                 || head < capacity);
1207 <            assert size == 0
1208 <                || (elements[head] != null && elements[tail()] != null);
1209 <            assert size == capacity
1210 <                || (elements[dec(head, capacity)] == null
1122 <                    && elements[inc(tail(), capacity)] == null);
1204 >            // assert size >= 0 && size <= capacity;
1205 >            // assert head >= 0;
1206 >            // assert capacity == 0 || head < capacity;
1207 >            // assert size == 0 || elements[head] != null;
1208 >            // assert size == 0 || elements[tail()] != null;
1209 >            // assert size == capacity || elements[dec(head, capacity)] == null;
1210 >            // assert size == capacity || elements[inc(tail(), capacity)] == null;
1211          } catch (Throwable t) {
1212              System.err.printf("head=%d size=%d capacity=%d%n",
1213                                head, size, elements.length);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines