int mclDagTest ( const mclMatrix* dag ) { mclv* v_transient = mclvCopy(NULL, dag->dom_cols) ; mclx* m_transient = NULL ; int maxdepth = 0 ; dim d ; mclvMakeCharacteristic(v_transient) ; for (d=0;d<N_COLS(dag);d++) { mclv* col = dag->cols+d ; if (mclvGetIvp(col, col->vid, NULL)) /* deemed attractor */ mclvInsertIdx(v_transient, col->vid, 0.25) ; } mclvSelectGqBar(v_transient, 0.5) ; m_transient = mclxSub(dag, v_transient, v_transient) ;if(0)mclxDebug("-", m_transient, 3, "transient") ; maxdepth = calc_depth(m_transient) ; mclxFree(&m_transient) ; mclvFree(&v_transient) ; return maxdepth ; }
int crush_adjust_tree_bucket_item_weight(struct crush_bucket_tree *bucket, int item, int weight) { int diff; int node; unsigned i, j; unsigned depth = calc_depth(bucket->h.size); for (i = 0; i < bucket->h.size; i++) { if (bucket->h.items[i] == item) break; } if (i == bucket->h.size) return 0; node = crush_calc_tree_node(i); diff = weight - bucket->node_weights[node]; bucket->node_weights[node] = weight; bucket->h.weight += diff; for (j=1; j<depth; j++) { node = parent(node); bucket->node_weights[node] += diff; } return diff; }
int crush_add_tree_bucket_item(struct crush_bucket_tree *bucket, int item, int weight) { int newsize = bucket->h.size + 1; int depth = calc_depth(newsize);; int node; int j; void *_realloc = NULL; bucket->num_nodes = 1 << depth; if ((_realloc = realloc(bucket->h.items, sizeof(__s32)*newsize)) == NULL) { return -ENOMEM; } else { bucket->h.items = _realloc; } if ((_realloc = realloc(bucket->h.perm, sizeof(__u32)*newsize)) == NULL) { return -ENOMEM; } else { bucket->h.perm = _realloc; } if ((_realloc = realloc(bucket->node_weights, sizeof(__u32)*bucket->num_nodes)) == NULL) { return -ENOMEM; } else { bucket->node_weights = _realloc; } node = crush_calc_tree_node(newsize-1); bucket->node_weights[node] = weight; /* if the depth increase, we need to initialize the new root node's weight before add bucket item */ int root = bucket->num_nodes/2; if (depth >= 2 && (node - 1) == root) { /* if the new item is the first node in right sub tree, so * the root node initial weight is left sub tree's weight */ bucket->node_weights[root] = bucket->node_weights[root/2]; } for (j=1; j<depth; j++) { node = parent(node); if (crush_addition_is_unsafe(bucket->node_weights[node], weight)) return -ERANGE; bucket->node_weights[node] += weight; dprintk(" node %d weight %d\n", node, bucket->node_weights[node]); } if (crush_addition_is_unsafe(bucket->h.weight, weight)) return -ERANGE; bucket->h.items[newsize-1] = item; bucket->h.weight += weight; bucket->h.size++; return 0; }
int main(int argc, char **argv) { char *left_file = NULL; char *right_file = NULL; char *out_file = NULL; int feature_width = -1; int feature_height = -1; int maximum_displacement = -1; int verbosity = 0; int i; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'l': if (argc > i + 1) left_file = argv[++i]; break; case 'r': if (argc > i + 1) right_file = argv[++i]; break; case 'o': if (argc > i + 1) out_file = argv[++i]; break; case 'w': if (argc > i + 1) feature_width = atoi(argv[++i]); break; case 'h': if (argc > i + 1) feature_height = atoi(argv[++i]); break; case 't': if (argc > i + 1) maximum_displacement = atoi(argv[++i]); break; case 'v': verbosity = 1; break; default: printf("Unknown option: %s\n", argv[i]); exit(EINVAL); } } } if (left_file == NULL || right_file == NULL || feature_width == -1 || feature_height == -1 || maximum_displacement == -1) { printf(USAGE, argv[0]); exit(EINVAL); } Image left_image = load_image(left_file); Image right_image = load_image(right_file); if (left_image.height != right_image.height || left_image.width != right_image.width) { printf("The two images do not have the same dimensions.\n"); exit(EINVAL); } Image depth; depth.width = left_image.width; depth.height = right_image.height; depth.data = (unsigned char*) malloc(depth.width * depth.height); if (!depth.data) allocation_failed(); srand((unsigned int) time(NULL)); for (i = 0; i < depth.width * depth.height; i++) { depth.data[i] = rand(); } calc_depth(depth.data, left_image.data, right_image.data, left_image.width, left_image.height, feature_width, feature_height, maximum_displacement); if (out_file != NULL) { save_image_with_depth(out_file, left_image.data, depth.data, left_image.width, left_image.height, feature_width, feature_height); } if (verbosity >= 1) { print_image(depth.data, depth.width, depth.height); } return 0; }
int crush_remove_tree_bucket_item(struct crush_bucket_tree *bucket, int item) { unsigned i; unsigned newsize; for (i = 0; i < bucket->h.size; i++) { int node; int weight; int j; int depth = calc_depth(bucket->h.size); if (bucket->h.items[i] != item) continue; node = crush_calc_tree_node(i); weight = bucket->node_weights[node]; bucket->node_weights[node] = 0; for (j = 1; j < depth; j++) { node = parent(node); bucket->node_weights[node] -= weight; dprintk(" node %d weight %d\n", node, bucket->node_weights[node]); } bucket->h.weight -= weight; break; } if (i == bucket->h.size) return -ENOENT; newsize = bucket->h.size; while (newsize > 0) { int node = crush_calc_tree_node(newsize - 1); if (bucket->node_weights[node]) break; --newsize; } if (newsize != bucket->h.size) { int olddepth, newdepth; void *_realloc = NULL; if ((_realloc = realloc(bucket->h.items, sizeof(__s32)*newsize)) == NULL) { return -ENOMEM; } else { bucket->h.items = _realloc; } if ((_realloc = realloc(bucket->h.perm, sizeof(__u32)*newsize)) == NULL) { return -ENOMEM; } else { bucket->h.perm = _realloc; } olddepth = calc_depth(bucket->h.size); newdepth = calc_depth(newsize); if (olddepth != newdepth) { bucket->num_nodes = 1 << newdepth; if ((_realloc = realloc(bucket->node_weights, sizeof(__u32)*bucket->num_nodes)) == NULL) { return -ENOMEM; } else { bucket->node_weights = _realloc; } } bucket->h.size = newsize; } return 0; }
struct crush_bucket_tree* crush_make_tree_bucket(int hash, int type, int size, int *items, /* in leaf order */ int *weights) { struct crush_bucket_tree *bucket; int depth; int node; int i, j; bucket = malloc(sizeof(*bucket)); if (!bucket) return NULL; memset(bucket, 0, sizeof(*bucket)); bucket->h.alg = CRUSH_BUCKET_TREE; bucket->h.hash = hash; bucket->h.type = type; bucket->h.size = size; if (size == 0) { bucket->h.items = NULL; bucket->h.perm = NULL; bucket->h.weight = 0; bucket->node_weights = NULL; bucket->num_nodes = 0; /* printf("size 0 depth 0 nodes 0\n"); */ return bucket; } bucket->h.items = malloc(sizeof(__s32)*size); if (!bucket->h.items) goto err; bucket->h.perm = malloc(sizeof(__u32)*size); if (!bucket->h.perm) goto err; /* calc tree depth */ depth = calc_depth(size); bucket->num_nodes = 1 << depth; dprintk("size %d depth %d nodes %d\n", size, depth, bucket->num_nodes); bucket->node_weights = malloc(sizeof(__u32)*bucket->num_nodes); if (!bucket->node_weights) goto err; memset(bucket->h.items, 0, sizeof(__s32)*bucket->h.size); memset(bucket->node_weights, 0, sizeof(__u32)*bucket->num_nodes); for (i=0; i<size; i++) { bucket->h.items[i] = items[i]; node = crush_calc_tree_node(i); dprintk("item %d node %d weight %d\n", i, node, weights[i]); bucket->node_weights[node] = weights[i]; if (crush_addition_is_unsafe(bucket->h.weight, weights[i])) goto err; bucket->h.weight += weights[i]; for (j=1; j<depth; j++) { node = parent(node); if (crush_addition_is_unsafe(bucket->node_weights[node], weights[i])) goto err; bucket->node_weights[node] += weights[i]; dprintk(" node %d weight %d\n", node, bucket->node_weights[node]); } } BUG_ON(bucket->node_weights[bucket->num_nodes/2] != bucket->h.weight); return bucket; err: free(bucket->node_weights); free(bucket->h.perm); free(bucket->h.items); free(bucket); return NULL; }