]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: chooseleaf
authorSage Weil <sage@newdream.net>
Wed, 17 Sep 2008 21:37:39 +0000 (14:37 -0700)
committerSage Weil <sage@newdream.net>
Wed, 17 Sep 2008 21:39:05 +0000 (14:39 -0700)
src/crush/CrushWrapper.h
src/crush/crush.h
src/crush/grammar.h
src/crush/mapper.c
src/crushtool.cc

index 7c4d3e80c249a363c666d5cd7a32f37dd971cdc0..ed82f67140fdf415e994a19973292e2a2b79870b 100644 (file)
@@ -241,6 +241,12 @@ public:
   int set_rule_step_choose_indep(unsigned ruleno, unsigned step, int val, int type) {
     return set_rule_step(ruleno, step, CRUSH_RULE_CHOOSE_INDEP, val, type);
   }
+  int set_rule_step_choose_leaf_firstn(unsigned ruleno, unsigned step, int val, int type) {
+    return set_rule_step(ruleno, step, CRUSH_RULE_CHOOSE_LEAF_FIRSTN, val, type);
+  }
+  int set_rule_step_choose_leaf_indep(unsigned ruleno, unsigned step, int val, int type) {
+    return set_rule_step(ruleno, step, CRUSH_RULE_CHOOSE_LEAF_INDEP, val, type);
+  }
   int set_rule_step_emit(unsigned ruleno, unsigned step) {
     return set_rule_step(ruleno, step, CRUSH_RULE_EMIT, 0, 0);
   }
index 4259a9bec4b3283c497eb7263d1d4ac8cec94891..8fd5f61839b859d28d4215726e2ea1736c296742 100644 (file)
@@ -21,8 +21,10 @@ enum {
        CRUSH_RULE_TAKE = 1,          /* arg1 = value to start with */
        CRUSH_RULE_CHOOSE_FIRSTN = 2, /* arg1 = num items to pick */
                                      /* arg2 = type */
-       CRUSH_RULE_CHOOSE_INDEP = 3,  /* same */ 
-       CRUSH_RULE_EMIT = 4           /* no args */
+       CRUSH_RULE_CHOOSE_INDEP = 3,  /* same */
+       CRUSH_RULE_EMIT = 4,          /* no args */
+       CRUSH_RULE_CHOOSE_LEAF_FIRSTN = 6,
+       CRUSH_RULE_CHOOSE_LEAF_INDEP = 7,
 };
 
 #define CRUSH_MAX_DEPTH 10
index a4c17d0752805719dd20c3b97faf83b6b09ef04f..090d0c75c8b4d8efea617c0b1624d805c92d1618 100644 (file)
@@ -101,9 +101,10 @@ struct crush_grammar : public grammar<crush_grammar>
       
       // rules
       step_take = str_p("take") >> str_p("root");
