From 7bae3d04a96ff68d22f4e09101820683c75f5558 Mon Sep 17 00:00:00 2001
From: Pedro Gonnet <pedro.gonnet@durham.ac.uk>
Date: Wed, 26 Jun 2013 22:11:55 +0000
Subject: [PATCH] make superfluous sorts implicit or skip them alltogether.

Former-commit-id: 95f9b781749d85eb1fd337283da3115428304f11
---
 src/cell.h      |  2 +-
 src/engine.c    | 21 +++++++++++++++++----
 src/scheduler.c | 25 +++++++++++++------------
 3 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/src/cell.h b/src/cell.h
index 6005929f35..bfa54e6b54 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -65,7 +65,7 @@ struct cell {
     
     /* Pointers for the sorted indices. */
     struct entry *sort;
-    int sorted;
+    unsigned int sorted;
     
     /* Number of pairs associated with this cell. */
     // int nr_pairs;
diff --git a/src/engine.c b/src/engine.c
index 0e78da341e..cdb8afc8b3 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -269,6 +269,15 @@ int engine_marktasks ( struct engine *e ) {
                     return 1;
 
                 }
+                
+            /* Sort? */
+            else if ( t->type == task_type_sort ) {
+            
+                /* If all the sorts have been done, make this task implicit. */
+                if ( !( t->flags & (t->flags ^ t->ci->sorted ) ) )
+                    t->implicit = 1;
+            
+                }
 
             }
             
@@ -320,10 +329,14 @@ int engine_marktasks ( struct engine *e ) {
 
                 /* Set the sort flags. */
                 if ( !t->skip && t->type == task_type_pair ) {
-                    ci->sorts->flags |= (1 << t->flags);
-                    ci->sorts->skip = 0;
-                    cj->sorts->flags |= (1 << t->flags);
-                    cj->sorts->skip = 0;
+                    if ( !( ci->sorted & ( 1 << t->flags ) ) ) {
+                        ci->sorts->flags |= (1 << t->flags);
+                        ci->sorts->skip = 0;
+                        }
+                    if ( !( cj->sorted & ( 1 << t->flags ) ) ) {
+                        cj->sorts->flags |= (1 << t->flags);
+                        cj->sorts->skip = 0;
+                        }
                     }
 
                 }
diff --git a/src/scheduler.c b/src/scheduler.c
index 6a132d21ce..fc2a5db633 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -692,18 +692,19 @@ void scheduler_done ( struct scheduler *s , struct task *t ) {
     struct task *t2;
     
     /* Release whatever locks this task held. */
-    switch ( t->type ) {
-        case task_type_self:
-        case task_type_sort:
-            cell_unlocktree( t->ci );
-            break;
-        case task_type_pair:
-        case task_type_sub:
-            cell_unlocktree( t->ci );
-            if ( t->cj != NULL )
-                cell_unlocktree( t->cj );
-            break;
-        }
+    if ( !t->implicit )
+        switch ( t->type ) {
+            case task_type_self:
+            case task_type_sort:
+                cell_unlocktree( t->ci );
+                break;
+            case task_type_pair:
+            case task_type_sub:
+                cell_unlocktree( t->ci );
+                if ( t->cj != NULL )
+                    cell_unlocktree( t->cj );
+                break;
+            }
         
     /* Loop through the dependencies and add them to a queue if
        they are ready. */
-- 
GitLab