From 256810de286c67c4ae68acbdb009ec94d4ca7776 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Sun, 15 Feb 2009 14:40:42 +0100
Subject: [PATCH] A small optimization in node computation

Currently we always compute the available node list for moves (for an
instances) based on the nodes of the initial table. This works find,
however is a repeated calculation.

We optimize this by passing a node list (of indexes, not full objects),
which helps in two ways:
  - faster to filter later
  - allows restriction of target nodes by enforcing only this subset as
    target for moves
---
 src/Cluster.hs | 36 ++++++++++++++++++------------------
 src/hbal.hs    |  5 +++--
 2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/src/Cluster.hs b/src/Cluster.hs
index b3ce190d1..be811db1e 100644
--- a/src/Cluster.hs
+++ b/src/Cluster.hs
@@ -389,24 +389,22 @@ checkSingleStep ini_tbl target cur_tbl move =
           in
             compareTables cur_tbl upd_tbl
 
-checkInstanceMove :: Table             -- original Table
-                  -> Instance.Instance -- instance to move
-                  -> Table             -- best new table for this instance
-checkInstanceMove ini_tbl target =
+checkInstanceMove :: [Int]             -- Allowed target node indices
+                  -> Table             -- Original table
+                  -> Instance.Instance -- Instance to move
+                  -> Table             -- Best new table for this instance
+checkInstanceMove nodes_idx ini_tbl target =
     let
-        Table ini_nl _ _ _ = ini_tbl
         opdx = Instance.pnode target
         osdx = Instance.snode target
-        nodes = filter (\node -> let idx = Node.idx node
-                                 in idx /= opdx && idx /= osdx)
-                $ Container.elems ini_nl
+        nodes = filter (\idx -> idx /= opdx && idx /= osdx)
+                nodes_idx
         aft_failover = checkSingleStep ini_tbl target ini_tbl Failover
     in
       -- iterate over the possible nodes for this instance
       foldl'
-      (\ accu_p new_node ->
+      (\ accu_p new_idx ->
            let
-               new_idx = Node.idx new_node
                pmoves = [ReplacePrimary new_idx,
                          ReplaceSecondary new_idx]
            in
@@ -415,16 +413,18 @@ checkInstanceMove ini_tbl target =
       ) aft_failover nodes
 
 -- | Compute the best next move.
-checkMove :: Table            -- ^ The current solution
+checkMove :: [Int]               -- ^ Allowed target node indices
+          -> Table               -- ^ The current solution
           -> [Instance.Instance] -- ^ List of instances still to move
-          -> Table            -- ^ The new solution
-checkMove ini_tbl victims =
+          -> Table               -- ^ The new solution
+checkMove nodes_idx ini_tbl victims =
     let Table _ _ _ ini_plc = ini_tbl
         -- iterate over all instances, computing the best move
-        best_tbl = foldl'
-                   (\ step_tbl elem -> compareTables step_tbl $
-                                       checkInstanceMove ini_tbl elem)
-                   ini_tbl victims
+        best_tbl =
+            foldl'
+            (\ step_tbl elem -> compareTables step_tbl $
+                                checkInstanceMove nodes_idx ini_tbl elem)
+            ini_tbl victims
     in let
         Table _ _ _ best_plc = best_tbl
         (target, _, _) = head best_plc
@@ -436,7 +436,7 @@ checkMove ini_tbl victims =
              ini_tbl
          else
              if null vtail then best_tbl
-             else checkMove best_tbl vtail
+             else checkMove nodes_idx best_tbl vtail
 
 
 {- | Auxiliary function for solution computation.
diff --git a/src/hbal.hs b/src/hbal.hs
index 564837167..070c16667 100644
--- a/src/hbal.hs
+++ b/src/hbal.hs
@@ -52,9 +52,10 @@ iterateDepth :: Cluster.Table    -- The starting table
              -> Bool             -- ^ Wheter to be silent
              -> IO Cluster.Table -- The resulting table
 iterateDepth ini_tbl cur_round max_rounds oneline =
-    let Cluster.Table _ ini_il ini_cv ini_plc = ini_tbl
+    let Cluster.Table ini_nl ini_il ini_cv ini_plc = ini_tbl
         all_inst = Container.elems ini_il
-        fin_tbl = Cluster.checkMove ini_tbl all_inst
+        node_idx = Container.keys ini_nl
+        fin_tbl = Cluster.checkMove node_idx ini_tbl all_inst
         (Cluster.Table _ _ fin_cv fin_plc) = fin_tbl
         ini_plc_len = length ini_plc
         fin_plc_len = length fin_plc
-- 
GitLab