Skip to content

Commit

Permalink
backport #15565 (chunking into a single delete)
Browse files Browse the repository at this point in the history
- a prerequisite to make order-by on delete meaningful for large transactions
  • Loading branch information
S11001001 committed Feb 27, 2023
1 parent 8c3cbf5 commit 029f2b5
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 13 deletions.
2 changes: 2 additions & 0 deletions ledger-service/db-backend/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ da_scala_library(
"//ledger/metrics",
"//libs-scala/contextualized-logging",
"//libs-scala/nonempty",
"//libs-scala/nonempty-cats",
"//libs-scala/scala-utils",
"@maven//:io_dropwizard_metrics_metrics_core",
],
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,21 +306,25 @@ sealed abstract class Queries(tablePrefix: String, tpIdCacheMaxEntries: Long)(im
final def deleteContracts(
cids: Set[String]
)(implicit log: LogHandler): ConnectionIO[Int] = {
import cats.data.NonEmptyVector
import cats.instances.vector._
import cats.instances.int._
import cats.syntax.foldable._
NonEmptyVector.fromVector(cids.toVector) match {
case None =>
free.connection.pure(0)
case Some(cids) =>
val chunks = maxListSize.fold(Vector(cids))(size => cids.grouped(size).toVector)
chunks
.map(chunk =>
(fr"DELETE FROM $contractTableName WHERE " ++ Fragments
.in(fr"contract_id", chunk)).update.run
import nonempty.catsinstances._
cids match {
case NonEmpty(cids) =>
val del = fr"DELETE FROM $contractTableName WHERE " ++ {
val chunks =
maxListSize.fold(NonEmpty(Vector, cids)) { size =>
val NonEmpty(groups) =
cids.grouped(size).collect { case NonEmpty(group) => group }.toVector
groups
}
joinFragment(
chunks.map(cids => Fragments.in(fr"contract_id", cids.toVector.toNEF)),
fr" OR ",
)
.foldA
}
del.update.run
case _ =>
free.connection.pure(0)
}
}

Expand Down Expand Up @@ -508,6 +512,10 @@ object Queries {
case object GTEQ extends OrderOperator
}

// XXX SC I'm pretty certain we can use NonEmpty all the way down
private[http] def joinFragment(xs: NonEmpty[Vector[Fragment]], sep: Fragment): Fragment =
concatFragment(intersperse(xs.toOneAnd, sep))

private[http] def joinFragment(xs: OneAnd[Vector, Fragment], sep: Fragment): Fragment =
concatFragment(intersperse(xs, sep))

Expand Down

0 comments on commit 029f2b5

Please sign in to comment.