@@ -88,7 +88,11 @@ abstract class Chunk[+O] extends Serializable with ChunkPlatform[O] with ChunkRu
88
88
/** Copies the elements of this chunk in to the specified array at the specified start index. */
89
89
def copyToArray [O2 >: O ](xs : Array [O2 ], start : Int = 0 ): Unit
90
90
91
- /** Converts this chunk to a chunk backed by a single array. */
91
+ /** Converts this chunk to a chunk backed by a single array.
92
+ *
93
+ * Alternatively, call `toIndexedChunk` to get back a chunk with guaranteed O(1) indexed lookup
94
+ * while also minimizing copying.
95
+ */
92
96
def compact [O2 >: O ](implicit ct : ClassTag [O2 ]): Chunk .ArraySlice [O2 ] =
93
97
Chunk .ArraySlice (toArray[O2 ], 0 , size)
94
98
@@ -309,6 +313,21 @@ abstract class Chunk[+O] extends Serializable with ChunkPlatform[O] with ChunkRu
309
313
if (isEmpty) Chain .empty
310
314
else Chain .fromSeq(toList)
311
315
316
+ /** Returns a chunk with guaranteed O(1) lookup by index.
317
+ *
318
+ * Unlike `compact`, this operation does not copy any elements unless this chunk
319
+ * does not provide O(1) lookup by index -- e.g., a chunk built via 1 or more usages
320
+ * of `++`.
321
+ */
322
+ def toIndexedChunk : Chunk [O ] = this match {
323
+ case _ : Chunk .Queue [_] =>
324
+ val b = collection.mutable.Buffer .newBuilder[O ]
325
+ b.sizeHint(size)
326
+ foreach(o => b += o)
327
+ Chunk .buffer(b.result())
328
+ case other => other
329
+ }
330
+
312
331
/** Converts this chunk to a list. */
313
332
def toList : List [O ] =
314
333
if (isEmpty) Nil
@@ -1063,6 +1082,14 @@ object Chunk
1063
1082
1064
1083
check(chunks, 0 )
1065
1084
}
1085
+
1086
+ override def traverse [F [_], O2 ](f : O => F [O2 ])(implicit F : Applicative [F ]): F [Chunk [O2 ]] =
1087
+ toIndexedChunk.traverse(f)
1088
+
1089
+ override def traverseFilter [F [_], O2 ](f : O => F [Option [O2 ]])(implicit
1090
+ F : Applicative [F ]
1091
+ ): F [Chunk [O2 ]] =
1092
+ toIndexedChunk.traverseFilter(f)
1066
1093
}
1067
1094
1068
1095
object Queue {
0 commit comments