speed up startup

This commit is contained in:
Mark Harrah 2011-04-27 20:40:52 -04:00
parent 58d2e3415c
commit 375f09cd26
3 changed files with 29 additions and 6 deletions

View File

@ -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) )
{

View File

@ -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]

View File

@ -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)