Skip to content

Commit

Permalink
Merge pull request #762 from sangria-graphql/optimize_objects_creation
Browse files Browse the repository at this point in the history
avoid allocations
  • Loading branch information
yanns authored Oct 26, 2021
2 parents 4a56cd2 + 11e40f2 commit 443e7a5
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 114 deletions.
18 changes: 10 additions & 8 deletions modules/core/src/main/scala/sangria/execution/FieldCollector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,15 @@ class FieldCollector[Ctx, Val](
.map(dir -> _)
})

possibleDirs.collect { case Failure(error) => error }.headOption.map(Failure(_)).getOrElse {
val validDirs = possibleDirs.collect { case Success(v) => v }
val should = validDirs.forall { case (dir, args) =>
dir.shouldInclude(DirectiveContext(selection, dir, args))
}
possibleDirs.collectFirst { case Failure(error) => error } match {
case Some(f) => Failure(f)
case None =>
val validDirs = possibleDirs.collect { case Success(v) => v }
val should = validDirs.forall { case (dir, args) =>
dir.shouldInclude(DirectiveContext(selection, dir, args))
}

Success(should)
Success(should)
}
}

Expand Down Expand Up @@ -255,9 +257,9 @@ class CollectedFieldsBuilder {
}

def build = {
val builtFields = firstFields.toVector.zipWithIndex.map { case (f, idx) =>
val builtFields = firstFields.iterator.zipWithIndex.map { case (f, idx) =>
CollectedField(names(idx), f, fields(idx).map(_.toVector))
}
}.toVector

CollectedFields(names.toVector, builtFields)
}
Expand Down
53 changes: 32 additions & 21 deletions modules/core/src/main/scala/sangria/execution/Resolver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,12 @@ class Resolver[Ctx](
Result(ErrorRegistry(fieldPath, resolveError(e), fields.head.location), None)
}

val deferred = values.collect { case SeqRes(_, d, _) if d != null => d }.toVector
val deferredFut = values.collect { case SeqRes(_, _, d) if d != null => d }.toVector
val deferred = values.iterator.collect {
case SeqRes(_, d, _) if d != null => d
}.toVector
val deferredFut = values.iterator.collect {
case SeqRes(_, _, d) if d != null => d
}.toVector

immediatelyResolveDeferred(
uc,
Expand Down Expand Up @@ -826,7 +830,7 @@ class Resolver[Ctx](

val resolved = future
.flatMap { vs =>
val errors = vs.flatMap(_.errors).toVector
val errors = vs.iterator.flatMap(_.errors).toVector
val successfulValues = vs.collect { case SeqFutRes(v, _, _) if v != null => v }
val dctx = vs.collect { case SeqFutRes(_, _, d) if d != null => d }

Expand Down Expand Up @@ -869,8 +873,12 @@ class Resolver[Ctx](
None)
}

val deferred = values.collect { case SeqRes(_, d, _) if d != null => d }.toVector
val deferredFut = values.collect { case SeqRes(_, _, d) if d != null => d }.toVector
val deferred = values.iterator.collect {
case SeqRes(_, d, _) if d != null => d
}.toVector
val deferredFut = values.iterator.collect {
case SeqRes(_, _, d) if d != null => d
}.toVector

astFields.head -> DeferredResult(Future.successful(deferred) +: deferredFut, resolved)

Expand Down Expand Up @@ -1101,19 +1109,19 @@ class Resolver[Ctx](

}

val simpleRes = resolvedValues.collect { case (af, r: Result) => af -> r }

val resSoFar =
simpleRes.foldLeft(Result(errors, Some(marshaller.emptyMapNode(fieldsNamesOrdered)))) {
case (res, (astField, other)) =>
res.addToMap(
other,
astField.outputName,
isOptional(tpe, astField.name),
path.add(astField, tpe),
astField.location,
res.errors)
}
resolvedValues.iterator
.collect { case (af, r: Result) => af -> r }
.foldLeft(Result(errors, Some(marshaller.emptyMapNode(fieldsNamesOrdered)))) {
case (res, (astField, other)) =>
res.addToMap(
other,
astField.outputName,
isOptional(tpe, astField.name),
path.add(astField, tpe),
astField.location,
res.errors)
}

val complexRes = resolvedValues.collect { case (af, r: DeferredResult) => af -> r }

Expand Down Expand Up @@ -1438,7 +1446,7 @@ class Resolver[Ctx](
val beforeAction = mBefore.collect {
case (BeforeFieldResult(_, Some(action), _), _, _) => action
}.lastOption
val beforeAttachments = mBefore.collect {
val beforeAttachments = mBefore.iterator.collect {
case (BeforeFieldResult(_, _, Some(att)), _, _) => att
}.toVector
val updatedCtx =
Expand All @@ -1463,14 +1471,15 @@ class Resolver[Ctx](
}

def doErrorMiddleware(error: Throwable): Unit =
mError.collect {
mError.foreach {
case (BeforeFieldResult(cv, _, _), mv, m: MiddlewareErrorField[Ctx]) =>
m.fieldError(
mv.asInstanceOf[m.QueryVal],
cv.asInstanceOf[m.FieldVal],
error,
middlewareCtx,
updatedCtx)
case _ => ()
}

def doAfterMiddlewareWithMap[Val, NewVal](fn: Val => NewVal)(v: Val): NewVal =
Expand Down Expand Up @@ -1646,10 +1655,12 @@ class Resolver[Ctx](
.contains(ProjectionExclude) =>
val astField = fields.head
val field = objTpe.getField(schema, astField.name).head
val projectionNames = field.tags.collect { case ProjectionName(name) => name }
val projectionNames = field.tags.iterator.collect { case ProjectionName(name) =>
name
}.toVector

val projectedName =
if (projectionNames.nonEmpty) projectionNames.toVector
if (projectionNames.nonEmpty) projectionNames
else Vector(field.name)

projectedName.map(name =>
Expand Down
Loading

0 comments on commit 443e7a5

Please sign in to comment.