From: Sage Weil Date: Sun, 19 Feb 2012 20:08:11 +0000 (-0800) Subject: crush: uninline encode/decode X-Git-Tag: v0.43~46^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4dd8c3542a066504e9f1902e9b0eb38dcc864038;p=ceph.git crush: uninline encode/decode Signed-off-by: Sage Weil --- diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index c979ab55760..60e78e51239 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -159,3 +159,230 @@ void CrushWrapper::reweight(CephContext *cct) crush_reweight_bucket(crush, b); } } + +void CrushWrapper::encode(bufferlist& bl, bool lean) const +{ + assert(crush); + + __u32 magic = CRUSH_MAGIC; + ::encode(magic, bl); + + ::encode(crush->max_buckets, bl); + ::encode(crush->max_rules, bl); + ::encode(crush->max_devices, bl); + + // buckets + for (int i=0; imax_buckets; i++) { + __u32 alg = 0; + if (crush->buckets[i]) alg = crush->buckets[i]->alg; + ::encode(alg, bl); + if (!alg) + continue; + + ::encode(crush->buckets[i]->id, bl); + ::encode(crush->buckets[i]->type, bl); + ::encode(crush->buckets[i]->alg, bl); + ::encode(crush->buckets[i]->hash, bl); + ::encode(crush->buckets[i]->weight, bl); + ::encode(crush->buckets[i]->size, bl); + for (unsigned j=0; jbuckets[i]->size; j++) + ::encode(crush->buckets[i]->items[j], bl); + + switch (crush->buckets[i]->alg) { + case CRUSH_BUCKET_UNIFORM: + ::encode(((crush_bucket_uniform*)crush->buckets[i])->item_weight, bl); + break; + + case CRUSH_BUCKET_LIST: + for (unsigned j=0; jbuckets[i]->size; j++) { + ::encode(((crush_bucket_list*)crush->buckets[i])->item_weights[j], bl); + ::encode(((crush_bucket_list*)crush->buckets[i])->sum_weights[j], bl); + } + break; + + case CRUSH_BUCKET_TREE: + ::encode(((crush_bucket_tree*)crush->buckets[i])->num_nodes, bl); + for (unsigned j=0; j<((crush_bucket_tree*)crush->buckets[i])->num_nodes; j++) + ::encode(((crush_bucket_tree*)crush->buckets[i])->node_weights[j], bl); + break; + + case CRUSH_BUCKET_STRAW: + for (unsigned j=0; jbuckets[i]->size; j++) { + ::encode(((crush_bucket_straw*)crush->buckets[i])->item_weights[j], bl); + ::encode(((crush_bucket_straw*)crush->buckets[i])->straws[j], bl); + } + break; + + default: + assert(0); + break; + } + } + + // rules + for (unsigned i=0; imax_rules; i++) { + __u32 yes = crush->rules[i] ? 1:0; + ::encode(yes, bl); + if (!yes) + continue; + + ::encode(crush->rules[i]->len, bl); + ::encode(crush->rules[i]->mask, bl); + for (unsigned j=0; jrules[i]->len; j++) + ::encode(crush->rules[i]->steps[j], bl); + } + + // name info + ::encode(type_map, bl); + ::encode(name_map, bl); + ::encode(rule_name_map, bl); +} + +void CrushWrapper::decode(bufferlist::iterator& blp) +{ + create(); + + __u32 magic; + ::decode(magic, blp); + if (magic != CRUSH_MAGIC) + throw buffer::malformed_input("bad magic number"); + + ::decode(crush->max_buckets, blp); + ::decode(crush->max_rules, blp); + ::decode(crush->max_devices, blp); + + try { + // buckets + crush->buckets = (crush_bucket**)calloc(1, crush->max_buckets * sizeof(crush_bucket*)); + for (int i=0; imax_buckets; i++) { + decode_crush_bucket(&crush->buckets[i], blp); + } + + // rules + crush->rules = (crush_rule**)calloc(1, crush->max_rules * sizeof(crush_rule*)); + for (unsigned i = 0; i < crush->max_rules; ++i) { + __u32 yes; + ::decode(yes, blp); + if (!yes) { + crush->rules[i] = NULL; + continue; + } + + __u32 len; + ::decode(len, blp); + crush->rules[i] = (crush_rule*)calloc(1, crush_rule_size(len)); + crush->rules[i]->len = len; + ::decode(crush->rules[i]->mask, blp); + for (unsigned j=0; jrules[i]->len; j++) + ::decode(crush->rules[i]->steps[j], blp); + } + + // name info + ::decode(type_map, blp); + ::decode(name_map, blp); + ::decode(rule_name_map, blp); + build_rmaps(); + + finalize(); + } + catch (...) { + crush_destroy(crush); + throw; + } +} + +void CrushWrapper::decode_crush_bucket(crush_bucket** bptr, bufferlist::iterator &blp) +{ + __u32 alg; + ::decode(alg, blp); + if (!alg) { + *bptr = NULL; + return; + } + + int size = 0; + switch (alg) { + case CRUSH_BUCKET_UNIFORM: + size = sizeof(crush_bucket_uniform); + break; + case CRUSH_BUCKET_LIST: + size = sizeof(crush_bucket_list); + break; + case CRUSH_BUCKET_TREE: + size = sizeof(crush_bucket_tree); + break; + case CRUSH_BUCKET_STRAW: + size = sizeof(crush_bucket_straw); + break; + default: + { + char str[128]; + snprintf(str, sizeof(str), "unsupported bucket algorithm: %d", alg); + throw buffer::malformed_input(str); + } + } + crush_bucket *bucket = (crush_bucket*)calloc(1, size); + *bptr = bucket; + + ::decode(bucket->id, blp); + ::decode(bucket->type, blp); + ::decode(bucket->alg, blp); + ::decode(bucket->hash, blp); + ::decode(bucket->weight, blp); + ::decode(bucket->size, blp); + + bucket->items = (__s32*)calloc(1, bucket->size * sizeof(__s32)); + for (unsigned j = 0; j < bucket->size; ++j) { + ::decode(bucket->items[j], blp); + } + + bucket->perm = (__u32*)calloc(1, bucket->size * sizeof(__s32)); + bucket->perm_n = 0; + + switch (bucket->alg) { + case CRUSH_BUCKET_UNIFORM: + ::decode(((crush_bucket_uniform*)bucket)->item_weight, blp); + break; + + case CRUSH_BUCKET_LIST: { + crush_bucket_list* cbl = (crush_bucket_list*)bucket; + cbl->item_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32)); + cbl->sum_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32)); + + for (unsigned j = 0; j < bucket->size; ++j) { + ::decode(cbl->item_weights[j], blp); + ::decode(cbl->sum_weights[j], blp); + } + break; + } + + case CRUSH_BUCKET_TREE: { + crush_bucket_tree* cbt = (crush_bucket_tree*)bucket; + ::decode(cbt->num_nodes, blp); + cbt->node_weights = (__u32*)calloc(1, cbt->num_nodes * sizeof(__u32)); + for (unsigned j=0; jnum_nodes; j++) { + ::decode(cbt->node_weights[j], blp); + } + break; + } + + case CRUSH_BUCKET_STRAW: { + crush_bucket_straw* cbs = (crush_bucket_straw*)bucket; + cbs->straws = (__u32*)calloc(1, bucket->size * sizeof(__u32)); + cbs->item_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32)); + for (unsigned j = 0; j < bucket->size; ++j) { + ::decode(cbs->item_weights[j], blp); + ::decode(cbs->straws[j], blp); + } + break; + } + + default: + // We should have handled this case in the first switch statement + assert(0); + break; + } +} + + + diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index df62b8abcc9..e495815dca2 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -411,225 +411,9 @@ public: return bl.write_file(fn); } - void encode(bufferlist &bl, bool lean=false) const { - assert(crush); - - __u32 magic = CRUSH_MAGIC; - ::encode(magic, bl); - - ::encode(crush->max_buckets, bl); - ::encode(crush->max_rules, bl); - ::encode(crush->max_devices, bl); - - // buckets - for (int i=0; imax_buckets; i++) { - __u32 alg = 0; - if (crush->buckets[i]) alg = crush->buckets[i]->alg; - ::encode(alg, bl); - if (!alg) continue; - - ::encode(crush->buckets[i]->id, bl); - ::encode(crush->buckets[i]->type, bl); - ::encode(crush->buckets[i]->alg, bl); - ::encode(crush->buckets[i]->hash, bl); - ::encode(crush->buckets[i]->weight, bl); - ::encode(crush->buckets[i]->size, bl); - for (unsigned j=0; jbuckets[i]->size; j++) - ::encode(crush->buckets[i]->items[j], bl); - - switch (crush->buckets[i]->alg) { - case CRUSH_BUCKET_UNIFORM: - ::encode(((crush_bucket_uniform*)crush->buckets[i])->item_weight, bl); - break; - - case CRUSH_BUCKET_LIST: - for (unsigned j=0; jbuckets[i]->size; j++) { - ::encode(((crush_bucket_list*)crush->buckets[i])->item_weights[j], bl); - ::encode(((crush_bucket_list*)crush->buckets[i])->sum_weights[j], bl); - } - break; - - case CRUSH_BUCKET_TREE: - ::encode(((crush_bucket_tree*)crush->buckets[i])->num_nodes, bl); - for (unsigned j=0; j<((crush_bucket_tree*)crush->buckets[i])->num_nodes; j++) - ::encode(((crush_bucket_tree*)crush->buckets[i])->node_weights[j], bl); - break; - - case CRUSH_BUCKET_STRAW: - for (unsigned j=0; jbuckets[i]->size; j++) { - ::encode(((crush_bucket_straw*)crush->buckets[i])->item_weights[j], bl); - ::encode(((crush_bucket_straw*)crush->buckets[i])->straws[j], bl); - } - break; - default: - assert(0); - break; - } - } - - // rules - for (unsigned i=0; imax_rules; i++) { - __u32 yes = crush->rules[i] ? 1:0; - ::encode(yes, bl); - if (!yes) continue; - - ::encode(crush->rules[i]->len, bl); - ::encode(crush->rules[i]->mask, bl); - for (unsigned j=0; jrules[i]->len; j++) - ::encode(crush->rules[i]->steps[j], bl); - } - - // name info - ::encode(type_map, bl); - ::encode(name_map, bl); - ::encode(rule_name_map, bl); - } - - void decode(bufferlist::iterator &blp) - { - create(); - - __u32 magic; - ::decode(magic, blp); - if (magic != CRUSH_MAGIC) - throw buffer::malformed_input("bad magic number"); - - ::decode(crush->max_buckets, blp); - ::decode(crush->max_rules, blp); - ::decode(crush->max_devices, blp); - - try { - // buckets - crush->buckets = (crush_bucket**)calloc(1, crush->max_buckets * sizeof(crush_bucket*)); - for (int i=0; imax_buckets; i++) { - decode_crush_bucket(&crush->buckets[i], blp); - } - - // rules - crush->rules = (crush_rule**)calloc(1, crush->max_rules * sizeof(crush_rule*)); - for (unsigned i = 0; i < crush->max_rules; ++i) { - __u32 yes; - ::decode(yes, blp); - if (!yes) { - crush->rules[i] = NULL; - continue; - } - - __u32 len; - ::decode(len, blp); - crush->rules[i] = (crush_rule*)calloc(1, crush_rule_size(len)); - crush->rules[i]->len = len; - ::decode(crush->rules[i]->mask, blp); - for (unsigned j=0; jrules[i]->len; j++) - ::decode(crush->rules[i]->steps[j], blp); - } - - // name info - ::decode(type_map, blp); - ::decode(name_map, blp); - ::decode(rule_name_map, blp); - build_rmaps(); - - finalize(); - } - catch (...) { - crush_destroy(crush); - throw; - } - } - - void decode_crush_bucket(crush_bucket** bptr, bufferlist::iterator &blp) - { - __u32 alg; - ::decode(alg, blp); - if (!alg) { - *bptr = NULL; - return; - } - - int size = 0; - switch (alg) { - case CRUSH_BUCKET_UNIFORM: - size = sizeof(crush_bucket_uniform); - break; - case CRUSH_BUCKET_LIST: - size = sizeof(crush_bucket_list); - break; - case CRUSH_BUCKET_TREE: - size = sizeof(crush_bucket_tree); - break; - case CRUSH_BUCKET_STRAW: - size = sizeof(crush_bucket_straw); - break; - default: { - char str[128]; - snprintf(str, sizeof(str), "unsupported bucket algorithm: %d", alg); - throw buffer::malformed_input(str); - } - } - crush_bucket *bucket = (crush_bucket*)calloc(1, size); - *bptr = bucket; - - ::decode(bucket->id, blp); - ::decode(bucket->type, blp); - ::decode(bucket->alg, blp); - ::decode(bucket->hash, blp); - ::decode(bucket->weight, blp); - ::decode(bucket->size, blp); - - bucket->items = (__s32*)calloc(1, bucket->size * sizeof(__s32)); - for (unsigned j = 0; j < bucket->size; ++j) { - ::decode(bucket->items[j], blp); - } - - bucket->perm = (__u32*)calloc(1, bucket->size * sizeof(__s32)); - bucket->perm_n = 0; - - switch (bucket->alg) { - case CRUSH_BUCKET_UNIFORM: { - ::decode(((crush_bucket_uniform*)bucket)->item_weight, blp); - break; - } - - case CRUSH_BUCKET_LIST: { - crush_bucket_list* cbl = (crush_bucket_list*)bucket; - cbl->item_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32)); - cbl->sum_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32)); - - for (unsigned j = 0; j < bucket->size; ++j) { - ::decode(cbl->item_weights[j], blp); - ::decode(cbl->sum_weights[j], blp); - } - break; - } - - case CRUSH_BUCKET_TREE: { - crush_bucket_tree* cbt = (crush_bucket_tree*)bucket; - ::decode(cbt->num_nodes, blp); - cbt->node_weights = (__u32*)calloc(1, cbt->num_nodes * sizeof(__u32)); - for (unsigned j=0; jnum_nodes; j++) { - ::decode(cbt->node_weights[j], blp); - } - break; - } - - case CRUSH_BUCKET_STRAW: { - crush_bucket_straw* cbs = (crush_bucket_straw*)bucket; - cbs->straws = (__u32*)calloc(1, bucket->size * sizeof(__u32)); - cbs->item_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32)); - for (unsigned j = 0; j < bucket->size; ++j) { - ::decode(cbs->item_weights[j], blp); - ::decode(cbs->straws[j], blp); - } - break; - } - - default: - // We should have handled this case in the first switch statement - assert(0); - break; - } - } + void encode(bufferlist &bl, bool lean=false) const; + void decode(bufferlist::iterator &blp); + void decode_crush_bucket(crush_bucket** bptr, bufferlist::iterator &blp); }; WRITE_CLASS_ENCODER(CrushWrapper)