Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.

Commit c241908

Browse files
committed
Fix semantic issue according to Stefan's review comments and add test cases
1 parent 99f32cd commit c241908

File tree

3 files changed

+82
-12
lines changed

3 files changed

+82
-12
lines changed

benchmarks/time/src/main/scala/strawman/collection/immutable/ImmutableArrayBenchmark.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import scala.Predef.intWrapper
1010

1111
@BenchmarkMode(scala.Array(Mode.AverageTime))
1212
@OutputTimeUnit(TimeUnit.NANOSECONDS)
13-
@Fork(2)
13+
@Fork(1)
1414
@Warmup(iterations = 8)
1515
@Measurement(iterations = 8)
1616
@State(Scope.Benchmark)

collections/src/main/scala/strawman/collection/immutable/ImmutableArray.scala

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ object ImmutableArray extends StrictOptimizedSeqFactory[ImmutableArray] {
186186
}
187187
override def slice(from: Int, until: Int): ImmutableArray[T] = {
188188
val lo = scala.math.max(from, 0)
189-
ImmutableArray.unsafeWrapArray(Arrays.copyOfRange[T](unsafeArray, lo, until))
189+
val hi = scala.math.min(until, length)
190+
new ofRef(Arrays.copyOfRange[T](unsafeArray, lo, hi))
190191
}
191192
}
192193

@@ -201,7 +202,8 @@ object ImmutableArray extends StrictOptimizedSeqFactory[ImmutableArray] {
201202
}
202203
override def slice(from: Int, until: Int): ImmutableArray[Byte] = {
203204
val lo = scala.math.max(from, 0)
204-
ImmutableArray.unsafeWrapArray(Arrays.copyOfRange(unsafeArray, lo, until))
205+
val hi = scala.math.min(until, length)
206+
new ofByte(Arrays.copyOfRange(unsafeArray, lo, hi))
205207
}
206208
}
207209

@@ -216,7 +218,8 @@ object ImmutableArray extends StrictOptimizedSeqFactory[ImmutableArray] {
216218
}
217219
override def slice(from: Int, until: Int): ImmutableArray[Short] = {
218220
val lo = scala.math.max(from, 0)
219-
ImmutableArray.unsafeWrapArray(Arrays.copyOfRange(unsafeArray, lo, until))
221+
val hi = scala.math.min(until, length)
222+
new ofShort(Arrays.copyOfRange(unsafeArray, lo, hi))
220223
}
221224
}
222225

@@ -231,7 +234,8 @@ object ImmutableArray extends StrictOptimizedSeqFactory[ImmutableArray] {
231234
}
232235
override def slice(from: Int, until: Int): ImmutableArray[Char] = {
233236
val lo = scala.math.max(from, 0)
234-
ImmutableArray.unsafeWrapArray(Arrays.copyOfRange(unsafeArray, lo, until))
237+
val hi = scala.math.min(until, length)
238+
new ofChar(Arrays.copyOfRange(unsafeArray, lo, hi))
235239
}
236240
}
237241

@@ -246,7 +250,8 @@ object ImmutableArray extends StrictOptimizedSeqFactory[ImmutableArray] {
246250
}
247251
override def slice(from: Int, until: Int): ImmutableArray[Int] = {
248252
val lo = scala.math.max(from, 0)
249-
ImmutableArray.unsafeWrapArray(Arrays.copyOfRange(unsafeArray, lo, until))
253+
val hi = scala.math.min(until, length)
254+
new ofInt(Arrays.copyOfRange(unsafeArray, lo, hi))
250255
}
251256
}
252257

@@ -261,7 +266,8 @@ object ImmutableArray extends StrictOptimizedSeqFactory[ImmutableArray] {
261266
}
262267
override def slice(from: Int, until: Int): ImmutableArray[Long] = {
263268
val lo = scala.math.max(from, 0)
264-
ImmutableArray.unsafeWrapArray(Arrays.copyOfRange(unsafeArray, lo, until))
269+
val hi = scala.math.min(until, length)
270+
new ofLong(Arrays.copyOfRange(unsafeArray, lo, hi))
265271
}
266272
}
267273

@@ -276,7 +282,8 @@ object ImmutableArray extends StrictOptimizedSeqFactory[ImmutableArray] {
276282
}
277283
override def slice(from: Int, until: Int): ImmutableArray[Float] = {
278284
val lo = scala.math.max(from, 0)
279-
ImmutableArray.unsafeWrapArray(Arrays.copyOfRange(unsafeArray, lo, until))
285+
val hi = scala.math.min(until, length)
286+
new ofFloat(Arrays.copyOfRange(unsafeArray, lo, hi))
280287
}
281288
}
282289

