From 375f09cd2685fe7b99b9b5334eb008241fa4185d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 27 Apr 2011 20:40:52 -0400 Subject: [PATCH] speed up startup --- util/collection/Dag.scala | 18 ++++++++++++++++++ util/collection/PMap.scala | 7 +++++++ util/collection/Settings.scala | 10 ++++------ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/util/collection/Dag.scala b/util/collection/Dag.scala index 29b43038a..8a6d0ba46 100644 --- a/util/collection/Dag.scala +++ b/util/collection/Dag.scala @@ -36,6 +36,24 @@ object Dag finished.toList; } + // doesn't check for cycles + def topologicalSortUnchecked[T](node: T)(dependencies: T => Iterable[T]): List[T] = + { + val discovered = new mutable.HashSet[T] + var finished: List[T] = Nil + + def visitAll(nodes: Iterable[T]) = nodes foreach visit + def visit(node : T){ + if (!discovered(node)) { + discovered(node) = true; + visitAll(dependencies(node)) + finished ::= node; + } + } + + visit(node); + finished; + } final class Cyclic(val value: Any, val all: List[Any], val complete: Boolean) extends Exception( "Cyclic reference involving " + (if(complete) all.mkString(", ") else value) ) { diff --git a/util/collection/PMap.scala b/util/collection/PMap.scala index 95bb1b6b0..febab0286 100644 --- a/util/collection/PMap.scala +++ b/util/collection/PMap.scala @@ -12,6 +12,8 @@ trait RMap[K[_], V[_]] def get[T](k: K[T]): Option[V[T]] def contains[T](k: K[T]): Boolean def toSeq: Seq[(K[_], V[_])] + def keys: Iterable[K[_]] + def values: Iterable[V[_]] } trait IMap[K[_], V[_]] extends (K ~> V) with RMap[K,V] @@ -54,6 +56,8 @@ object IMap def mapValues[V2[_]](f: V ~> V2) = new IMap0[K,V2](backing.mapValues(x => f(x)).toMap) def toSeq = backing.toSeq + def keys = backing.keys + def values = backing.values override def toString = backing.toString } @@ -83,6 +87,9 @@ class DelegatingPMap[K[_], V[_]](backing: mutable.Map[K[_], V[_]]) extends Abstr v } def toSeq = backing.toSeq + def keys = backing.keys + def values = backing.values + private[this] def cast[T](v: V[_]): V[T] = v.asInstanceOf[V[T]] private[this] def cast[T](o: Option[V[_]]): Option[V[T]] = o map cast[T] diff --git a/util/collection/Settings.scala b/util/collection/Settings.scala index aabb4c955..40d54de0d 100644 --- a/util/collection/Settings.scala +++ b/util/collection/Settings.scala @@ -68,7 +68,7 @@ trait Init[Scope] def asTransform(s: Settings[Scope]): ScopedKey ~> Id = new (ScopedKey ~> Id) { def apply[T](k: ScopedKey[T]): T = getValue(s, k) } - def getValue[T](s: Settings[Scope], k: ScopedKey[T]) = s.get(k.scope, k.key).get + def getValue[T](s: Settings[Scope], k: ScopedKey[T]) = s.get(k.scope, k.key) getOrElse error("Internal settings error: invalid reference to " + display(k)) def asFunction[T](s: Settings[Scope]): ScopedKey[T] => T = k => getValue(s, k) def compiled(init: Seq[Setting[_]], actual: Boolean = true)(implicit delegates: Scope => Seq[Scope], scopeLocal: ScopeLocal): CompiledMap = @@ -124,18 +124,16 @@ trait Init[Scope] } private[this] def delegateForKey[T](sMap: ScopedMap, k: ScopedKey[T], scopes: Seq[Scope], refKey: ScopedKey[_], isFirst: Boolean): ScopedKey[T] = { - val scache = PMap.empty[ScopedKey, ScopedKey] def resolve(search: Seq[Scope]): ScopedKey[T] = search match { case Seq() => throw Uninitialized(k, refKey) case Seq(x, xs @ _*) => val sk = ScopedKey(x, k.key) - scache.getOrUpdate(sk, if(defines(sMap, sk, refKey, isFirst)) sk else resolve(xs)) + val definesKey = (refKey != sk || !isFirst) && (sMap contains sk) + if(definesKey) sk else resolve(xs) } resolve(scopes) } - private[this] def defines(map: ScopedMap, key: ScopedKey[_], refKey: ScopedKey[_], isFirst: Boolean): Boolean = - (map get key) match { case Some(Seq(x, _*)) => (refKey != key) || !isFirst; case _ => false } private[this] def applyInits(ordered: Seq[Compiled])(implicit delegates: Scope => Seq[Scope]): Settings[Scope] = (empty /: ordered){ (m, comp) => comp.eval(m) } @@ -149,7 +147,7 @@ trait Init[Scope] final class Uninitialized(val key: ScopedKey[_], val refKey: ScopedKey[_], msg: String) extends Exception(msg) def Uninitialized(key: ScopedKey[_], refKey: ScopedKey[_]): Uninitialized = - new Uninitialized(key, refKey, "Reference to uninitialized setting " + key.key.label + " (in " + key.scope + ") from " + refKey.key.label +" (in " + refKey.scope + ")") + new Uninitialized(key, refKey, "Reference to uninitialized setting " + display(key) + " from " + display(refKey)) final class Compiled(val key: ScopedKey[_], val dependencies: Iterable[ScopedKey[_]], val eval: Settings[Scope] => Settings[Scope]) { override def toString = display(key)