jdk/src/share/classes/java/util/stream/SpinedBuffer.java
changeset 18171 2725a30c1a02
parent 18155 889970e5b728
child 19188 bbf287c5cd92
equal deleted inserted replaced
18170:e845f3a78db5 18171:2725a30c1a02
   267 
   267 
   268     /**
   268     /**
   269      * Return a {@link Spliterator} describing the contents of the buffer.
   269      * Return a {@link Spliterator} describing the contents of the buffer.
   270      */
   270      */
   271     public Spliterator<E> spliterator() {
   271     public Spliterator<E> spliterator() {
   272         return new Spliterator<E>() {
   272         class Splitr implements Spliterator<E> {
   273             // The current spine index
   273             // The current spine index
   274             int splSpineIndex;
   274             int splSpineIndex;
   275 
   275 
       
   276             // Last spine index
       
   277             final int lastSpineIndex;
       
   278 
   276             // The current element index into the current spine
   279             // The current element index into the current spine
   277             int splElementIndex;
   280             int splElementIndex;
   278 
   281 
   279             // When splSpineIndex >= spineIndex and splElementIndex >= elementIndex then
   282             // Last spine's last element index + 1
       
   283             final int lastSpineElementFence;
       
   284 
       
   285             // When splSpineIndex >= lastSpineIndex and
       
   286             // splElementIndex >= lastSpineElementFence then
   280             // this spliterator is fully traversed
   287             // this spliterator is fully traversed
   281             // tryAdvance can set splSpineIndex > spineIndex if the last spine is full
   288             // tryAdvance can set splSpineIndex > spineIndex if the last spine is full
   282 
   289 
   283             // The current spine array
   290             // The current spine array
   284             E[] splChunk = (spine == null) ? curChunk : spine[0];
   291             E[] splChunk;
       
   292 
       
   293             Splitr(int firstSpineIndex, int lastSpineIndex,
       
   294                    int firstSpineElementIndex, int lastSpineElementFence) {
       
   295                 this.splSpineIndex = firstSpineIndex;
       
   296                 this.lastSpineIndex = lastSpineIndex;
       
   297                 this.splElementIndex = firstSpineElementIndex;
       
   298                 this.lastSpineElementFence = lastSpineElementFence;
       
   299                 assert spine != null || firstSpineIndex == 0 && lastSpineIndex == 0;
       
   300                 splChunk = (spine == null) ? curChunk : spine[firstSpineIndex];
       
   301             }
   285 
   302 
   286             @Override
   303             @Override
   287             public long estimateSize() {
   304             public long estimateSize() {
   288                 return (spine == null)
   305                 return (splSpineIndex == lastSpineIndex)
   289                        ? (elementIndex - splElementIndex)
   306                        ? (long) lastSpineElementFence - splElementIndex
   290                        : count() - (priorElementCount[splSpineIndex] + splElementIndex);
   307                        : // # of elements prior to end -
       
   308                        priorElementCount[lastSpineIndex] + lastSpineElementFence -
       
   309                        // # of elements prior to current
       
   310                        priorElementCount[splSpineIndex] - splElementIndex;
   291             }
   311             }
   292 
   312 
   293             @Override
   313             @Override
   294             public int characteristics() {
   314             public int characteristics() {
   295                 return SPLITERATOR_CHARACTERISTICS;
   315                 return SPLITERATOR_CHARACTERISTICS;
   296             }
   316             }
   297 
   317 
   298             @Override
   318             @Override
   299             public boolean tryAdvance(Consumer<? super E> consumer) {
   319             public boolean tryAdvance(Consumer<? super E> consumer) {
   300                 if (splSpineIndex < spineIndex
   320                 if (splSpineIndex < lastSpineIndex
   301                     || (splSpineIndex == spineIndex && splElementIndex < elementIndex)) {
   321                     || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) {
   302                     consumer.accept(splChunk[splElementIndex++]);
   322                     consumer.accept(splChunk[splElementIndex++]);
   303 
   323 
   304                     if (splElementIndex == splChunk.length) {
   324                     if (splElementIndex == splChunk.length) {
   305                         splElementIndex = 0;
   325                         splElementIndex = 0;
   306                         ++splSpineIndex;
   326                         ++splSpineIndex;
   307                         if (spine != null && splSpineIndex < spine.length)
   327                         if (spine != null && splSpineIndex <= lastSpineIndex)
   308                             splChunk = spine[splSpineIndex];
   328                             splChunk = spine[splSpineIndex];
   309                     }
   329                     }
   310                     return true;
   330                     return true;
   311                 }
   331                 }
   312                 return false;
   332                 return false;
   313             }
   333             }
   314 
   334 
   315             @Override
   335             @Override
   316             public void forEachRemaining(Consumer<? super E> consumer) {
   336             public void forEachRemaining(Consumer<? super E> consumer) {
   317                 if (splSpineIndex < spineIndex
   337                 if (splSpineIndex < lastSpineIndex
   318                     || (splSpineIndex == spineIndex && splElementIndex < elementIndex)) {
   338                     || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) {
   319                     int i = splElementIndex;
   339                     int i = splElementIndex;
   320                     // completed chunks, if any
   340                     // completed chunks, if any
   321                     for (int sp = splSpineIndex; sp < spineIndex; sp++) {
   341                     for (int sp = splSpineIndex; sp < lastSpineIndex; sp++) {
   322                         E[] chunk = spine[sp];
   342                         E[] chunk = spine[sp];
   323                         for (; i < chunk.length; i++) {
   343                         for (; i < chunk.length; i++) {
   324                             consumer.accept(chunk[i]);
   344                             consumer.accept(chunk[i]);
   325                         }
   345                         }
   326                         i = 0;
   346                         i = 0;
   327                     }
   347                     }
   328 
   348                     // last (or current uncompleted) chunk
   329                     // current chunk
   349                     E[] chunk = (splSpineIndex == lastSpineIndex) ? splChunk : spine[lastSpineIndex];
   330                     E[] chunk = curChunk;
   350                     int hElementIndex = lastSpineElementFence;
   331                     int hElementIndex = elementIndex;
       
   332                     for (; i < hElementIndex; i++) {
   351                     for (; i < hElementIndex; i++) {
   333                         consumer.accept(chunk[i]);
   352                         consumer.accept(chunk[i]);
   334                     }
   353                     }
   335 
   354                     // mark consumed
   336                     splSpineIndex = spineIndex;
   355                     splSpineIndex = lastSpineIndex;
   337                     splElementIndex = elementIndex;
   356                     splElementIndex = lastSpineElementFence;
   338                 }
   357                 }
   339             }
   358             }
   340 
   359 
   341             @Override
   360             @Override
   342             public Spliterator<E> trySplit() {
   361             public Spliterator<E> trySplit() {
   343                 if (splSpineIndex < spineIndex) {
   362                 if (splSpineIndex < lastSpineIndex) {
   344                     Spliterator<E> ret = Arrays.spliterator(spine[splSpineIndex],
   363                     // split just before last chunk (if it is full this means 50:50 split)
   345                                                             splElementIndex, spine[splSpineIndex].length);
   364                     Spliterator<E> ret = new Splitr(splSpineIndex, lastSpineIndex - 1,
   346                     splChunk = spine[++splSpineIndex];
   365                                                     splElementIndex, spine[lastSpineIndex-1].length);
       
   366                     // position to start of last chunk
       
   367                     splSpineIndex = lastSpineIndex;
   347                     splElementIndex = 0;
   368                     splElementIndex = 0;
       
   369                     splChunk = spine[splSpineIndex];
   348                     return ret;
   370                     return ret;
   349                 }
   371                 }
   350                 else if (splSpineIndex == spineIndex) {
   372                 else if (splSpineIndex == lastSpineIndex) {
   351                     int t = (elementIndex - splElementIndex) / 2;
   373                     int t = (lastSpineElementFence - splElementIndex) / 2;
   352                     if (t == 0)
   374                     if (t == 0)
   353                         return null;
   375                         return null;
   354                     else {
   376                     else {
   355                         Spliterator<E> ret = Arrays.spliterator(curChunk, splElementIndex, splElementIndex + t);
   377                         Spliterator<E> ret = Arrays.spliterator(splChunk, splElementIndex, splElementIndex + t);
   356                         splElementIndex += t;
   378                         splElementIndex += t;
   357                         return ret;
   379                         return ret;
   358                     }
   380                     }
   359                 }
   381                 }
   360                 else {
   382                 else {
   361                     return null;
   383                     return null;
   362                 }
   384                 }
   363             }
   385             }
   364         };
   386         }
       
   387         return new Splitr(0, spineIndex, 0, elementIndex);
   365     }
   388     }
   366 
   389 
   367     /**
   390     /**
   368      * An ordered collection of primitive values.  Elements can be added, but
   391      * An ordered collection of primitive values.  Elements can be added, but
   369      * not removed. Goes through a building phase, during which elements can be
   392      * not removed. Goes through a building phase, during which elements can be
   434 
   457 
   435         /** Create a new array-of-array of the proper type and size */
   458         /** Create a new array-of-array of the proper type and size */
   436         protected abstract T_ARR[] newArrayArray(int size);
   459         protected abstract T_ARR[] newArrayArray(int size);
   437 
   460 
   438         /** Create a new array of the proper type and size */
   461         /** Create a new array of the proper type and size */
   439         protected abstract T_ARR newArray(int size);
   462         public abstract T_ARR newArray(int size);
   440 
   463 
   441         /** Get the length of an array */
   464         /** Get the length of an array */
   442         protected abstract int arrayLength(T_ARR array);
   465         protected abstract int arrayLength(T_ARR array);
   443 
   466 
   444         /** Iterate an array with the provided consumer */
   467         /** Iterate an array with the provided consumer */
   553 
   576 
   554             // current chunk
   577             // current chunk
   555             arrayForEach(curChunk, 0, elementIndex, consumer);
   578             arrayForEach(curChunk, 0, elementIndex, consumer);
   556         }
   579         }
   557 
   580 
   558         abstract class BaseSpliterator<T_SPLITER extends Spliterator<E>>
   581         abstract class BaseSpliterator<T_SPLITR extends Spliterator.OfPrimitive<E, T_CONS, T_SPLITR>>
   559                 implements Spliterator<E> {
   582                 implements Spliterator.OfPrimitive<E, T_CONS, T_SPLITR> {
   560             // The current spine index
   583             // The current spine index
   561             int splSpineIndex;
   584             int splSpineIndex;
   562 
   585 
       
   586             // Last spine index
       
   587             final int lastSpineIndex;
       
   588 
   563             // The current element index into the current spine
   589             // The current element index into the current spine
   564             int splElementIndex;
   590             int splElementIndex;
   565 
   591 
   566             // When splSpineIndex >= spineIndex and splElementIndex >= elementIndex then
   592             // Last spine's last element index + 1
       
   593             final int lastSpineElementFence;
       
   594 
       
   595             // When splSpineIndex >= lastSpineIndex and
       
   596             // splElementIndex >= lastSpineElementFence then
   567             // this spliterator is fully traversed
   597             // this spliterator is fully traversed
   568             // tryAdvance can set splSpineIndex > spineIndex if the last spine is full
   598             // tryAdvance can set splSpineIndex > spineIndex if the last spine is full
   569 
   599 
   570             // The current spine array
   600             // The current spine array
   571             T_ARR splChunk = (spine == null) ? curChunk : spine[0];
   601             T_ARR splChunk;
       
   602 
       
   603             BaseSpliterator(int firstSpineIndex, int lastSpineIndex,
       
   604                             int firstSpineElementIndex, int lastSpineElementFence) {
       
   605                 this.splSpineIndex = firstSpineIndex;
       
   606                 this.lastSpineIndex = lastSpineIndex;
       
   607                 this.splElementIndex = firstSpineElementIndex;
       
   608                 this.lastSpineElementFence = lastSpineElementFence;
       
   609                 assert spine != null || firstSpineIndex == 0 && lastSpineIndex == 0;
       
   610                 splChunk = (spine == null) ? curChunk : spine[firstSpineIndex];
       
   611             }
       
   612 
       
   613             abstract T_SPLITR newSpliterator(int firstSpineIndex, int lastSpineIndex,
       
   614                                              int firstSpineElementIndex, int lastSpineElementFence);
   572 
   615 
   573             abstract void arrayForOne(T_ARR array, int index, T_CONS consumer);
   616             abstract void arrayForOne(T_ARR array, int index, T_CONS consumer);
   574 
   617 
   575             abstract T_SPLITER arraySpliterator(T_ARR array, int offset, int len);
   618             abstract T_SPLITR arraySpliterator(T_ARR array, int offset, int len);
   576 
   619 
   577             @Override
   620             @Override
   578             public long estimateSize() {
   621             public long estimateSize() {
   579                 return (spine == null)
   622                 return (splSpineIndex == lastSpineIndex)
   580                        ? (elementIndex - splElementIndex)
   623                        ? (long) lastSpineElementFence - splElementIndex
   581                        : count() - (priorElementCount[splSpineIndex] + splElementIndex);
   624                        : // # of elements prior to end -
       
   625                        priorElementCount[lastSpineIndex] + lastSpineElementFence -
       
   626                        // # of elements prior to current
       
   627                        priorElementCount[splSpineIndex] - splElementIndex;
   582             }
   628             }
   583 
   629 
   584             @Override
   630             @Override
   585             public int characteristics() {
   631             public int characteristics() {
   586                 return SPLITERATOR_CHARACTERISTICS;
   632                 return SPLITERATOR_CHARACTERISTICS;
   587             }
   633             }
   588 
   634 
       
   635             @Override
   589             public boolean tryAdvance(T_CONS consumer) {
   636             public boolean tryAdvance(T_CONS consumer) {
   590                 if (splSpineIndex < spineIndex
   637                 if (splSpineIndex < lastSpineIndex
   591                     || (splSpineIndex == spineIndex && splElementIndex < elementIndex)) {
   638                     || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) {
   592                     arrayForOne(splChunk, splElementIndex++, consumer);
   639                     arrayForOne(splChunk, splElementIndex++, consumer);
   593 
   640 
   594                     if (splElementIndex == arrayLength(splChunk)) {
   641                     if (splElementIndex == arrayLength(splChunk)) {
   595                         splElementIndex = 0;
   642                         splElementIndex = 0;
   596                         ++splSpineIndex;
   643                         ++splSpineIndex;
   597                         if (spine != null && splSpineIndex < spine.length)
   644                         if (spine != null && splSpineIndex <= lastSpineIndex)
   598                             splChunk = spine[splSpineIndex];
   645                             splChunk = spine[splSpineIndex];
   599                     }
   646                     }
   600                     return true;
   647                     return true;
   601                 }
   648                 }
   602                 return false;
   649                 return false;
   603             }
   650             }
   604 
   651 
       
   652             @Override
   605             public void forEachRemaining(T_CONS consumer) {
   653             public void forEachRemaining(T_CONS consumer) {
   606                 if (splSpineIndex < spineIndex
   654                 if (splSpineIndex < lastSpineIndex
   607                     || (splSpineIndex == spineIndex && splElementIndex < elementIndex)) {
   655                     || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) {
   608                     int i = splElementIndex;
   656                     int i = splElementIndex;
   609                     // completed chunks, if any
   657                     // completed chunks, if any
   610                     for (int sp = splSpineIndex; sp < spineIndex; sp++) {
   658                     for (int sp = splSpineIndex; sp < lastSpineIndex; sp++) {
   611                         T_ARR chunk = spine[sp];
   659                         T_ARR chunk = spine[sp];
   612                         arrayForEach(chunk, i, arrayLength(chunk), consumer);
   660                         arrayForEach(chunk, i, arrayLength(chunk), consumer);
   613                         i = 0;
   661                         i = 0;
   614                     }
   662                     }
   615 
   663                     // last (or current uncompleted) chunk
   616                     arrayForEach(curChunk, i, elementIndex, consumer);
   664                     T_ARR chunk = (splSpineIndex == lastSpineIndex) ? splChunk : spine[lastSpineIndex];
   617 
   665                     arrayForEach(chunk, i, lastSpineElementFence, consumer);
   618                     splSpineIndex = spineIndex;
   666                     // mark consumed
   619                     splElementIndex = elementIndex;
   667                     splSpineIndex = lastSpineIndex;
       
   668                     splElementIndex = lastSpineElementFence;
   620                 }
   669                 }
   621             }
   670             }
   622 
   671 
   623             @Override
   672             @Override
   624             public T_SPLITER trySplit() {
   673             public T_SPLITR trySplit() {
   625                 if (splSpineIndex < spineIndex) {
   674                 if (splSpineIndex < lastSpineIndex) {
   626                     T_SPLITER ret = arraySpliterator(spine[splSpineIndex], splElementIndex,
   675                     // split just before last chunk (if it is full this means 50:50 split)
   627                                                      arrayLength(spine[splSpineIndex]) - splElementIndex);
   676                     T_SPLITR ret = newSpliterator(splSpineIndex, lastSpineIndex - 1,
   628                     splChunk = spine[++splSpineIndex];
   677                                                   splElementIndex, arrayLength(spine[lastSpineIndex - 1]));
       
   678                     // position us to start of last chunk
       
   679                     splSpineIndex = lastSpineIndex;
   629                     splElementIndex = 0;
   680                     splElementIndex = 0;
       
   681                     splChunk = spine[splSpineIndex];
   630                     return ret;
   682                     return ret;
   631                 }
   683                 }
   632                 else if (splSpineIndex == spineIndex) {
   684                 else if (splSpineIndex == lastSpineIndex) {
   633                     int t = (elementIndex - splElementIndex) / 2;
   685                     int t = (lastSpineElementFence - splElementIndex) / 2;
   634                     if (t == 0)
   686                     if (t == 0)
   635                         return null;
   687                         return null;
   636                     else {
   688                     else {
   637                         T_SPLITER ret = arraySpliterator(curChunk, splElementIndex, t);
   689                         T_SPLITR ret = arraySpliterator(splChunk, splElementIndex, t);
   638                         splElementIndex += t;
   690                         splElementIndex += t;
   639                         return ret;
   691                         return ret;
   640                     }
   692                     }
   641                 }
   693                 }
   642                 else {
   694                 else {
   673         protected int[][] newArrayArray(int size) {
   725         protected int[][] newArrayArray(int size) {
   674             return new int[size][];
   726             return new int[size][];
   675         }
   727         }
   676 
   728 
   677         @Override
   729         @Override
   678         protected int[] newArray(int size) {
   730         public int[] newArray(int size) {
   679             return new int[size];
   731             return new int[size];
   680         }
   732         }
   681 
   733 
   682         @Override
   734         @Override
   683         protected int arrayLength(int[] array) {
   735         protected int arrayLength(int[] array) {
   704                 return curChunk[(int) index];
   756                 return curChunk[(int) index];
   705             else
   757             else
   706                 return spine[ch][(int) (index-priorElementCount[ch])];
   758                 return spine[ch][(int) (index-priorElementCount[ch])];
   707         }
   759         }
   708 
   760 
   709         public int[] asIntArray() {
       
   710             return asPrimitiveArray();
       
   711         }
       
   712 
       
   713         @Override
   761         @Override
   714         public PrimitiveIterator.OfInt iterator() {
   762         public PrimitiveIterator.OfInt iterator() {
   715             return Spliterators.iterator(spliterator());
   763             return Spliterators.iterator(spliterator());
   716         }
   764         }
   717 
   765 
   718         public Spliterator.OfInt spliterator() {
   766         public Spliterator.OfInt spliterator() {
   719             class Splitr extends BaseSpliterator<Spliterator.OfInt>
   767             class Splitr extends BaseSpliterator<Spliterator.OfInt>
   720                     implements Spliterator.OfInt {
   768                     implements Spliterator.OfInt {
       
   769                 Splitr(int firstSpineIndex, int lastSpineIndex,
       
   770                        int firstSpineElementIndex, int lastSpineElementFence) {
       
   771                     super(firstSpineIndex, lastSpineIndex,
       
   772                           firstSpineElementIndex, lastSpineElementFence);
       
   773                 }
       
   774 
       
   775                 @Override
       
   776                 Splitr newSpliterator(int firstSpineIndex, int lastSpineIndex,
       
   777                                       int firstSpineElementIndex, int lastSpineElementFence) {
       
   778                     return new Splitr(firstSpineIndex, lastSpineIndex,
       
   779                                       firstSpineElementIndex, lastSpineElementFence);
       
   780                 }
   721 
   781 
   722                 @Override
   782                 @Override
   723                 void arrayForOne(int[] array, int index, IntConsumer consumer) {
   783                 void arrayForOne(int[] array, int index, IntConsumer consumer) {
   724                     consumer.accept(array[index]);
   784                     consumer.accept(array[index]);
   725                 }
   785                 }
   726 
   786 
   727                 @Override
   787                 @Override
   728                 Spliterator.OfInt arraySpliterator(int[] array, int offset, int len) {
   788                 Spliterator.OfInt arraySpliterator(int[] array, int offset, int len) {
   729                     return Arrays.spliterator(array, offset, offset+len);
   789                     return Arrays.spliterator(array, offset, offset+len);
   730                 }
   790                 }
   731             };
   791             }
   732             return new Splitr();
   792             return new Splitr(0, spineIndex, 0, elementIndex);
   733         }
   793         }
   734 
   794 
   735         @Override
   795         @Override
   736         public String toString() {
   796         public String toString() {
   737             int[] array = asIntArray();
   797             int[] array = asPrimitiveArray();
   738             if (array.length < 200) {
   798             if (array.length < 200) {
   739                 return String.format("%s[length=%d, chunks=%d]%s",
   799                 return String.format("%s[length=%d, chunks=%d]%s",
   740                                      getClass().getSimpleName(), array.length,
   800                                      getClass().getSimpleName(), array.length,
   741                                      spineIndex, Arrays.toString(array));
   801                                      spineIndex, Arrays.toString(array));
   742             }
   802             }
   776         protected long[][] newArrayArray(int size) {
   836         protected long[][] newArrayArray(int size) {
   777             return new long[size][];
   837             return new long[size][];
   778         }
   838         }
   779 
   839 
   780         @Override
   840         @Override
   781         protected long[] newArray(int size) {
   841         public long[] newArray(int size) {
   782             return new long[size];
   842             return new long[size];
   783         }
   843         }
   784 
   844 
   785         @Override
   845         @Override
   786         protected int arrayLength(long[] array) {
   846         protected int arrayLength(long[] array) {
   807                 return curChunk[(int) index];
   867                 return curChunk[(int) index];
   808             else
   868             else
   809                 return spine[ch][(int) (index-priorElementCount[ch])];
   869                 return spine[ch][(int) (index-priorElementCount[ch])];
   810         }
   870         }
   811 
   871 
   812         public long[] asLongArray() {
       
   813             return asPrimitiveArray();
       
   814         }
       
   815 
       
   816         @Override
   872         @Override
   817         public PrimitiveIterator.OfLong iterator() {
   873         public PrimitiveIterator.OfLong iterator() {
   818             return Spliterators.iterator(spliterator());
   874             return Spliterators.iterator(spliterator());
   819         }
   875         }
   820 
   876 
   821 
   877 
   822         public Spliterator.OfLong spliterator() {
   878         public Spliterator.OfLong spliterator() {
   823             class Splitr extends BaseSpliterator<Spliterator.OfLong>
   879             class Splitr extends BaseSpliterator<Spliterator.OfLong>
   824                     implements Spliterator.OfLong {
   880                     implements Spliterator.OfLong {
       
   881                 Splitr(int firstSpineIndex, int lastSpineIndex,
       
   882                        int firstSpineElementIndex, int lastSpineElementFence) {
       
   883                     super(firstSpineIndex, lastSpineIndex,
       
   884                           firstSpineElementIndex, lastSpineElementFence);
       
   885                 }
       
   886 
       
   887                 @Override
       
   888                 Splitr newSpliterator(int firstSpineIndex, int lastSpineIndex,
       
   889                                       int firstSpineElementIndex, int lastSpineElementFence) {
       
   890                     return new Splitr(firstSpineIndex, lastSpineIndex,
       
   891                                       firstSpineElementIndex, lastSpineElementFence);
       
   892                 }
       
   893 
   825                 @Override
   894                 @Override
   826                 void arrayForOne(long[] array, int index, LongConsumer consumer) {
   895                 void arrayForOne(long[] array, int index, LongConsumer consumer) {
   827                     consumer.accept(array[index]);
   896                     consumer.accept(array[index]);
   828                 }
   897                 }
   829 
   898 
   830                 @Override
   899                 @Override
   831                 Spliterator.OfLong arraySpliterator(long[] array, int offset, int len) {
   900                 Spliterator.OfLong arraySpliterator(long[] array, int offset, int len) {
   832                     return Arrays.spliterator(array, offset, offset+len);
   901                     return Arrays.spliterator(array, offset, offset+len);
   833                 }
   902                 }
   834             };
   903             }
   835             return new Splitr();
   904             return new Splitr(0, spineIndex, 0, elementIndex);
   836         }
   905         }
   837 
   906 
   838         @Override
   907         @Override
   839         public String toString() {
   908         public String toString() {
   840             long[] array = asLongArray();
   909             long[] array = asPrimitiveArray();
   841             if (array.length < 200) {
   910             if (array.length < 200) {
   842                 return String.format("%s[length=%d, chunks=%d]%s",
   911                 return String.format("%s[length=%d, chunks=%d]%s",
   843                                      getClass().getSimpleName(), array.length,
   912                                      getClass().getSimpleName(), array.length,
   844                                      spineIndex, Arrays.toString(array));
   913                                      spineIndex, Arrays.toString(array));
   845             }
   914             }
   880         protected double[][] newArrayArray(int size) {
   949         protected double[][] newArrayArray(int size) {
   881             return new double[size][];
   950             return new double[size][];
   882         }
   951         }
   883 
   952 
   884         @Override
   953         @Override
   885         protected double[] newArray(int size) {
   954         public double[] newArray(int size) {
   886             return new double[size];
   955             return new double[size];
   887         }
   956         }
   888 
   957 
   889         @Override
   958         @Override
   890         protected int arrayLength(double[] array) {
   959         protected int arrayLength(double[] array) {
   911                 return curChunk[(int) index];
   980                 return curChunk[(int) index];
   912             else
   981             else
   913                 return spine[ch][(int) (index-priorElementCount[ch])];
   982                 return spine[ch][(int) (index-priorElementCount[ch])];
   914         }
   983         }
   915 
   984 
   916         public double[] asDoubleArray() {
       
   917             return asPrimitiveArray();
       
   918         }
       
   919 
       
   920         @Override
   985         @Override
   921         public PrimitiveIterator.OfDouble iterator() {
   986         public PrimitiveIterator.OfDouble iterator() {
   922             return Spliterators.iterator(spliterator());
   987             return Spliterators.iterator(spliterator());
   923         }
   988         }
   924 
   989 
   925         public Spliterator.OfDouble spliterator() {
   990         public Spliterator.OfDouble spliterator() {
   926             class Splitr extends BaseSpliterator<Spliterator.OfDouble>
   991             class Splitr extends BaseSpliterator<Spliterator.OfDouble>
   927                     implements Spliterator.OfDouble {
   992                     implements Spliterator.OfDouble {
       
   993                 Splitr(int firstSpineIndex, int lastSpineIndex,
       
   994                        int firstSpineElementIndex, int lastSpineElementFence) {
       
   995                     super(firstSpineIndex, lastSpineIndex,
       
   996                           firstSpineElementIndex, lastSpineElementFence);
       
   997                 }
       
   998 
       
   999                 @Override
       
  1000                 Splitr newSpliterator(int firstSpineIndex, int lastSpineIndex,
       
  1001                                       int firstSpineElementIndex, int lastSpineElementFence) {
       
  1002                     return new Splitr(firstSpineIndex, lastSpineIndex,
       
  1003                                       firstSpineElementIndex, lastSpineElementFence);
       
  1004                 }
       
  1005 
   928                 @Override
  1006                 @Override
   929                 void arrayForOne(double[] array, int index, DoubleConsumer consumer) {
  1007                 void arrayForOne(double[] array, int index, DoubleConsumer consumer) {
   930                     consumer.accept(array[index]);
  1008                     consumer.accept(array[index]);
   931                 }
  1009                 }
   932 
  1010 
   933                 @Override
  1011                 @Override
   934                 Spliterator.OfDouble arraySpliterator(double[] array, int offset, int len) {
  1012                 Spliterator.OfDouble arraySpliterator(double[] array, int offset, int len) {
   935                     return Arrays.spliterator(array, offset, offset+len);
  1013                     return Arrays.spliterator(array, offset, offset+len);
   936                 }
  1014                 }
   937             }
  1015             }
   938             return new Splitr();
  1016             return new Splitr(0, spineIndex, 0, elementIndex);
   939         }
  1017         }
   940 
  1018 
   941         @Override
  1019         @Override
   942         public String toString() {
  1020         public String toString() {
   943             double[] array = asDoubleArray();
  1021             double[] array = asPrimitiveArray();
   944             if (array.length < 200) {
  1022             if (array.length < 200) {
   945                 return String.format("%s[length=%d, chunks=%d]%s",
  1023                 return String.format("%s[length=%d, chunks=%d]%s",
   946                                      getClass().getSimpleName(), array.length,
  1024                                      getClass().getSimpleName(), array.length,
   947                                      spineIndex, Arrays.toString(array));
  1025                                      spineIndex, Arrays.toString(array));
   948             }
  1026             }