• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

crushwrapper.h

Go to the documentation of this file.
00001 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
00002 // vim: ts=8 sw=2 smarttab
00003 
00004 #ifndef __CRUSH_WRAPPER_H
00005 #define __CRUSH_WRAPPER_H
00006 
00007 #define BUG_ON(x) assert(!(x))
00008 
00009 
00010 //extern "C" {
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> //for testing, remove
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; /* bucket/device type names */
00032   std::map<int, string> name_map; /* bucket/device names */
00033   std::map<int, string> rule_name_map;
00034 
00035   /* reverse maps */
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   /* building */
00062   void create() {
00063     if (crush) crush_destroy(crush);
00064     crush = crush_create();
00065   }
00066 
00067   // bucket types
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   // item/bucket names
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;  /* hrm */
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   // rule names
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;  /* hrm */
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   /*** devices ***/
00131   int get_max_devices() {
00132     if (!crush) return 0;
00133     return crush->max_devices;
00134   }
00135 
00136 
00137   /*** rules ***/
00138 private:
00139   //VDRIVE::Distributor *dist;
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   /* accessors */
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   /* modifiers */
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   /* modifiers */
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

Generated on Mon Oct 11 2010 13:09:26 for CppDistributors by  doxygen 1.7.2