From 8a3b30ca2b2afd389440889f2bfcb36b00cc88f6 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Wed, 21 Jul 2010 17:33:00 +0200
Subject: [PATCH] Introduce per-metric weights

Currently all metrics have the same weight (we just sum them together).
However, for the hard constraints (N+1 failures, offline nodes, etc.)
we should handle the metrics differently based on their meaning. For
example, an instance living on a primary offline node is worse than an
instance having its secondary node offline, which in turn is worse than
an instance having its secondary node failing N+1.

To express this case in our code, we introduce a table of weights for
the metrics, with which we can influence their relative importance.
---
 Ganeti/HTools/Cluster.hs | 42 ++++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/Ganeti/HTools/Cluster.hs b/Ganeti/HTools/Cluster.hs
index d8c90665e..ab573645f 100644
--- a/Ganeti/HTools/Cluster.hs
+++ b/Ganeti/HTools/Cluster.hs
@@ -202,21 +202,24 @@ computeAllocationDelta cini cfin =
         runa = RSpec un_cpu (truncate t_mem - f_imem) (truncate t_dsk - f_idsk)
     in (rini, rfin, runa)
 
--- | The names of the individual elements in the CV list
-detailedCVNames :: [String]
-detailedCVNames = [ "free_mem_cv"
-                  , "free_disk_cv"
-                  , "n1_cnt"
-                  , "reserved_mem_cv"
-                  , "offline_all_cnt"
-                  , "offline_pri_cnt"
-                  , "vcpu_ratio_cv"
-                  , "cpu_load_cv"
-                  , "mem_load_cv"
-                  , "disk_load_cv"
-                  , "net_load_cv"
-                  , "pri_tags_score"
-                  ]
+-- | The names and weights of the individual elements in the CV list
+detailedCVInfo :: [(Double, String)]
+detailedCVInfo = [ (1,  "free_mem_cv")
+                 , (1,  "free_disk_cv")
+                 , (1,  "n1_cnt")
+                 , (1,  "reserved_mem_cv")
+                 , (4,  "offline_all_cnt")
+                 , (16, "offline_pri_cnt")
+                 , (1,  "vcpu_ratio_cv")
+                 , (1,  "cpu_load_cv")
+                 , (1,  "mem_load_cv")
+                 , (1,  "disk_load_cv")
+                 , (1,  "net_load_cv")
+                 , (1,  "pri_tags_score")
+                 ]
+
+detailedCVWeights :: [Double]
+detailedCVWeights = map fst detailedCVInfo
 
 -- | Compute the mem and disk covariance.
 compDetailedCV :: Node.List -> [Double]
@@ -265,7 +268,7 @@ compDetailedCV nl =
 
 -- | Compute the /total/ variance.
 compCV :: Node.List -> Double
-compCV = sum . compDetailedCV
+compCV = sum . zipWith (*) detailedCVWeights . compDetailedCV
 
 -- | Compute online nodes from a Node.List
 getOnline :: Node.List -> [Node.Node]
@@ -797,9 +800,10 @@ printInsts nl il =
 printStats :: Node.List -> String
 printStats nl =
     let dcvs = compDetailedCV nl
-        hd = zip (detailedCVNames ++ repeat "unknown") dcvs
-        formatted = map (\(header, val) ->
-                             printf "%s=%.8f" header val::String) hd
+        (weights, names) = unzip detailedCVInfo
+        hd = zip3 (weights ++ repeat 1) (names ++ repeat "unknown") dcvs
+        formatted = map (\(w, header, val) ->
+                             printf "%s=%.8f(x%.2f)" header val w::String) hd
     in intercalate ", " formatted
 
 -- | Convert a placement into a list of OpCodes (basically a job).
-- 
GitLab