]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crush/CrushWrapper: refactor get_rule_weight_osd_map to work with roots too
authorSage Weil <sage@redhat.com>
Sun, 23 Jul 2017 03:50:27 +0000 (23:50 -0400)
committerJohn Spray <john.spray@redhat.com>
Wed, 1 Nov 2017 23:03:22 +0000 (23:03 +0000)
Allow us to specify a root node in the hierarchy instead of a rule.
This way we can use it in conjunction with find_takes().

Signed-off-by: Sage Weil <sage@redhat.com>
(cherry picked from commit 69454e0570274ff7f252e7f081965dcc9bb04459)

src/crush/CrushWrapper.cc
src/crush/CrushWrapper.h

index f646a2de09927b5cd2bd8fc4b756bc241eb34fb3..52af91f6f47d1f9c9815dd3f112b659c9878a8aa 100644 (file)
@@ -1593,7 +1593,56 @@ int CrushWrapper::add_simple_rule(
                            rule_type, -1, err);
 }
 
-int CrushWrapper::get_rule_weight_osd_map(unsigned ruleno, map<int,float> *pmap)
+float CrushWrapper::_get_take_weight_osd_map(int root,
+                                            map<int,float> *pmap) const
+{
+  float sum = 0.0;
+  list<int> q;
+  q.push_back(root);
+  //breadth first iterate the OSD tree
+  while (!q.empty()) {
+    int bno = q.front();
+    q.pop_front();
+    crush_bucket *b = crush->buckets[-1-bno];
+    assert(b);
+    for (unsigned j=0; j<b->size; ++j) {
+      int item_id = b->items[j];
+      if (item_id >= 0) { //it's an OSD
+       float w = crush_get_bucket_item_weight(b, j);
+       (*pmap)[item_id] = w;
+       sum += w;
+      } else { //not an OSD, expand the child later
+       q.push_back(item_id);
+      }
+    }
+  }
+  return sum;
+}
+
+void CrushWrapper::_normalize_weight_map(float sum,
+                                        const map<int,float>& m,
+                                        map<int,float> *pmap) const
+{
+  for (auto& p : m) {
+    map<int,float>::iterator q = pmap->find(p.first);
+    if (q == pmap->end()) {
+      (*pmap)[p.first] = p.second / sum;
+    } else {
+      q->second += p.second / sum;
+    }
+  }
+}
+
+int CrushWrapper::get_take_weight_osd_map(int root, map<int,float> *pmap) const
+{
+  map<int,float> m;
+  float sum = _get_take_weight_osd_map(root, &m);
+  _normalize_weight_map(sum, m, pmap);
+  return 0;
+}
+
+int CrushWrapper::get_rule_weight_osd_map(unsigned ruleno,
+                                         map<int,float> *pmap) const
 {
   if (ruleno >= crush->max_rules)
     return -ENOENT;
@@ -1616,35 +1665,10 @@ int CrushWrapper::get_rule_weight_osd_map(unsigned ruleno, map<int,float> *pmap)
        m[n] = 1.0;
        sum = 1.0;
       } else {
-       list<int> q;
-       q.push_back(n);
-       //breadth first iterate the OSD tree
-       while (!q.empty()) {
-         int bno = q.front();
-         q.pop_front();
-         crush_bucket *b = crush->buckets[-1-bno];
-         assert(b);
-         for (unsigned j=0; j<b->size; ++j) {
-           int item_id = b->items[j];
-           if (item_id >= 0) { //it's an OSD
-             float w = crush_get_bucket_item_weight(b, j);
-             m[item_id] = w;
-             sum += w;
-           } else { //not an OSD, expand the child later
-             q.push_back(item_id);
-           }
-         }
-       }
-      }
-    }
-    for (map<int,float>::iterator p = m.begin(); p != m.end(); ++p) {
-      map<int,float>::iterator q = pmap->find(p->first);
-      if (q == pmap->end()) {
-       (*pmap)[p->first] = p->second / sum;
-      } else {
-       q->second += p->second / sum;
+       sum += _get_take_weight_osd_map(n, &m);
       }
     }
+    _normalize_weight_map(sum, m, pmap);
   }
 
   return 0;
index 034cf1e9f3b65c51675c89d87e02729560d7be8b..00773779471552330734a347a2a9d64c059be1dd 100644 (file)
@@ -1025,6 +1025,12 @@ public:
     return s->arg2;
   }
 
+private:
+  float _get_take_weight_osd_map(int root, map<int,float> *pmap) const;
+  void _normalize_weight_map(float sum, const map<int,float>& m,
+                            map<int,float> *pmap) const;
+
+public:
   /**
    * calculate a map of osds to weights for a given rule
    *
@@ -1035,7 +1041,19 @@ public:
    * @param pmap [out] map of osd to weight
    * @return 0 for success, or negative error code
    */
-  int get_rule_weight_osd_map(unsigned ruleno, map<int,float> *pmap);
+  int get_rule_weight_osd_map(unsigned ruleno, map<int,float> *pmap) const;
+
+  /**
+   * calculate a map of osds to weights for a given starting root
+   *
+   * Generate a map of which OSDs get how much relative weight for a
+   * given starting root
+   *
+   * @param root node
+   * @param pmap [out] map of osd to weight
+   * @return 0 for success, or negative error code
+   */
+  int get_take_weight_osd_map(int root, map<int,float> *pmap) const;
 
   /* modifiers */