00001
00002
00003
00004 #ifndef __CRUSH_WRAPPER_H
00005 #define __CRUSH_WRAPPER_H
00006
00007 #define BUG_ON(x) assert(!(x))
00008
00009
00010
00011 #include "crush.h"
00012 #include "hash.h"
00013 #include "mapper.h"
00014 #include "Builder.h"
00015
00016
00017 #include <stdlib.h>
00018 #include <map>
00019 #include <set>
00020 #include <string>
00021 #include <sstream>
00022 #include <iostream>
00023
00024 #define IS_ERR(n) n == -1
00025
00026 using namespace std;
00027
00028 class CrushWrapper {
00029 public:
00030 struct crush_map *crush;
00031 std::map<int, string> type_map;
00032 std::map<int, string> name_map;
00033 std::map<int, string> rule_name_map;
00034
00035
00036 bool have_rmaps;
00037 std::map<string, int> type_rmap, name_rmap, rule_name_rmap;
00038
00039 private:
00040 void build_rmaps() {
00041 if (have_rmaps) return;
00042 build_rmap(type_map, type_rmap);
00043 build_rmap(name_map, name_rmap);
00044 build_rmap(rule_name_map, rule_name_rmap);
00045 have_rmaps = true;
00046 }
00047 void build_rmap(map<int, string> &f, std::map<string, int> &r) {
00048 r.clear();
00049 for (std::map<int, string>::iterator p = f.begin(); p != f.end(); p++)
00050 r[p->second] = p->first;
00051 }
00052
00053 public:
00054 CrushWrapper() : crush(0), have_rmaps(false) {}
00055 ~CrushWrapper() {
00056 if (crush) {
00057 crush_destroy(crush);
00058 }
00059 }
00060
00061
00062 void create() {
00063 if (crush) crush_destroy(crush);
00064 crush = crush_create();
00065 }
00066
00067
00068 int get_num_type_names() {
00069 return type_map.size();
00070 }
00071 int get_type_id(const char *s) {
00072 string name(s);
00073 build_rmaps();
00074 if (type_rmap.count(name))
00075 return type_rmap[name];
00076 return 0;
00077 }
00078 const char *get_type_name(int t) {
00079 if (type_map.count(t))
00080 return type_map[t].c_str();
00081 return 0;
00082 }
00083 void set_type_name(int i, const char *n) {
00084 string name(n);
00085 type_map[i] = name;
00086 if (have_rmaps)
00087 type_rmap[name] = i;
00088 }
00089
00090
00091 int get_item_id(const char *s) {
00092 string name(s);
00093 build_rmaps();
00094 if (name_rmap.count(name))
00095 return name_rmap[name];
00096 return 0;
00097 }
00098 const char *get_item_name(int t) {
00099 if (name_map.count(t))
00100 return name_map[t].c_str();
00101 return 0;
00102 }
00103 void set_item_name(int i, const char *n) {
00104 string name(n);
00105 name_map[i] = name;
00106 if (have_rmaps)
00107 name_rmap[name] = i;
00108 }
00109
00110
00111 int get_rule_id(const char *n) {
00112 string name(n);
00113 build_rmaps();
00114 if (rule_name_rmap.count(name))
00115 return rule_name_rmap[name];
00116 return 0;
00117 }
00118 const char *get_rule_name(int t) {
00119 if (rule_name_map.count(t))
00120 return rule_name_map[t].c_str();
00121 return 0;
00122 }
00123 void set_rule_name(int i, const char *n) {
00124 string name(n);
00125 rule_name_map[i] = name;
00126 if (have_rmaps)
00127 rule_name_rmap[name] = i;
00128 }
00129
00130
00131 int get_max_devices() {
00132 if (!crush) return 0;
00133 return crush->max_devices;
00134 }
00135
00136
00137
00138 private:
00139
00140 crush_rule *get_rule(unsigned ruleno) {
00141 if (!crush) return (crush_rule *)(-1);
00142 if (ruleno >= crush->max_rules)
00143 return 0;
00144 return crush->rules[ruleno];
00145 }
00146 crush_rule_step *get_rule_step(unsigned ruleno, unsigned step) {
00147 crush_rule *n = get_rule(ruleno);
00148 if (!n) return (crush_rule_step *)(-1);
00149 if (step >= n->len) return (crush_rule_step *)(-1);
00150 return &n->steps[step];
00151 }
00152
00153 public:
00154
00155 int get_max_rules() {
00156 if (!crush) return 0;
00157 return crush->max_rules;
00158 }
00159 bool rule_exists(unsigned ruleno) {
00160 if (!crush) return false;
00161 if (ruleno < crush->max_rules &&
00162 crush->rules[ruleno] != NULL)
00163 return true;
00164 return false;
00165 }
00166
00167
00168
00169 int add_rule(int len, int pool, int type, int minsize, int maxsize, int ruleno) {
00170 if (!crush) return -1;
00171 crush_rule *n = crush_make_rule(len, pool, type, minsize, maxsize);
00172 ruleno = crush_add_rule(crush, n, ruleno);
00173 return ruleno;
00174 }
00175 int set_rule_step(unsigned ruleno, unsigned step, int op, int arg1, int arg2) {
00176 if (!crush) return -1;
00177 crush_rule *n = get_rule(ruleno);
00178 if (!n) return -1;
00179 crush_rule_set_step(n, step, op, arg1, arg2);
00180 return 0;
00181 }
00182 int set_rule_step_take(unsigned ruleno, unsigned step, int val) {
00183 return set_rule_step(ruleno, step, CRUSH_RULE_TAKE, val, 0);
00184 }
00185 int set_rule_step_choose_firstn(unsigned ruleno, unsigned step, int val, int type) {
00186 return set_rule_step(ruleno, step, CRUSH_RULE_CHOOSE_FIRSTN, val, type);
00187 }
00188 int set_rule_step_choose_indep(unsigned ruleno, unsigned step, int val, int type) {
00189 return set_rule_step(ruleno, step, CRUSH_RULE_CHOOSE_INDEP, val, type);
00190 }
00191 int set_rule_step_choose_leaf_firstn(unsigned ruleno, unsigned step, int val, int type) {
00192 return set_rule_step(ruleno, step, CRUSH_RULE_CHOOSE_LEAF_FIRSTN, val, type);
00193 }
00194 int set_rule_step_choose_leaf_indep(unsigned ruleno, unsigned step, int val, int type) {
00195 return set_rule_step(ruleno, step, CRUSH_RULE_CHOOSE_LEAF_INDEP, val, type);
00196 }
00197 int set_rule_step_emit(unsigned ruleno, unsigned step) {
00198 return set_rule_step(ruleno, step, CRUSH_RULE_EMIT, 0, 0);
00199 }
00200
00201
00202
00204 private:
00205 crush_bucket *get_bucket(int id) {
00206 if (!crush) return (crush_bucket *)(-1);
00207 int pos = -1 - id;
00208 if (pos >= crush->max_buckets) return 0;
00209 return crush->buckets[pos];
00210 }
00211
00212 public:
00213 int get_max_buckets() {
00214 if (!crush) return -1;
00215 return crush->max_buckets;
00216 }
00217 int get_next_bucket_id() {
00218 if (!crush) return -1;
00219 return crush_get_next_bucket_id(crush);
00220 }
00221
00222
00223 int add_bucket(int bucketno, int alg, int hash, int type, int size,
00224 int *items, int *weights) {
00225 crush_bucket *b = crush_make_bucket(alg, hash, type, size, items, weights);
00226 return crush_add_bucket(crush, bucketno, b);
00227 }
00228
00229 void finalize() {
00230 crush_finalize(crush);
00231 }
00232
00233 void set_max_devices(int m) {
00234 crush->max_devices = m;
00235 }
00236
00237 int find_rule(int pool, int type, int size) {
00238 if (!crush) return -1;
00239 return crush_find_rule(crush, pool, type, size);
00240 }
00241
00242 void do_rule(VDRIVE::Distributor *dist, int rule, int64_t x, vector<int>& out, int maxout, int forcefeed, vector<uint32_t>& weight) const {
00243 int rawout[maxout];
00244 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
00245
00246 pthread_mutex_lock(&mutex);
00247 int numrep = crush_do_rule(dist, crush, rule, x, rawout, maxout, forcefeed, &weight[0]);
00248 pthread_mutex_unlock(&mutex);
00249
00250 out.resize(numrep);
00251 for (int i=0; i<numrep; i++)
00252 out[i] = rawout[i];
00253 }
00254
00255
00256
00257
00258 };
00259
00260
00261 #endif