forked from scala/scala-java8-compat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStepsLikeIterator.scala
118 lines (111 loc) · 4.51 KB
/
StepsLikeIterator.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc. dba Akka
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/
package scala.compat.java8.converterImpl
import scala.compat.java8.collectionImpl._
import Stepper._
/** Common functionality for Steppers that step through an Iterator, caching the results as needed when a split is requested. */
private[java8] abstract class AbstractStepsLikeIterator[A, SP >: Null <: Stepper[A], Semi <: SP](final protected var underlying: Iterator[A]) {
final protected var nextChunkSize = 16
final protected var proxied: SP = null
def semiclone(): Semi // Must initialize with null iterator!
def characteristics(): Int = if (proxied ne null) Ordered | Sized | SubSized else Ordered
def estimateSize(): Long = if (proxied ne null) proxied.knownSize else Long.MaxValue
def hasNext(): Boolean = if (proxied ne null) proxied.hasStep else underlying.hasNext
}
/** Abstracts the operation of stepping over an iterator (that needs to be cached when splitting) */
private[java8] abstract class StepsLikeIterator[A, SLI >: Null <: StepsLikeIterator[A, SLI] with AnyStepper[A]](_underlying: Iterator[A])
extends AbstractStepsLikeIterator[A, AnyStepper[A], SLI](_underlying)
with AnyStepper[A]
{
override def substep(): AnyStepper[A] = if (proxied ne null) proxied.substep else {
val acc = new Accumulator[A]
var i = 0
val n = (nextChunkSize & 0xFFFFFFFC)
while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 }
if (i < n || !underlying.hasNext) {
proxied = acc.stepper
proxied.substep
}
else {
val ans = semiclone()
ans.proxied = acc.stepper
nextChunkSize = if ((nextChunkSize&3) == 3) { if (n < 0x40000000) n*2 else n } else nextChunkSize + 1
ans
}
}
}
/** Abstracts the operation of stepping over an iterator of Doubles (needs caching when split) */
private[java8] abstract class StepsDoubleLikeIterator[SLI >: Null <: StepsDoubleLikeIterator[SLI] with DoubleStepper](_underlying: Iterator[Double])
extends AbstractStepsLikeIterator[Double, DoubleStepper, SLI](_underlying)
with DoubleStepper
{
override def substep(): DoubleStepper = if (proxied ne null) proxied.substep else {
val acc = new DoubleAccumulator
var i = 0
val n = (nextChunkSize & 0xFFFFFFFC)
while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 }
if (i < n || !underlying.hasNext) {
proxied = acc.stepper
proxied.substep
}
else {
val ans = semiclone()
ans.proxied = acc.stepper
nextChunkSize = if ((nextChunkSize&3) == 3) { if (n < 0x40000000) n*2 else n } else nextChunkSize + 1
ans
}
}
}
/** Abstracts the operation of stepping over an iterator of Ints (needs caching when split) */
private[java8] abstract class StepsIntLikeIterator[SLI >: Null <: StepsIntLikeIterator[SLI] with IntStepper](_underlying: Iterator[Int])
extends AbstractStepsLikeIterator[Int, IntStepper, SLI](_underlying)
with IntStepper
{
override def substep(): IntStepper = if (proxied ne null) proxied.substep else {
val acc = new IntAccumulator
var i = 0
val n = (nextChunkSize & 0xFFFFFFFC)
while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 }
if (i < n || !underlying.hasNext) {
proxied = acc.stepper
proxied.substep
}
else {
val ans = semiclone()
ans.proxied = acc.stepper
nextChunkSize = if ((nextChunkSize&3) == 3) { if (n < 0x40000000) n*2 else n } else nextChunkSize + 1
ans
}
}
}
/** Abstracts the operation of stepping over an iterator of Longs (needs caching when split) */
private[java8] abstract class StepsLongLikeIterator[SLI >: Null <: StepsLongLikeIterator[SLI] with LongStepper](_underlying: Iterator[Long])
extends AbstractStepsLikeIterator[Long, LongStepper, SLI](_underlying)
with LongStepper
{
override def substep: LongStepper = if (proxied ne null) proxied.substep else {
val acc = new LongAccumulator
var i = 0
val n = (nextChunkSize & 0xFFFFFFFC)
while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 }
if (i < n || !underlying.hasNext) {
proxied = acc.stepper
proxied.substep
}
else {
val ans = semiclone()
ans.proxied = acc.stepper
nextChunkSize = if ((nextChunkSize&3) == 3) { if (n < 0x40000000) n*2 else n } else nextChunkSize + 1
ans
}
}
}