@@ -291,7 +298,8 @@ object ImmutableArray extends StrictOptimizedSeqFactory[ImmutableArray] {
291298
}
292299
override def slice(from: Int, until: Int): ImmutableArray[Double] = {
293300
val lo = scala.math.max(from, 0)
294-
ImmutableArray.unsafeWrapArray(Arrays.copyOfRange(unsafeArray, lo, until))
301+
val hi = scala.math.min(until, length)
302+
new ofDouble(Arrays.copyOfRange(unsafeArray, lo, hi))
295303
}
296304
}
297305

@@ -306,7 +314,8 @@ object ImmutableArray extends StrictOptimizedSeqFactory[ImmutableArray] {
306314
}
307315
override def slice(from: Int, until: Int): ImmutableArray[Boolean] = {
308316
val lo = scala.math.max(from, 0)
309-
ImmutableArray.unsafeWrapArray(Arrays.copyOfRange(unsafeArray, lo, until))
317+
val hi = scala.math.min(until, length)
318+
new ofBoolean(Arrays.copyOfRange(unsafeArray, lo, hi))
310319
}
311320
}
312321

@@ -324,8 +333,9 @@ object ImmutableArray extends StrictOptimizedSeqFactory[ImmutableArray] {
324333
// new ofUnit(util.Arrays.copyOfRange[Unit](array, from, until)) - Unit is special and doesnt compile
325334
// cant use util.Arrays.copyOfRange[Unit](repr, from, until) - Unit is special and doesnt compile
326335
val lo = scala.math.max(from, 0)
327-
val res = new Array[Unit](until-lo)
328-
System.arraycopy(unsafeArray, lo, res, 0, until-lo)
336+
val hi = scala.math.min(until, length)
337+
val slicedLenght = hi - lo
338+
val res = new Array[Unit](slicedLenght)
329339
new ofUnit(res)
330340
}
331341
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package strawman.collection.immutable
2+
3+
import org.junit.Assert
4+
import org.junit.Test
5+
import org.junit.runner.RunWith
6+
import org.junit.runners.JUnit4
7+
8+
@RunWith(classOf[JUnit4])
9+
class ImmutableArrayTest {
10+
@Test
11+
def slice(): Unit = {
12+
import scala.language.implicitConversions
13+
14+
implicit def array2ImmutableArray[T](array: Array[T]): ImmutableArray[T] =
15+
ImmutableArray.unsafeWrapArray(array)
16+
17+
val booleanArray = Array(true, false, true, false)
18+
check(booleanArray, Array(true, false), Array(false, true))
19+
20+
val shortArray = Array(1.toShort, 2.toShort, 3.toShort, 4.toShort)
21+
check(shortArray, Array(1.toShort, 2.toShort), Array(2.toShort, 3.toShort))
22+
23+
val intArray = Array(1, 2, 3, 4)
24+
check(intArray, Array(1, 2), Array(2, 3))
25+
26+
val longArray = Array(1L, 2L, 3L, 4L)
27+
check(longArray, Array(1L, 2L), Array(2L, 3L))
28+
29+
val byteArray = Array(1.toByte, 2.toByte, 3.toByte, 4.toByte)
30+
check(byteArray, Array(1.toByte, 2.toByte), Array(2.toByte, 3.toByte))
31+
32+
val charArray = Array('1', '2', '3', '4')
33+
check(charArray, Array('1', '2'), Array('2', '3'))
34+
35+
val doubleArray = Array(1.0, 2.0, 3.0, 4.0)
36+
check(doubleArray, Array(1.0, 2.0), Array(2.0, 3.0))
37+
38+
val floatArray = Array(1.0f, 2.0f, 3.0f, 4.0f)
39+
check(floatArray, Array(1.0f, 2.0f), Array(2.0f, 3.0f))
40+
41+
val refArray = Array("1", "2", "3", "4")
42+
check[String](refArray, Array("1", "2"), Array("2", "3"))
43+
44+
def unit1(): Unit = {}
45+
def unit2(): Unit = {}
46+
Assert.assertEquals(unit1, unit2)
47+
// unitArray is actually an instance of Immutable[BoxedUnit], the check to which is actually checked slice
48+
// implementation of ofRef
49+
val unitArray: ImmutableArray[Unit] = Array(unit1, unit2, unit1, unit2)
50+
check(unitArray, Array(unit1, unit1), Array(unit1, unit1))
51+
}
52+
53+
private def check[T](array: ImmutableArray[T], expectedSliceResult1: ImmutableArray[T], expectedSliceResult2: ImmutableArray[T]) {
54+
Assert.assertEquals(array, array.slice(-1, 4))
55+
Assert.assertEquals(array, array.slice(0, 5))
56+
Assert.assertEquals(array, array.slice(-1, 5))
57+
Assert.assertEquals(expectedSliceResult1, array.slice(0, 2))
58+
Assert.assertEquals(expectedSliceResult2, array.slice(1, 3))
59+
}
60+
}

0 commit comments

Comments
 (0)