From 5ad867775f36f3111dbfdb18414f7ccdf3e843ea Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Thu, 14 Jan 2010 17:05:29 +0100 Subject: [PATCH] Split the balancing function in two parts Currently in the balancing function we do two thing: - take the decision where to do a new balancing round or not - and actually computing the balancing round This is not nice, as the two parts are conceptually separate, so this patch splits the decision on whether to descend or not to a new function. --- Ganeti/HTools/Cluster.hs | 39 +++++++++++++++++++++------------------ hbal.hs | 5 ++++- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/Ganeti/HTools/Cluster.hs b/Ganeti/HTools/Cluster.hs index e29eb0981..ab5cbb4b5 100644 --- a/Ganeti/HTools/Cluster.hs +++ b/Ganeti/HTools/Cluster.hs @@ -47,6 +47,7 @@ module Ganeti.HTools.Cluster , printInsts -- * Balacing functions , checkMove + , doNextBalance , tryBalance , compCV , printStats @@ -77,7 +78,6 @@ type AllocSolution = ([FailMode], Int, Maybe (Score, AllocElement)) -- | Allocation\/relocation element. type AllocElement = (Node.List, Instance.Instance, [Node.Node]) - -- | The complete state for the balancing solution data Table = Table Node.List Instance.List Score [Placement] deriving (Show) @@ -448,29 +448,32 @@ checkMove nodes_idx disk_moves ini_tbl victims = else best_tbl +-- | Check if we are allowed to go deeper in the balancing + +doNextBalance :: Table -- ^ The starting table + -> Int -- ^ Remaining length + -> Score -- ^ Score at which to stop + -> Bool -- ^ The resulting table and commands +doNextBalance ini_tbl max_rounds min_score = + let Table _ _ ini_cv ini_plc = ini_tbl + ini_plc_len = length ini_plc + in (max_rounds < 0 || ini_plc_len < max_rounds) && ini_cv > min_score + -- | Run a balance move tryBalance :: Table -- ^ The starting table - -> Int -- ^ Remaining length -> Bool -- ^ Allow disk moves - -> Score -- ^ Score at which to stop -> Maybe Table -- ^ The resulting table and commands -tryBalance ini_tbl max_rounds disk_moves min_score = - let Table ini_nl ini_il ini_cv ini_plc = ini_tbl - ini_plc_len = length ini_plc - allowed_next = (max_rounds < 0 || ini_plc_len < max_rounds) && - ini_cv > min_score +tryBalance ini_tbl disk_moves = + let Table ini_nl ini_il ini_cv _ = ini_tbl + all_inst = Container.elems ini_il + node_idx = map Node.idx . filter (not . Node.offline) $ + Container.elems ini_nl + fin_tbl = checkMove node_idx disk_moves ini_tbl all_inst + (Table _ _ fin_cv _) = fin_tbl in - if allowed_next - then let all_inst = Container.elems ini_il - node_idx = map Node.idx . filter (not . Node.offline) $ - Container.elems ini_nl - fin_tbl = checkMove node_idx disk_moves ini_tbl all_inst - (Table _ _ fin_cv _) = fin_tbl - in - if fin_cv < ini_cv - then Just fin_tbl -- this round made success, try deeper - else Nothing + if fin_cv < ini_cv + then Just fin_tbl -- this round made success, return the new table else Nothing -- * Allocation functions diff --git a/hbal.hs b/hbal.hs index ae4cb80c9..66681adc4 100644 --- a/hbal.hs +++ b/hbal.hs @@ -94,7 +94,10 @@ iterateDepth :: Cluster.Table -- ^ The starting table iterateDepth ini_tbl max_rounds disk_moves nmlen imlen cmd_strs oneline min_score = let Cluster.Table ini_nl ini_il _ _ = ini_tbl - m_fin_tbl = Cluster.tryBalance ini_tbl max_rounds disk_moves min_score + allowed_next = Cluster.doNextBalance ini_tbl max_rounds min_score + m_fin_tbl = if allowed_next + then Cluster.tryBalance ini_tbl disk_moves + else Nothing in case m_fin_tbl of Just fin_tbl -> -- GitLab