cached resolution: use mutable map to speed up breakLoops

This commit is contained in:
Eugene Yokota 2015-08-05 07:01:21 -04:00
parent dd94cb90d9
commit 868740a2ae
1 changed files with 13 additions and 19 deletions

View File

@ -410,7 +410,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
// group by takes up too much memory. trading space with time. // group by takes up too much memory. trading space with time.
val orgNamePairs: Vector[(String, String)] = (reports0 map { oar => (oar.organization, oar.name) }).distinct val orgNamePairs: Vector[(String, String)] = (reports0 map { oar => (oar.organization, oar.name) }).distinct
// this might take up some memory, but it's limited to a single // this might take up some memory, but it's limited to a single
val reports1 = reports0 map { filterOutCallers } val reports1 = reports0 flatMap { filterReports }
val allModules0: Map[(String, String), Vector[OrganizationArtifactReport]] = val allModules0: Map[(String, String), Vector[OrganizationArtifactReport]] =
Map(orgNamePairs map { Map(orgNamePairs map {
case (organization, name) => case (organization, name) =>
@ -447,15 +447,15 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
} }
loopLists.toList loopLists.toList
} }
@tailrec def breakLoops(loops: List[List[(String, String)]], val allModules2: mutable.Map[(String, String), Vector[OrganizationArtifactReport]] =
allModules1: Map[(String, String), Vector[OrganizationArtifactReport]]): Map[(String, String), Vector[OrganizationArtifactReport]] = mutable.Map(allModules0.toSeq: _*)
@tailrec def breakLoops(loops: List[List[(String, String)]]): Unit =
loops match { loops match {
case Nil => case Nil => ()
allModules1
case loop :: rest => case loop :: rest =>
loop match { loop match {
case Nil => case Nil =>
breakLoops(rest, allModules1) breakLoops(rest)
case loop => case loop =>
val sortedLoop = loop sortBy { x => val sortedLoop = loop sortBy { x =>
(for { (for {
@ -468,7 +468,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
val next: (String, String) = loop(loop.indexOf(moduleWithMostCallers) + 1) val next: (String, String) = loop(loop.indexOf(moduleWithMostCallers) + 1)
// remove the module with most callers as the caller of next. // remove the module with most callers as the caller of next.
// so, A -> C, B -> C, and C -> A. C has the most callers, and C -> A will be removed. // so, A -> C, B -> C, and C -> A. C has the most callers, and C -> A will be removed.
val nextMap = allModules1 map { allModules2 foreach {
case (k: (String, String), oars0) if k == next => case (k: (String, String), oars0) if k == next =>
val oars: Vector[OrganizationArtifactReport] = oars0 map { oar => val oars: Vector[OrganizationArtifactReport] = oars0 map { oar =>
val mrs = oar.modules map { mr => val mrs = oar.modules map { mr =>
@ -482,15 +482,17 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
} }
OrganizationArtifactReport(oar.organization, oar.name, mrs) OrganizationArtifactReport(oar.organization, oar.name, mrs)
} }
(k, oars) allModules2(k) = oars
case (k, v) => (k, v) case (k, v) => // do nothing
} }
breakLoops(rest, nextMap)
breakLoops(rest)
} }
} }
val loop = detectLoops(allModules0) val loop = detectLoops(allModules0)
log.debug(s":: $rootModuleConf: loop: $loop") log.debug(s":: $rootModuleConf: loop: $loop")
val allModules2 = breakLoops(loop, allModules0) breakLoops(loop)
// sort the all modules such that less called modules comes earlier // sort the all modules such that less called modules comes earlier
@tailrec def sortModules(cs: Vector[(String, String)], @tailrec def sortModules(cs: Vector[(String, String)],
acc: Vector[(String, String)], extra: Vector[(String, String)], acc: Vector[(String, String)], extra: Vector[(String, String)],
@ -554,14 +556,6 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
val result = resolveConflicts(sorted.toList, allModules0) val result = resolveConflicts(sorted.toList, allModules0)
result.toVector result.toVector
} }
def filterOutCallers(report0: OrganizationArtifactReport): OrganizationArtifactReport =
OrganizationArtifactReport(
report0.organization,
report0.name,
report0.modules map { mr =>
// https://github.com/sbt/sbt/issues/1763
mr.copy(callers = JsonUtil.filterOutArtificialCallers(mr.callers))
})
/** /**
* Merges ModuleReports, which represents orgnization, name, and version. * Merges ModuleReports, which represents orgnization, name, and version.
* Returns a touple of (surviving modules ++ non-conflicting modules, newly evicted modules). * Returns a touple of (surviving modules ++ non-conflicting modules, newly evicted modules).