return rno;
}
+int CrushWrapper::get_rule_weight_map(unsigned ruleno, map<int,float> *pmap)
+{
+ if (ruleno >= crush->max_rules)
+ return -ENOENT;
+ if (crush->rules[ruleno] == NULL)
+ return -ENOENT;
+ crush_rule *rule = crush->rules[ruleno];
+
+ // build a weight map for each TAKE in the rule, and then merge them
+ for (unsigned i=0; i<rule->len; ++i) {
+ map<int,float> m;
+ float sum = 0;
+ if (rule->steps[i].op == CRUSH_RULE_TAKE) {
+ int n = rule->steps[i].arg1;
+ if (n >= 0) {
+ m[n] = 1.0;
+ sum = 1.0;
+ } else {
+ list<int> q;
+ q.push_back(n);
+ 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) {
+ float w = crush_get_bucket_item_weight(b, j);
+ m[b->items[j]] = w;
+ sum += w;
+ }
+ }
+ }
+ }
+ 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;
+ }
+ }
+ }
+
+ return 0;
+}
+
int CrushWrapper::remove_rule(int ruleno)
{
if (ruleno >= (int)crush->max_rules)
return s->arg2;
}
+ /**
+ * calculate a map of osds to weights for a given rule
+ *
+ * Generate a map of which OSDs get how much relative weight for a
+ * given rule.
+ *
+ * @param ruleno [in] rule id
+ * @param pmap [out] map of osd to weight
+ * @return 0 for success, or negative error code
+ */
+ int get_rule_weight_map(unsigned ruleno, map<int,float> *pmap);
+
/* modifiers */
int add_rule(int len, int ruleset, int type, int minsize, int maxsize, int ruleno) {
if (!crush) return -ENOENT;
ss.str().find("<item_name>default</item_name></step>"));
}
+ map<int,float> wm;
+ c->get_rule_weight_map(0, &wm);
+ ASSERT_TRUE(wm.size() == 1);
+ ASSERT_TRUE(wm[0] == 1.0);
+
delete c;
}