Skip to content

Commit

Permalink
Avoid unnecessary creation of Both / Then when `BlockedRequests =…
Browse files Browse the repository at this point in the history
…= Empty` (#494)

* Avoid creation of objects when BlockedRequests == Empty

* Place Empty as last in pattern-matching
  • Loading branch information
kyri-petrou authored Jul 1, 2024
1 parent 210eacb commit a57ea1d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 26 deletions.
46 changes: 27 additions & 19 deletions zio-query/shared/src/main/scala/zio/query/ZQuery.scala
Original file line number Diff line number Diff line change
Expand Up @@ -851,9 +851,11 @@ final class ZQuery[-R, +E, +A] private (private val step: ZIO[R, Nothing, Result
Exit.succeed(Result.blocked(br, Continue.effect(c.zipWith(that)(f))))
case Result.Blocked(br1, c1) =>
that.step.map {
case Result.Blocked(br2, c2) => Result.blocked(br1 ++ br2, c1.zipWith(c2)(f))
case Result.Done(b) => Result.blocked(br1, c1.map(a => f(a, b)))
case Result.Fail(e) => Result.fail(e)
case Result.Blocked(br2, c2) =>
val br = if (br1.isEmpty) br2 else if (br2.isEmpty) br1 else br1 ++ br2
Result.blocked(br, c1.zipWith(c2)(f))
case Result.Done(b) => Result.blocked(br1, c1.map(a => f(a, b)))
case Result.Fail(e) => Result.fail(e)
}
case Result.Done(a) =>
that.step.map {
Expand All @@ -874,13 +876,15 @@ final class ZQuery[-R, +E, +A] private (private val step: ZIO[R, Nothing, Result
)(f: (A, B) => C)(implicit trace: Trace): ZQuery[R1, E1, C] =
ZQuery {
self.step.zipWith(that.step) {
case (Result.Blocked(br1, c1), Result.Blocked(br2, c2)) => Result.blocked(br1 && br2, c1.zipWithBatched(c2)(f))
case (Result.Blocked(br, c), Result.Done(b)) => Result.blocked(br, c.map(a => f(a, b)))
case (Result.Done(a), Result.Blocked(br, c)) => Result.blocked(br, c.map(b => f(a, b)))
case (Result.Done(a), Result.Done(b)) => Result.done(f(a, b))
case (Result.Fail(e1), Result.Fail(e2)) => Result.fail(Cause.Both(e1, e2))
case (Result.Fail(e), _) => Result.fail(e)
case (_, Result.Fail(e)) => Result.fail(e)
case (Result.Blocked(br1, c1), Result.Blocked(br2, c2)) =>
val br = if (br1.isEmpty) br2 else if (br2.isEmpty) br1 else br1 && br2
Result.blocked(br, c1.zipWithBatched(c2)(f))
case (Result.Blocked(br, c), Result.Done(b)) => Result.blocked(br, c.map(a => f(a, b)))
case (Result.Done(a), Result.Blocked(br, c)) => Result.blocked(br, c.map(b => f(a, b)))
case (Result.Done(a), Result.Done(b)) => Result.done(f(a, b))
case (Result.Fail(e1), Result.Fail(e2)) => Result.fail(Cause.Both(e1, e2))
case (Result.Fail(e), _) => Result.fail(e)
case (_, Result.Fail(e)) => Result.fail(e)
}
}

Expand All @@ -895,13 +899,15 @@ final class ZQuery[-R, +E, +A] private (private val step: ZIO[R, Nothing, Result
)(f: (A, B) => C)(implicit trace: Trace): ZQuery[R1, E1, C] =
ZQuery {
self.step.zipWithPar(that.step) {
case (Result.Blocked(br1, c1), Result.Blocked(br2, c2)) => Result.blocked(br1 && br2, c1.zipWithPar(c2)(f))
case (Result.Blocked(br, c), Result.Done(b)) => Result.blocked(br, c.map(a => f(a, b)))
case (Result.Done(a), Result.Blocked(br, c)) => Result.blocked(br, c.map(b => f(a, b)))
case (Result.Done(a), Result.Done(b)) => Result.done(f(a, b))
case (Result.Fail(e1), Result.Fail(e2)) => Result.fail(Cause.Both(e1, e2))
case (Result.Fail(e), _) => Result.fail(e)
case (_, Result.Fail(e)) => Result.fail(e)
case (Result.Blocked(br1, c1), Result.Blocked(br2, c2)) =>
val br = if (br1.isEmpty) br2 else if (br2.isEmpty) br1 else br1 && br2
Result.blocked(br, c1.zipWithPar(c2)(f))
case (Result.Blocked(br, c), Result.Done(b)) => Result.blocked(br, c.map(a => f(a, b)))
case (Result.Done(a), Result.Blocked(br, c)) => Result.blocked(br, c.map(b => f(a, b)))
case (Result.Done(a), Result.Done(b)) => Result.done(f(a, b))
case (Result.Fail(e1), Result.Fail(e2)) => Result.fail(Cause.Both(e1, e2))
case (Result.Fail(e), _) => Result.fail(e)
case (_, Result.Fail(e)) => Result.fail(e)
}
}

Expand Down Expand Up @@ -1302,8 +1308,10 @@ object ZQuery {

while (iter.hasNext) {
iter.next() match {
case Result.Blocked(blockedRequest, continue) =>
blockedRequests = if (mode == 0) blockedRequests ++ blockedRequest else blockedRequests && blockedRequest
case Result.Blocked(br, continue) =>
if (!br.isEmpty) {
blockedRequests = if (mode == 0) blockedRequests ++ br else blockedRequests && br
}
continue match {
case Continue.Effect(query) =>
effectBuilder.addOne(query)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ private[query] sealed trait BlockedRequests[-R] { self =>
@tailrec
def loop(in: List[BlockedRequests[R]], out: List[Either[BlockedRequestsCase, Z]]): List[Z] =
in match {
case Empty :: blockedRequests =>
loop(blockedRequests, Right(folder.emptyCase) :: out)
case Single(dataSource, blockedRequest) :: blockedRequests =>
loop(blockedRequests, Right(folder.singleCase(dataSource, blockedRequest)) :: out)
case Both(left, right) :: blockedRequests =>
loop(left :: right :: blockedRequests, Left(BothCase) :: out)
case Then(left, right) :: blockedRequests =>
loop(left :: right :: blockedRequests, Left(ThenCase) :: out)
case Empty :: blockedRequests =>
loop(blockedRequests, Right(folder.emptyCase) :: out)
case Nil =>
out.foldLeft[List[Z]](List.empty) {
case (acc, Right(blockedRequests)) =>
Expand All @@ -86,6 +86,8 @@ private[query] sealed trait BlockedRequests[-R] { self =>
loop(List(self), List.empty).head
}

final def isEmpty: Boolean = self eq Empty

/**
* Transforms all data sources with the specified data source aspect, which
* can change the environment type of data sources but must preserve the
Expand Down Expand Up @@ -158,7 +160,9 @@ private[query] object BlockedRequests {

final case class Both[-R](left: BlockedRequests[R], right: BlockedRequests[R]) extends BlockedRequests[R]

case object Empty extends BlockedRequests[Any]
case object Empty extends BlockedRequests[Any] {
override def run(implicit trace: Trace): ZIO[Any, Nothing, Unit] = Exit.unit
}

final case class Single[-R, A](dataSource: DataSource[R, A], blockedRequest: BlockedRequest[A])
extends BlockedRequests[R]
Expand Down Expand Up @@ -239,11 +243,11 @@ private[query] object BlockedRequests {
stack: List[BlockedRequests[R]]
): Unit =
blockedRequests match {
case Empty =>
if (stack ne Nil) loop(stack.head, stack.tail)
case Single(dataSource, request) =>
parallel.addOne(dataSource, request)
if (stack ne Nil) loop(stack.head, stack.tail)
case Both(left, right) =>
loop(left, right :: stack)
case Then(left, right) =>
left match {
case Empty => loop(right, stack)
Expand All @@ -252,8 +256,8 @@ private[query] object BlockedRequests {
if (right ne Empty) sequential.prepend(right)
loop(o, stack)
}
case Both(left, right) =>
loop(left, right :: stack)
case Empty =>
if (stack ne Nil) loop(stack.head, stack.tail)
}

loop(c, List.empty)
Expand Down

0 comments on commit a57ea1d

Please sign in to comment.