]> git.unchartedbackwaters.co.uk Git - francis/ofc.git/commitdiff
Reimplement transitive closure for better reuse.
authorFrancis Russell <francis@unchartedbackwaters.co.uk>
Fri, 6 Apr 2012 18:12:14 +0000 (19:12 +0100)
committerFrancis Russell <francis@unchartedbackwaters.co.uk>
Fri, 6 Apr 2012 18:18:43 +0000 (19:18 +0100)
src/ofc/codegen/ProducerStatement.scala
src/ofc/util/Ordering.scala

index 52cbba321a9eaaab1045a7ee875b8c092d2a45fe..c79e169ad06f1147885fe980d196efa0c3355af0 100644 (file)
@@ -4,19 +4,12 @@ import ofc.util.Ordering
 class ProducerStatement extends Statement {
   object Context {
     def sort(contexts: Seq[Context]) : Seq[Context] = {
-      val ordering = scala.collection.mutable.Set[(Context, Context)]()
-      for(c1 <- contexts; c2 <- contexts)
-        (c1.tryCompare(c2)) match {
-          case Some(x) => {
-            if (x<0) 
-              ordering += (c1 -> c2)
-            else if (x>0)
-              ordering += (c2 -> c1)
-          }
-          case None => ()
-        }
+      def pathFunction(c1: Context, c2: Context) = c1.tryCompare(c2) match {
+        case Some(x) if x<0 => true
+        case _ => false
+      }
 
-      val totalOrdering = Ordering.transitiveClosure(ordering.toSet)
+      val totalOrdering = Ordering.transitiveClosure(contexts, pathFunction(_: Context, _: Context))
       contexts.sortWith((a,b) => totalOrdering.contains(a,b))
     }
   }
index bd6fd461553f34c593535fbb90de1b7c201a8d84..3bc1c09c5532b33e819d7519c46d201303ef5c9e 100644 (file)
@@ -1,26 +1,14 @@
 package ofc.util
-import scala.annotation.tailrec
 
 object Ordering {
-  
-  @tailrec
-  def transitiveClosure[T](ordering: Set[(T, T)]) : Set[(T, T)] = {
-    def step[T](ordering: Set[(T, T)]) = {
-      val newOrdering = scala.collection.mutable.Set[(T, T)]()
-      newOrdering ++= ordering
+  def transitiveClosure[T](nodes: Seq[T], hasPath: (T,T) => Boolean) : Set[(T,T)] = {
+    val ordering = scala.collection.mutable.Set[(T, T)]()
+    ordering ++= { for(n1 <- nodes; n2 <- nodes; if hasPath(n1, n2)) yield (n1 -> n2) }
 
-      for ((a1,a2) <- ordering; (b1, b2) <- ordering; if a2 == b1)
-        newOrdering += (a1 -> b2)
+    for(via <- nodes; start <- nodes; end <- nodes)
+      if (!ordering.contains(start -> end) && ordering.contains(start -> via) && ordering.contains(via -> end))
+        ordering += (start -> end)
 
-      assert(newOrdering.size >= ordering.size)
-      newOrdering.toSet
-    }
-
-    val stepped = step(ordering)
-
-    if (stepped.size == ordering.size)
-      ordering
-    else
-      transitiveClosure(stepped)
+    ordering.toSet
   }
 }