-      step_choose = str_p("choose") >> ( str_p("indep") | str_p("firstn") )
-                                   >> integer
-                                   >> str_p("type") >> name;
+      step_choose = (str_p("choose") | str_p("chooseleaf"))
+       >> ( str_p("indep") | str_p("firstn") )
+       >> integer
+       >> str_p("type") >> name;
       step_emit = str_p("emit");
       step = str_p("step") >> ( step_take | 
                                step_choose | 
index e3b0cbf1b01f8104371f7fab0d4f272dbf900ca9..b0a08549617b410905c9d7bd69ae37d8fee28298 100644 (file)
@@ -164,7 +164,9 @@ static int is_out(struct crush_map *map, int item, int x)
 static int crush_choose(struct crush_map *map,
                        struct crush_bucket *bucket,
                        int x, int numrep, int type,
-                       int *out, int outpos, int firstn)
+                       int *out, int outpos, 
+                       int firstn, int recurse_to_leaf,
+                       int *out2)
 {
        int rep;
        int ftotal, flocal;
@@ -251,6 +253,11 @@ static int crush_choose(struct crush_map *map,
                                        reject = is_out(map, item, x);
                                else 
                                        reject = 0;
+                               if (recurse_to_leaf &&
+                                   !crush_choose(map, bucket, x, 1, 0,
+                                                 out2+outpos, 0,
+                                                 firstn, 0, 0))
+                                       reject = 1;
                                
                                if (reject || collide) {
                                        ftotal++;
@@ -285,6 +292,8 @@ int crush_do_rule(struct crush_map *map,
        int force_pos = -1;
        int a[CRUSH_MAX_SET];
        int b[CRUSH_MAX_SET];
+       int c[CRUSH_MAX_SET];
+       int recurse_to_leaf;
        int *w;
        int wsize = 0;
        int *o;
@@ -335,11 +344,15 @@ int crush_do_rule(struct crush_map *map,
                        
                case CRUSH_RULE_CHOOSE_FIRSTN:
                case CRUSH_RULE_CHOOSE_INDEP:
+               case CRUSH_RULE_CHOOSE_LEAF_FIRSTN:
+               case CRUSH_RULE_CHOOSE_LEAF_INDEP:
                        BUG_ON(wsize == 0);
                        
                        /* reset output */
                        osize = 0;
                        
+                       recurse_to_leaf = rule->steps[step].op >=
+                               CRUSH_RULE_CHOOSE_LEAF_FIRSTN;
                        for (i = 0; i < wsize; i++) {
                                /*
                                 * see CRUSH_N, CRUSH_N_MINUS macros.
@@ -361,9 +374,14 @@ int crush_do_rule(struct crush_map *map,
                                osize += crush_choose(map,
                                                      map->buckets[-1-w[i]],
                                                      x, numrep, rule->steps[step].arg2,
-                                                     o+osize, j, rule->steps[step].op == CRUSH_RULE_CHOOSE_FIRSTN);
+                                                     o+osize, j, rule->steps[step].op == CRUSH_RULE_CHOOSE_FIRSTN,
+                                                     recurse_to_leaf, c+osize);
                        }
-                       
+
+                       if (recurse_to_leaf)
+                               /* copy final _leaf_ values to output set */
+                               memcpy(o, c, osize*sizeof(*o));
+
                        /* swap t and w arrays */
                        tmp = o;
                        o = w;
index e4e116f5389810f65aab9e101daad0b6d8247099..fca974d3370cbf4c2e9b9b472e7708740eed0b2e 100644 (file)
@@ -298,13 +298,21 @@ void parse_rule(iter_t const& i, CrushWrapper &crush)
          cerr << "in rule '" << rname << "' type '" << type << "' not defined" << std::endl;
          exit(1);
        }
+       string choose = string_node(s->children[0]);
        string mode = string_node(s->children[1]);
-       if (mode == "firstn")
-         crush.set_rule_step_choose_firstn(ruleno, step++, int_node(s->children[2]), type_id[type]);
-       else if (mode == "indep")
-         crush.set_rule_step_choose_indep(ruleno, step++, int_node(s->children[2]), type_id[type]);
-       else 
-         assert(0);
+       if (choose == "choose") {
+         if (mode == "firstn")
+           crush.set_rule_step_choose_firstn(ruleno, step++, int_node(s->children[2]), type_id[type]);
+         else if (mode == "indep")
+           crush.set_rule_step_choose_indep(ruleno, step++, int_node(s->children[2]), type_id[type]);
+         else assert(0);
+       } else if (choose == "chooseleaf") {
+         if (mode == "firstn") 
+           crush.set_rule_step_choose_leaf_firstn(ruleno, step++, int_node(s->children[2]), type_id[type]);
+         else if (mode == "indep")
+           crush.set_rule_step_choose_leaf_indep(ruleno, step++, int_node(s->children[2]), type_id[type]);
+         else assert(0);
+       } else assert(0);
       }
       break;