Permalink
Browse files

inline tasks, for internal use later

  • Loading branch information...
1 parent 5ff33fa commit 4b724e11024b9d91f9081e13fd10370c4534d927 @harrah committed May 19, 2012
View
@@ -120,17 +120,17 @@ object EvaluateTask
try { f(str) } finally { str.close() }
}
- def getTask[T](structure: BuildStructure, taskKey: ScopedKey[Task[T]], state: State, streams: Streams, ref: ProjectRef): Option[(Task[T], Execute.NodeView[Task])] =
+ def getTask[T](structure: BuildStructure, taskKey: ScopedKey[Task[T]], state: State, streams: Streams, ref: ProjectRef): Option[(Task[T], NodeView[Task])] =
{
val thisScope = Load.projectScope(ref)
val resolvedScope = Scope.replaceThis(thisScope)( taskKey.scope )
for( t <- structure.data.get(resolvedScope, taskKey.key)) yield
(t, nodeView(state, streams, taskKey :: Nil))
}
- def nodeView[HL <: HList](state: State, streams: Streams, roots: Seq[ScopedKey[_]], extraDummies: KList[Task, HL] = KNil, extraValues: HL = HNil): Execute.NodeView[Task] =
+ def nodeView[HL <: HList](state: State, streams: Streams, roots: Seq[ScopedKey[_]], extraDummies: KList[Task, HL] = KNil, extraValues: HL = HNil): NodeView[Task] =
Transform(dummyRoots :^: dummyStreamsManager :^: KCons(dummyState, extraDummies), roots :+: streams :+: HCons(state, extraValues))
- def runTask[T](root: Task[T], state: State, streams: Streams, triggers: Triggers[Task], config: EvaluateConfig)(implicit taskToNode: Execute.NodeView[Task]): (State, Result[T]) =
+ def runTask[T](root: Task[T], state: State, streams: Streams, triggers: Triggers[Task], config: EvaluateConfig)(implicit taskToNode: NodeView[Task]): (State, Result[T]) =
{
import ConcurrentRestrictions.{completionService, TagMap, Tag, tagged, tagsKey}
View
@@ -15,7 +15,6 @@ object Execute
{
trait Part1of2K[M[_[_], _], A[_]] { type Apply[T] = M[A, T] }
type NodeT[A[_]] = Part1of2K[Node, A]
- type NodeView[A[_]] = A ~> NodeT[A]#Apply
def idMap[A,B]: Map[A, B] = JavaConversions.asScalaMap(new java.util.IdentityHashMap[A,B])
def pMap[A[_], B[_]]: PMap[A,B] = new DelegatingPMap[A, B](idMap)
@@ -27,6 +26,11 @@ object Execute
sealed trait Completed {
def process(): Unit
}
+trait NodeView[A[_]]
+{
+ def apply[T](a: A[T]): Node[A, T]
+ def inline[T](a: A[T]): Option[() => T]
+}
final class Triggers[A[_]](val runBefore: collection.Map[A[_], Seq[A[_]]], val injectFor: collection.Map[A[_], Seq[A[_]]], val onComplete: RMap[A,Result] => RMap[A,Result])
final class Execute[A[_] <: AnyRef](checkCycles: Boolean, triggers: Triggers[A])(implicit view: NodeView[A])
@@ -40,6 +44,13 @@ final class Execute[A[_] <: AnyRef](checkCycles: Boolean, triggers: Triggers[A])
private[this] val viewCache = pMap[A, NodeT[A]#Apply]
private[this] val results = pMap[A, Result]
+ private[this] val getResult: A ~> Result = new (A ~> Result) {
+ def apply[T](a: A[T]): Result[T] = view.inline(a) match {
+ case Some(v) => Value(v())
+ case None => results(a)
+ }
+ }
+
private[this] type State = State.Value
private[this] object State extends Enumeration {
val Pending, Running, Calling, Done = Value
@@ -216,8 +227,8 @@ final class Execute[A[_] <: AnyRef](checkCycles: Boolean, triggers: Triggers[A])
def submit[T]( node: A[T] )(implicit strategy: Strategy)
{
val v = viewCache(node)
- val rs = v.mixedIn transform results
- val ud = v.uniformIn.map(results.apply[v.Uniform])
+ val rs = v.mixedIn transform getResult
+ val ud = v.uniformIn.map(getResult.apply[v.Uniform])
strategy.submit( node, () => work(node, v.work(rs, ud)) )
}
/** Evaluates the computation 'f' for 'node'.
@@ -243,7 +254,7 @@ final class Execute[A[_] <: AnyRef](checkCycles: Boolean, triggers: Triggers[A])
def addCaller[T](caller: A[T], target: A[T]): Unit = callers.getOrUpdate(target, IDSet.create[A[T]]) += caller
def dependencies(node: A[_]): Iterable[A[_]] = dependencies(viewCache(node))
- def dependencies(v: Node[A, _]): Iterable[A[_]] = v.uniformIn ++ v.mixedIn.toList
+ def dependencies(v: Node[A, _]): Iterable[A[_]] = (v.uniformIn ++ v.mixedIn.toList).filter(dep => view.inline(dep).isEmpty)
def runBefore(node: A[_]): Seq[A[_]] = getSeq(triggers.runBefore, node)
def triggeredBy(node: A[_]): Seq[A[_]] = getSeq(triggers.injectFor, node)
View
@@ -6,7 +6,7 @@ package sbt
import Types._
/** Represents a task node in a format understood by the task evaluation engine Execute.
-* Heterogenous inputs (Mixed, tuple) and homogoneous (Uniform, sequence) are defined and consumed separately.
+* Heterogenous inputs (Mixed, tuple) and homogeneous (Uniform, sequence) are defined and consumed separately.
*
* @tparam A the task type
* @tparam T the type computed by this node */
@@ -12,8 +12,10 @@ package sbt
/** Defines a task compuation*/
sealed trait Action[T]
-/** A direct computation of a value. */
-final case class Pure[T](f: () => T) extends Action[T]
+/** A direct computation of a value.
+* If `inline` is true, `f` will be evaluated on the scheduler thread without the overhead of normal scheduling when possible.
+* This is intended as an optimization for already evaluated values or very short computations. */
+final case class Pure[T](f: () => T, inline: Boolean) extends Action[T]
/** Applies a function to the result of evaluating a heterogeneous list of other tasks.*/
final case class Mapped[T, In <: HList](in: Tasks[In], f: Results[In] => T) extends Action[T]
/** Computes another task to evaluate based on results from evaluating other tasks.*/
@@ -11,7 +11,7 @@ import Execute._
object Transform
{
- def fromDummy[T](original: Task[T])(action: => T): Task[T] = Task(original.info, Pure(action _))
+ def fromDummy[T](original: Task[T])(action: => T): Task[T] = Task(original.info, Pure(action _, false))
def fromDummyStrict[T](original: Task[T], value: T): Task[T] = fromDummy(original)( value)
implicit def to_~>| [K[_], V[_]](map: RMap[K,V]) : K ~>| V = new (K ~>| V) { def apply[T](k: K[T]): Option[V[T]] = map.get(k) }
@@ -39,17 +39,21 @@ object Transform
def apply[HL <: HList, Key](dummies: KList[Task, HL], injected: HL) =
{
import System._
- taskToNodegetOrId(dummyMap(dummies)(injected))
+ taskToNode( getOrId(dummyMap(dummies)(injected)) )
}
- def taskToNode = new (Task ~> NodeT[Task]#Apply) {
- def apply[T](t: Task[T]): Node[Task, T] = t.work match {
- case Pure(eval) => toNode(KNil)( _ => Right(eval()) )
+ def taskToNode(pre: Task ~> Task): NodeView[Task] = new NodeView[Task] {
+ def apply[T](t: Task[T]): Node[Task, T] = pre(t).work match {
+ case Pure(eval, _) => toNode(KNil)( _ => Right(eval()) )
case Mapped(in, f) => toNode(in)( right ∙ f )
case FlatMapped(in, f) => toNode(in)( left ∙ f )
case DependsOn(in, deps) => toNode(KList.fromList(deps))( ((_:Any) => Left(in)) ∙ allM )
case Join(in, f) => uniform(in)(f)
}
+ def inline[T](t: Task[T]) = t.work match {
+ case Pure(eval, true) => Some(eval)
+ case _ => None
+ }
}
def uniform[T, D](tasks: Seq[Task[D]])(f: Seq[Result[D]] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] {
@@ -86,7 +86,8 @@ trait TaskExtra
final implicit def actionToTask[T](a: Action[T]): Task[T] = Task(Info(), a)
final def task[T](f: => T): Task[T] = toTask(f _)
- final implicit def toTask[T](f: () => T): Task[T] = new Pure(f)
+ final implicit def toTask[T](f: () => T): Task[T] = new Pure(f, false)
+ final def inlineTask[T](value: T): Task[T] = new Pure(() => value, true)
final implicit def upcastTask[A >: B, B](t: Task[B]): Task[A] = t map { x => x : B }
final implicit def toTasks[S](in: Seq[() => S]): Seq[Task[S]] = in.map(toTask)

0 comments on commit 4b724e1

Please sign in to comment.