]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
tested each bucket type, fixed many bugs
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 18 Oct 2007 18:56:49 +0000 (18:56 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 18 Oct 2007 18:56:49 +0000 (18:56 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1968 29311d96-e01e-0410-9327-a35deaab8ce9

branches/sage/crush/crush/Makefile
branches/sage/crush/crush/builder.c
branches/sage/crush/crush/builder.h
branches/sage/crush/crush/crush.h
branches/sage/crush/crush/mapper.c

index 06ea3ab3019bf5dd8b43d535068265b646152995..b5deb36dc20198f7f4e35d6d6645d463d29e4f55 100644 (file)
@@ -6,7 +6,7 @@ CFLAGS += -g
 LD = ld
 RM = rm
 
-all: depend libcrush.o
+all: depend libcrush.o test
 
 clean:
        rm -f *.o libcrush.o
@@ -17,6 +17,9 @@ clean:
 libcrush.o: builder.o crush.o mapper.o
        $(LD) -i -o $@ $^
 
+test: test.c libcrush.o
+       $(CC) ${CFLAGS} -lm $^ -o $@
+
 .depend:
        touch .depend
 
index 6bd9f3bc3c1703f7250e0815776c2ba26c2470db..6e2021fcfdfd0f03e47bb77051e953522bd8e49f 100644 (file)
@@ -2,6 +2,7 @@
 #include <string.h>
 #include <math.h>
 #include <stdlib.h>
+#include <stdio.h>
 
 #include "builder.h"
 #include "hash.h"
@@ -135,6 +136,8 @@ int crush_add_bucket(struct crush_map *map,
 }
 
 
+/* uniform bucket */
+
 struct crush_bucket_uniform *
 crush_make_uniform_bucket(int type, int size,
                          int *items,
@@ -175,6 +178,9 @@ crush_make_uniform_bucket(int type, int size,
        return bucket;
 }
 
+
+/* list bucket */
+
 struct crush_bucket_list*
 crush_make_list_bucket(int type, int size,
                       int *items,
@@ -194,11 +200,13 @@ crush_make_list_bucket(int type, int size,
        bucket->item_weights = malloc(sizeof(__u32)*size);
        bucket->sum_weights = malloc(sizeof(__u32)*size);
        w = 0;
-       for (i=0; i<size; i++) {
+       for (i=size-1; i>=0; i--) {
                bucket->h.items[i] = items[i];
                bucket->item_weights[i] = weights[i];
                w += weights[i];
                bucket->sum_weights[i] = w;
+               printf("%d item %d weight %d sum %d\n",
+                      i, items[i], weights[i], bucket->sum_weights[i]);
        }
        
        bucket->h.weight = w;
@@ -206,6 +214,9 @@ crush_make_list_bucket(int type, int size,
        return bucket;
 }
 
+
+/* tree bucket */
+
 static int height(int n) {
        int h = 0;
        while ((n & 1) == 0) {
@@ -259,7 +270,7 @@ crush_make_tree_bucket(int type, int size,
        
        for (i=0; i<size; i++) {
                node = ((i+1) << 1)-1;
-               bucket->h.items[i] = items[i];
+               bucket->h.items[node] = items[i];
                bucket->node_weights[node] = weights[i];
                bucket->h.weight += weights[i];
                for (j=1; j<depth; j++) {
@@ -273,6 +284,8 @@ crush_make_tree_bucket(int type, int size,
 }
 
 
+/* straw bucket */
+
 struct crush_bucket_straw *
 crush_make_straw_bucket(int type, 
                        int size,
@@ -301,20 +314,21 @@ crush_make_straw_bucket(int type,
                bucket->h.weight += weights[i];
        }
        
-       /* reverse sort by weight */
+       /* reverse sort by weight (simple insertion sort) */
        reverse = malloc(sizeof(int) * size);
-       reverse[0] = items[0];
+       reverse[0] = 0;
        for (i=1; i<size; i++) {
                for (j=0; j<i; j++) {
                        if (weights[i] < weights[reverse[j]]) {
                                /* insert here */
                                for (k=i; k>j; k--)
                                        reverse[k] = reverse[k-1];
-                               reverse[j] = items[i];
+                               reverse[j] = i;
+                               break;
                        }
                }
                if (j == i)
-                       reverse[i] = items[i];
+                       reverse[i] = i;
        }
        
        numleft = size;
@@ -326,20 +340,30 @@ crush_make_straw_bucket(int type,
        while (i < size) {
                /* set this item's straw */
                bucket->straws[reverse[i]] = straw * 0x10000;
+               printf("item %d at %d weight %d straw %d (%lf)\n", 
+                      items[reverse[i]],
+                      reverse[i], weights[reverse[i]], bucket->straws[reverse[i]], straw);
                i++;
                if (i == size) break;
                
                /* same weight as previous? */
-               if (weights[reverse[i]] == weights[reverse[i-1]]) 
+               if (weights[reverse[i]] == weights[reverse[i-1]]) {
+                       printf("same as previous\n");
                        continue;
+               }
                
                /* adjust straw for next guy */
-               wbelow += (((double)weights[reverse[i-1]] / (double)0x10000) - lastw) * numleft;
-               numleft--;
-               wnext = numleft * ((double)(weights[reverse[i]] - weights[reverse[i-1]]) / (double)0x10000);
+               wbelow += ((double)weights[reverse[i-1]] - lastw) * numleft;
+               for (j=i; j<size; j++)
+                       if (weights[reverse[j]] == weights[reverse[i]])
+                               numleft--;
+                       else
+                               break;
+               wnext = numleft * (weights[reverse[i]] - weights[reverse[i-1]]);
                pbelow = wbelow / (wbelow + wnext);
+               printf("wbelow %lf  wnext %lf  pbelow %lf\n", wbelow, wnext, pbelow);
                
-               straw *= pow((double)1.0 / pbelow, (double)1.0 / numleft);
+               straw *= pow((double)1.0 / pbelow, (double)1.0 / (double)numleft);
                
                lastw = weights[reverse[i-1]];
        }
index b2d217c531bfd65c6eab77fdbb27dc4940685d0d..a324e3fe92a5059ad2c21e12ee39b316d67d7b33 100644 (file)
@@ -11,10 +11,10 @@ extern struct crush_map *crush_create();
 extern void crush_finalize(struct crush_map *map);
 
 /* rules */
+extern struct crush_rule *crush_make_rule();
 extern int crush_add_rule(struct crush_map *map,
                          int ruleno,
                          struct crush_rule *rule);
-extern struct crush_rule *crush_make_rule();
 extern void crush_rule_add_step(struct crush_rule *rule, int op, int arg1, int arg2);
 
 /* buckets */
index 157da879648b23208e6ea7f945febd6cdf0f0d3d..5cf6cff498f131d3f60cacf1d0d18e6e2813e9c2 100644 (file)
@@ -98,7 +98,7 @@ struct crush_map {
        
        __u32 max_buckets;
        __u32 max_rules;
-       __u32 max_devices;
+       __s32 max_devices;
 };
 
 
index 1d3cfd1d43d4268ed59ec9e830eb02123bc72ebd..37e8c6259f5c0d119ccc787ca5d379d3ee04f145 100644 (file)
@@ -3,20 +3,26 @@
 #include "hash.h"
 
 #include <string.h>
+#include <stdio.h>
 
 /** bucket choose methods **/
 
+/* uniform */
 
 static int 
 crush_bucket_uniform_choose(struct crush_bucket_uniform *bucket, int x, int r)
 {
        unsigned o, p, s;
-       o = crush_hash32_2(x, bucket->h.id);
+       o = crush_hash32_2(x, bucket->h.id) & 0xffff;
        p = bucket->primes[crush_hash32_2(bucket->h.id, x) % bucket->h.size];
        s = (x + o + (r+1)*p) % bucket->h.size;
+       /*printf("%d %d %d %d\n", x, o, r, p);*/
        return bucket->h.items[s];
 }
 
+
+/* list */
+
 static int 
 crush_bucket_list_choose(struct crush_bucket_list *bucket, int x, int r)
 {
@@ -24,8 +30,13 @@ crush_bucket_list_choose(struct crush_bucket_list *bucket, int x, int r)
        __u64 w;
        
        for (i=0; i<bucket->h.size; i++) {
-               w = crush_hash32_4(x, bucket->h.items[i], r, bucket->h.id) & 0xffff;
-               w = (w * bucket->sum_weights[i]) >> 32;
+               w = crush_hash32_4(x, bucket->h.items[i], r, bucket->h.id);
+               w &= 0xffff;
+               /*printf("%d item %d weight %d sum_weight %d r %lld", 
+                 i, bucket->h.items[i], bucket->item_weights[i], bucket->sum_weights[i], w);*/
+               w *= bucket->sum_weights[i];
+               w = w >> 16;
+               /*printf(" scaled %lld\n", w);*/
                if (w < bucket->item_weights[i])
                        return bucket->h.items[i];
        }
@@ -35,6 +46,8 @@ crush_bucket_list_choose(struct crush_bucket_list *bucket, int x, int r)
 }
 
 
+/* tree */
+
 static int height(int n) {
        int h = 0;
        while ((n & 1) == 0) {
@@ -82,24 +95,28 @@ crush_bucket_tree_choose(struct crush_bucket_tree *bucket, int x, int r)
        return bucket->h.items[n];
 }
 
+
+/* straw */
+
 static int 
 crush_bucket_straw_choose(struct crush_bucket_straw *bucket, int x, int r)
 {
        int i;
        int high = 0;
-       unsigned high_draw = 0;
+       __u64 high_draw = 0;
        __u64 draw;
        
        for (i=0; i<bucket->h.size; i++) {
-               draw = (crush_hash32_3(x, bucket->h.items[i], r) & 0xffff) * bucket->straws[i];
-               draw = draw >> 32;
+               draw = crush_hash32_3(x, bucket->h.items[i], r);
+               draw &= 0xffff;
+               draw *= bucket->straws[i];
                if (i == 0 || draw > high_draw) {
                        high = i;
                        high_draw = draw;
                }
        }
        
-       return high;
+       return bucket->h.items[high];
 }
 
 
@@ -139,7 +156,7 @@ static int crush_choose(struct crush_map *map,
                        flocal = 0;
                        do {
                                r = rep;
-                               if (in->type == CRUSH_BUCKET_UNIFORM) {
+                               if (in->bucket_type == CRUSH_BUCKET_UNIFORM) {
                                        /* be careful */
                                        if (firstn || numrep >= in->size) {
                                                r += ftotal;           /* r' = r + f_total */
@@ -158,7 +175,7 @@ static int crush_choose(struct crush_map *map,
                                }
 
                                /* bucket choose */
-                               switch (in->type) {
+                               switch (in->bucket_type) {
                                case CRUSH_BUCKET_UNIFORM:
                                        item = crush_bucket_uniform_choose((struct crush_bucket_uniform*)in, x, r);
                                        break;
@@ -183,6 +200,7 @@ static int crush_choose(struct crush_map *map,
                                
                                /* keep going? */
                                if (itemtype != type) {
+                                       BUG_ON((-1-item) >= map->max_buckets);
                                        in = map->buckets[-1-item];
                                        continue;
                                }