Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into rethrow
Browse files Browse the repository at this point in the history
  • Loading branch information
nikiforo committed Nov 30, 2021
2 parents 6fc311f + 647649b commit b811c67
Show file tree
Hide file tree
Showing 20 changed files with 705 additions and 468 deletions.
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "3.1.1"
version = "3.2.0"

style = default

Expand Down
37 changes: 8 additions & 29 deletions benchmark/src/main/scala/fs2/benchmark/ChunkBenchmark.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,47 +24,26 @@ package benchmark

import org.openjdk.jmh.annotations.{Benchmark, Param, Scope, Setup, State}

import cats.syntax.all._

@State(Scope.Thread)
class ChunkBenchmark {
@Param(Array("16", "256", "4096"))
var chunkSize: Int = _

@Param(Array("1", "20", "50", "100"))
var chunkCount: Int = _

case class Obj(dummy: Boolean)
object Obj {
def create: Obj = Obj(true)
}

var chunkSeq: Seq[Chunk[Obj]] = _
var flattened: Chunk[Obj] = _
var sizeHint: Int = _
var ints: Chunk[Int] = _

@Setup
def setup() = {
chunkSeq = Seq.range(0, chunkCount).map(_ => Chunk.seq(Seq.fill(chunkSize)(Obj.create)))
sizeHint = chunkSeq.foldLeft(0)(_ + _.size)
flattened = Chunk.seq(chunkSeq).flatten
}
def setup() =
ints = Chunk.seq((0 until chunkSize).map(_ + 1000)).compact

@Benchmark
def concat(): Unit = {
Chunk.concat(chunkSeq, sizeHint)
def map(): Unit = {
ints.map(_ + 1)
()
}

@Benchmark
def traverse(): Boolean = {
val fn: () => Chunk[Boolean] =
flattened.traverse { obj =>
if (obj.dummy) { () => true }
else { () => false }
}

fn().isEmpty
def filter(): Unit = {
ints.filter(_ % 3 == 0)
()
}

}
69 changes: 69 additions & 0 deletions benchmark/src/main/scala/fs2/benchmark/ChunksBenchmark.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2013 Functional Streams for Scala
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package fs2
package benchmark

import org.openjdk.jmh.annotations.{Benchmark, Param, Scope, Setup, State}

import cats.syntax.all._

@State(Scope.Thread)
class ChunksBenchmark {
@Param(Array("16", "256", "4096"))
var chunkSize: Int = _

@Param(Array("1", "20", "50", "100"))
var chunkCount: Int = _

case class Obj(dummy: Boolean)
object Obj {
def create: Obj = Obj(true)
}

var chunkSeq: Seq[Chunk[Obj]] = _
var flattened: Chunk[Obj] = _
var sizeHint: Int = _

@Setup
def setup() = {
chunkSeq = Seq.range(0, chunkCount).map(_ => Chunk.seq(Seq.fill(chunkSize)(Obj.create)))
sizeHint = chunkSeq.foldLeft(0)(_ + _.size)
flattened = Chunk.seq(chunkSeq).flatten
}

@Benchmark
def concat(): Unit = {
Chunk.concat(chunkSeq, sizeHint)
()
}

@Benchmark
def traverse(): Boolean = {
val fn: () => Chunk[Boolean] =
flattened.traverse { obj =>
if (obj.dummy) { () => true }
else { () => false }
}

fn().isEmpty
}
}
79 changes: 9 additions & 70 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,11 @@ lazy val core = crossProject(JVMPlatform, JSPlatform)
.settings(
name := "fs2-core",
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-core" % "2.6.1",
"org.typelevel" %%% "cats-laws" % "2.6.1" % Test,
"org.typelevel" %%% "cats-effect" % "3.2.9",
"org.typelevel" %%% "cats-effect-laws" % "3.2.9" % Test,
"org.typelevel" %%% "cats-effect-testkit" % "3.2.9" % Test,
"org.typelevel" %%% "cats-core" % "2.7.0",
"org.typelevel" %%% "cats-laws" % "2.7.0" % Test,
"org.typelevel" %%% "cats-effect" % "3.3.0",
"org.typelevel" %%% "cats-effect-laws" % "3.3.0" % Test,
"org.typelevel" %%% "cats-effect-testkit" % "3.3.0" % Test,
"org.scodec" %%% "scodec-bits" % "1.1.29",
"org.typelevel" %%% "scalacheck-effect-munit" % "1.0.3" % Test,
"org.typelevel" %%% "munit-cats-effect-3" % "1.0.6" % Test,
Expand All @@ -236,17 +236,8 @@ lazy val core = crossProject(JVMPlatform, JSPlatform)
)

lazy val coreJVM = core.jvm
.enablePlugins(SbtOsgi)
.settings(
Test / fork := true,
OsgiKeys.exportPackage := Seq("fs2.*"),
OsgiKeys.privatePackage := Seq(),
OsgiKeys.importPackage := {
val Some((major, minor)) = CrossVersion.partialVersion(scalaVersion.value)
Seq(s"""scala.*;version="[$major.$minor,$major.${minor + 1})"""", "*")
},
OsgiKeys.additionalHeaders := Map("-removeheaders" -> "Include-Resource,Private-Package"),
osgiSettings
Test / fork := true
)

lazy val coreJS = core.js
Expand Down Expand Up @@ -278,7 +269,6 @@ lazy val node = crossProject(JSPlatform)

lazy val io = crossProject(JVMPlatform, JSPlatform)
.in(file("io"))
.jvmEnablePlugins(SbtOsgi)
.jsEnablePlugins(ScalaJSBundlerPlugin)
.settings(
name := "fs2-io",
Expand All @@ -287,21 +277,9 @@ lazy val io = crossProject(JVMPlatform, JSPlatform)
.jvmSettings(
Test / fork := true,
libraryDependencies ++= Seq(
"com.github.jnr" % "jnr-unixsocket" % "0.38.12" % Optional,
"com.github.jnr" % "jnr-unixsocket" % "0.38.13" % Optional,
"com.google.jimfs" % "jimfs" % "1.2" % Test
),
OsgiKeys.exportPackage := Seq("fs2.io.*"),
OsgiKeys.privatePackage := Seq(),
OsgiKeys.importPackage := {
val Some((major, minor)) = CrossVersion.partialVersion(scalaVersion.value)
Seq(
s"""scala.*;version="[$major.$minor,$major.${minor + 1})"""",
"""fs2.*;version="${Bundle-Version}"""",
"*"
)
},
OsgiKeys.additionalHeaders := Map("-removeheaders" -> "Include-Resource,Private-Package"),
osgiSettings
)
)
.jsSettings(
scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.CommonJSModule)),
Expand All @@ -314,26 +292,13 @@ lazy val io = crossProject(JVMPlatform, JSPlatform)

lazy val scodec = crossProject(JVMPlatform, JSPlatform)
.in(file("scodec"))
.enablePlugins(SbtOsgi)
.settings(
name := "fs2-scodec",
libraryDependencies += "org.scodec" %%% "scodec-core" % (if (
scalaVersion.value.startsWith("2.")
)
"1.11.9"
else "2.1.0"),
OsgiKeys.exportPackage := Seq("fs2.interop.scodec.*"),
OsgiKeys.privatePackage := Seq(),
OsgiKeys.importPackage := {
val Some((major, minor)) = CrossVersion.partialVersion(scalaVersion.value)
Seq(
s"""scala.*;version="[$major.$minor,$major.${minor + 1})"""",
"""fs2.*;version="${Bundle-Version}"""",
"*"
)
},
OsgiKeys.additionalHeaders := Map("-removeheaders" -> "Include-Resource,Private-Package"),
osgiSettings,
mimaPreviousArtifacts := mimaPreviousArtifacts.value.filter { v =>
VersionNumber(v.revision).matchesSemVer(SemanticSelector(">3.2.0"))
}
Expand All @@ -345,21 +310,8 @@ lazy val scodec = crossProject(JVMPlatform, JSPlatform)

lazy val protocols = crossProject(JVMPlatform, JSPlatform)
.in(file("protocols"))
.enablePlugins(SbtOsgi)
.settings(
name := "fs2-protocols",
OsgiKeys.exportPackage := Seq("fs2.protocols.*"),
OsgiKeys.privatePackage := Seq(),
OsgiKeys.importPackage := {
val Some((major, minor)) = CrossVersion.partialVersion(scalaVersion.value)
Seq(
s"""scala.*;version="[$major.$minor,$major.${minor + 1})"""",
"""fs2.*;version="${Bundle-Version}"""",
"*"
)
},
OsgiKeys.additionalHeaders := Map("-removeheaders" -> "Include-Resource,Private-Package"),
osgiSettings,
mimaPreviousArtifacts := mimaPreviousArtifacts.value.filter { v =>
VersionNumber(v.revision).matchesSemVer(SemanticSelector(">3.2.0"))
}
Expand All @@ -371,27 +323,14 @@ lazy val protocols = crossProject(JVMPlatform, JSPlatform)

lazy val reactiveStreams = project
.in(file("reactive-streams"))
.enablePlugins(SbtOsgi)
.settings(
name := "fs2-reactive-streams",
Test / fork := true,
libraryDependencies ++= Seq(
"org.reactivestreams" % "reactive-streams" % "1.0.3",
"org.reactivestreams" % "reactive-streams-tck" % "1.0.3" % "test",
("org.scalatestplus" %% "testng-6-7" % "3.2.10.0" % "test").cross(CrossVersion.for3Use2_13)
),
OsgiKeys.exportPackage := Seq("fs2.interop.reactivestreams.*"),
OsgiKeys.privatePackage := Seq(),
OsgiKeys.importPackage := {
val Some((major, minor)) = CrossVersion.partialVersion(scalaVersion.value)
Seq(
s"""scala.*;version="[$major.$minor,$major.${minor + 1})"""",
"""fs2.*;version="${Bundle-Version}"""",
"*"
)
},
OsgiKeys.additionalHeaders := Map("-removeheaders" -> "Include-Resource,Private-Package"),
osgiSettings
)
)
.dependsOn(coreJVM % "compile->compile;test->test")

Expand Down
5 changes: 4 additions & 1 deletion core/shared/src/main/scala-2.12/fs2/ChunkPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

package fs2

import scala.collection.mutable.WrappedArray
import scala.collection.mutable.{ArrayBuilder, WrappedArray}
import scala.reflect.ClassTag

private[fs2] trait ChunkPlatform[+O] { self: Chunk[O] => }
Expand All @@ -34,6 +34,9 @@ private[fs2] trait ChunkCompanionPlatform { self: Chunk.type =>
case _ => None
}

private[fs2] def makeArrayBuilder[A](implicit ct: ClassTag[A]): ArrayBuilder[A] =
ArrayBuilder.make()(ct)

/** Creates a chunk backed by a `WrappedArray`
*/
def wrappedArray[O](wrappedArray: WrappedArray[O]): Chunk[O] = {
Expand Down
8 changes: 8 additions & 0 deletions core/shared/src/main/scala-2.13/fs2/ChunkPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package fs2

import scala.collection.immutable.ArraySeq
import scala.collection.immutable
import scala.collection.mutable.ArrayBuilder
import scala.reflect.ClassTag

private[fs2] trait ChunkPlatform[+O] { self: Chunk[O] =>
Expand Down Expand Up @@ -53,10 +54,17 @@ private[fs2] trait ChunkCompanionPlatform { self: Chunk.type =>
case _ => None
}

private[fs2] def makeArrayBuilder[A](implicit ct: ClassTag[A]): ArrayBuilder[A] =
ArrayBuilder.make(ct)

/** Creates a chunk backed by an immutable `ArraySeq`.
*/
def arraySeq[O](arraySeq: immutable.ArraySeq[O]): Chunk[O] = {
val arr = arraySeq.unsafeArray.asInstanceOf[Array[O]]
array(arr)(ClassTag[O](arr.getClass.getComponentType))
}

/** Creates a chunk from a `scala.collection.IterableOnce`. */
def iterableOnce[O](i: collection.IterableOnce[O]): Chunk[O] =
iterator(i.iterator)
}
8 changes: 8 additions & 0 deletions core/shared/src/main/scala-3/fs2/ChunkPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package fs2

import scala.collection.immutable.ArraySeq
import scala.collection.immutable
import scala.collection.mutable.ArrayBuilder
import scala.reflect.ClassTag

private[fs2] trait ChunkPlatform[+O] { self: Chunk[O] =>
Expand Down Expand Up @@ -62,6 +63,9 @@ private[fs2] trait ChunkCompanionPlatform { self: Chunk.type =>
case _ => None
}

private[fs2] def makeArrayBuilder[A](implicit ct: ClassTag[A]): ArrayBuilder[A] =
ArrayBuilder.make(ct)

/** Creates a chunk backed by an immutable `ArraySeq`.
*/
def arraySeq[O](arraySeq: immutable.ArraySeq[O]): Chunk[O] = {
Expand Down Expand Up @@ -115,4 +119,8 @@ private[fs2] trait ChunkCompanionPlatform { self: Chunk.type =>
if (offset == 0 && length == values.length) values
else super.toIArray[O2]
}

/** Creates a chunk from a `scala.collection.IterableOnce`. */
def iterableOnce[O](i: collection.IterableOnce[O]): Chunk[O] =
iterator(i.iterator)
}
Loading

0 comments on commit b811c67

Please sign in to comment.