Skip to content

Commit

Permalink
Merge pull request #10651 from som-snytt/followup/array-builder-followup
Browse files Browse the repository at this point in the history
Size hint with delta is not negative
  • Loading branch information
lrytz committed Jan 8, 2024
2 parents 13a80bd + 895a620 commit c1067d3
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
13 changes: 7 additions & 6 deletions src/library/scala/collection/mutable/Builder.scala
Expand Up @@ -35,10 +35,7 @@ trait Builder[-A, +To] extends Growable[A] { self =>
*
* Some builder classes will optimize their representation based on the hint.
* However, builder implementations are required to work correctly even if the hint is
* wrong, i.e., if a different number of elements is added.
*
* The semantics of supplying a hint out of range, such as a size that is negative
* or unreasonably large, is not specified but is implementation-dependent.
* wrong, e.g., a different number of elements is added, or the hint is out of range.
*
* The default implementation simply ignores the hint.
*
Expand All @@ -54,9 +51,13 @@ trait Builder[-A, +To] extends Growable[A] { self =>
*
* {{{
* if (coll.knownSize != -1)
* sizeHint(coll.knownSize + delta)
* if (coll.knownSize + delta <= 0) sizeHint(0)
* else sizeHint(coll.knownSize + delta)
* }}}
*
* If the delta is negative and the result size is known to be negative,
* then the size hint is issued at zero.
*
* Some builder classes will optimize their representation based on the hint.
* However, builder implementations are required to work correctly even if the hint is
* wrong, i.e., if a different number of elements is added.
Expand All @@ -67,7 +68,7 @@ trait Builder[-A, +To] extends Growable[A] { self =>
final def sizeHint(coll: scala.collection.IterableOnce[_], delta: Int = 0): Unit =
coll.knownSize match {
case -1 =>
case sz => sizeHint(sz + delta)
case sz => sizeHint(0 max sz + delta)
}

/** Gives a hint how many elements are expected to be added
Expand Down
25 changes: 25 additions & 0 deletions test/junit/scala/collection/mutable/BuilderTest.scala
@@ -0,0 +1,25 @@

package scala.collection.mutable

import org.junit.Test
import org.junit.Assert.assertEquals

class BuilderTest {
class TestBuilder extends Builder[String, String] {
val stuff = ListBuffer.empty[String]
def clear() = stuff.clear()
def result() = stuff.mkString("hello, world: ", ",", "")
def addOne(s: String) = { stuff.addOne(s); this }
var expectedSize = 16
override def sizeHint(size: Int) = expectedSize = size
}

@Test def `sizeHint is capped`: Unit = {
val b = new TestBuilder
val prototype = Nil
b.sizeHint(prototype, delta = -1)
assertEquals(0, b.expectedSize)
b.addOne("tested!")
assertEquals("hello, world: tested!", b.result())
}
}

0 comments on commit c1067d3

Please sign in to comment.