-
Notifications
You must be signed in to change notification settings - Fork 0
/
DelayingArray.scala
116 lines (93 loc) · 2.91 KB
/
DelayingArray.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
package me.d_d.delaying
class DelayingArray(val left: ResizableArray, val right: ResizableArray) {
val size: Int = left.size + right.size
def apply(idx: Int) = {
if (idx < left.size)
left(idx)
else
right(size - idx - 1)
}
def updated(idx: Int, value: Int): DelayingArray = {
if (idx < left.size)
new DelayingArray(left.updated(idx, value), right)
else
new DelayingArray(left, right.updated(size - idx - 1, value))
}
def append(elem: Int): DelayingArray = {
new DelayingArray(left, right prepend elem)
}
def prepend(elem: Int): DelayingArray = {
new DelayingArray(left prepend elem, right)
}
def reverse = new DelayingArray(right, left)
def foreach(f: Int => Unit): Unit = {
left.foreach(f)
right.rforeach(f)
}
// Optimize
def iterator: DelayingArrayIterator = new DelayingArrayIterator(this)
}
class DelayingArrayIterator(val darr: DelayingArray) {
private var index = 0
// First non-null entry
private var leftArr = Integer.numberOfTrailingZeros(darr.left.arraysTotalSize)
private var leftIndex = 0
private var rightArr = darr.right.arrays.length
private var rightIndex = -1
private final val leftArrays = darr.left.arrays
private final val rightArrays = darr.right.arrays
private final val leftHeads = darr.right.heads
private final val rightHeads = darr.right.heads
private final val leftSize = darr.left.size
private final val leftHeadsSize = darr.left.heads.length
private final val beforeRightHead = leftSize + darr.right.arraysTotalSize
private final val darrSize = darr.size
final def hasNext: Boolean = (index < darr.size)
final def foreach(f: Int => Unit): Unit = {
while (hasNext)
f(next())
}
final def leftNext(): Int = {
if (index >= leftHeadsSize) {
if (leftIndex >= leftArrays(leftArr).length) {
do leftArr += 1 while (leftArrays(leftArr).eq(null))
leftIndex = 0
}
val tmp = leftArrays(leftArr)(leftIndex)
leftIndex += 1
tmp
} else
leftHeads(index)
}
final def rightNext(): Int = {
if (index < beforeRightHead) {
if (rightIndex < 0) {
do rightArr -= 1 while (rightArrays(rightArr).eq(null))
rightIndex = rightArrays(rightArr).length - 1
}
val tmp = rightArrays(rightArr)(rightIndex)
rightIndex -= 1
tmp
} else
rightHeads(darrSize - index - 1)
}
final def next(): Int = {
if (!hasNext) throw new NoSuchElementException
val elem: Int = {
if (index < leftSize)
leftNext()
else
rightNext()
}
index += 1
elem
}
}
object DelayingArray {
val empty = new DelayingArray(ResizableArray.empty, ResizableArray.empty)
def apply(elems: Int*): DelayingArray = {
// elems.foldLeft(empty)(_ append _)
val (left, right) = elems.splitAt(elems.size / 2)
new DelayingArray(ResizableArray(left: _*), ResizableArray(right.reverse: _*))
}
}