Skip to content

Commit

Permalink
Chunk - Introduce a Constant Chunk subclass.
Browse files Browse the repository at this point in the history
When creating a constant stream, out of constant chunks, we do not
need to allocate a list of 256 nodes with the same value. instead
we can just write a chunk as a constant function.
  • Loading branch information
diesalbla committed Sep 25, 2022
1 parent a2552a7 commit 10ba16d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
26 changes: 26 additions & 0 deletions core/shared/src/main/scala/fs2/Chunk.scala
Expand Up @@ -546,6 +546,32 @@ object Chunk
override def map[O2](f: O => O2): Chunk[O2] = singleton(f(value))
}

def constant[A](value: A, size: Int): Chunk[A] = size match {
case 0 => empty
case 1 => singleton(value)
case _ => new Constant(value, size)
}

final class Constant[A](value: A, override val size: Int) extends Chunk[A] {

def apply(i: Int): A =
if (0 <= i && i < size) value else throw new IndexOutOfBoundsException()

def copyToArray[O2 >: A](xs: Array[O2], start: Int): Unit = {

@tailrec
def go(ix: Int): Unit =
if (ix < size) {
xs(start + ix) = value
go(ix + 1)
}
go(0)
}

protected def splitAtChunk_(n: Int): (Chunk[A], Chunk[A]) =
constant(value, n) -> constant(value, size - n)
}

/** Creates a chunk backed by a vector. */
def vector[O](v: Vector[O]): Chunk[O] = indexedSeq(v)

Expand Down
2 changes: 1 addition & 1 deletion core/shared/src/main/scala/fs2/Stream.scala
Expand Up @@ -3100,7 +3100,7 @@ object Stream extends StreamLowPriority {
* }}}
*/
def constant[F[x] >: Pure[x], O](o: O, chunkSize: Int = 256): Stream[F, O] =
chunk(Chunk.seq(List.fill(chunkSize)(o))).repeat
chunk(Chunk.constant(o, chunkSize)).repeat

/** A continuous stream of the elapsed time, computed using `System.nanoTime`.
* Note that the actual granularity of these elapsed times depends on the OS, for instance
Expand Down

0 comments on commit 10ba16d

Please sign in to comment.