Revision f25e5aac

b/Ganeti/HTools/Cluster.hs
46 46
    , printNodes
47 47
    -- * Balacing functions
48 48
    , checkMove
49
    , tryBalance
49 50
    , compCV
50 51
    , printStats
51 52
    -- * IAllocator functions
......
442 443
      else
443 444
          best_tbl
444 445

  
446
-- | Run a balance move
447

  
448
tryBalance :: Table       -- ^ The starting table
449
           -> Int         -- ^ Remaining length
450
           -> Bool        -- ^ Allow disk moves
451
           -> Score       -- ^ Score at which to stop
452
           -> Maybe Table -- ^ The resulting table and commands
453
tryBalance ini_tbl max_rounds disk_moves min_score =
454
    let Table ini_nl ini_il ini_cv ini_plc = ini_tbl
455
        ini_plc_len = length ini_plc
456
        allowed_next = (max_rounds < 0 || ini_plc_len < max_rounds) &&
457
                       ini_cv > min_score
458
    in
459
      if allowed_next
460
      then let all_inst = Container.elems ini_il
461
               node_idx = map Node.idx . filter (not . Node.offline) $
462
                          Container.elems ini_nl
463
               fin_tbl = checkMove node_idx disk_moves ini_tbl all_inst
464
               (Table _ _ fin_cv _) = fin_tbl
465
           in
466
             if fin_cv < ini_cv
467
             then Just fin_tbl -- this round made success, try deeper
468
             else Nothing
469
      else Nothing
470

  
445 471
-- * Allocation functions
446 472

  
447 473
-- | Build failure stats out of a list of failures
b/hbal.hs
80 80
                                               -- commands
81 81
iterateDepth ini_tbl max_rounds disk_moves nmlen imlen
82 82
             cmd_strs oneline min_score =
83
    let Cluster.Table ini_nl ini_il ini_cv ini_plc = ini_tbl
84
        all_inst = Container.elems ini_il
85
        node_idx = map Node.idx . filter (not . Node.offline) $
86
                   Container.elems ini_nl
87
        fin_tbl = Cluster.checkMove node_idx disk_moves ini_tbl all_inst
88
        (Cluster.Table _ _ fin_cv fin_plc) = fin_tbl
89
        ini_plc_len = length ini_plc
90
        fin_plc_len = length fin_plc
91
        allowed_next = (max_rounds < 0 || length fin_plc < max_rounds)
83
    let Cluster.Table ini_nl ini_il _ _ = ini_tbl
84
        m_fin_tbl = Cluster.tryBalance ini_tbl max_rounds disk_moves min_score
92 85
    in
93
      do
94
        let
95
            (sol_line, cmds) = Cluster.printSolutionLine ini_nl ini_il
96
                               nmlen imlen (head fin_plc) fin_plc_len
97
            upd_cmd_strs = cmds:cmd_strs
98
        unless (oneline || fin_plc_len == ini_plc_len) $ do
99
          putStrLn sol_line
100
          hFlush stdout
101
        (if fin_cv < ini_cv then -- this round made success, try deeper
102
             if allowed_next && fin_cv > min_score
103
             then iterateDepth fin_tbl max_rounds disk_moves
104
                  nmlen imlen upd_cmd_strs oneline min_score
105
             -- don't go deeper, but return the better solution
106
             else return (fin_tbl, upd_cmd_strs)
107
         else
108
             return (ini_tbl, cmd_strs))
86
      case m_fin_tbl of
87
        Just fin_tbl ->
88
            do
89
              let
90
                  (Cluster.Table _ _ _ fin_plc) = fin_tbl
91
                  fin_plc_len = length fin_plc
92
                  (sol_line, cmds) = Cluster.printSolutionLine ini_nl ini_il
93
                                     nmlen imlen (head fin_plc) fin_plc_len
94
                  upd_cmd_strs = cmds:cmd_strs
95
              unless oneline $ do
96
                       putStrLn sol_line
97
                       hFlush stdout
98
              iterateDepth fin_tbl max_rounds disk_moves
99
                           nmlen imlen upd_cmd_strs oneline min_score
100
        Nothing -> return (ini_tbl, cmd_strs)
109 101

  
110 102
-- | Formats the solution for the oneline display
111 103
formatOneline :: Double -> Int -> Double -> String

Also available in: Unified diff