my_bool test_compare_operators(MY_BITMAP *map, uint bitsize) { uint i, j, test_bit1, test_bit2, test_bit3,test_bit4; uint no_loops= bitsize > 128 ? 128 : bitsize; MY_BITMAP map2_obj, map3_obj; MY_BITMAP *map2= &map2_obj, *map3= &map3_obj; uint32 map2buf[MAX_TESTED_BITMAP_SIZE]; uint32 map3buf[MAX_TESTED_BITMAP_SIZE]; bitmap_init(&map2_obj, map2buf, bitsize, FALSE); bitmap_init(&map3_obj, map3buf, bitsize, FALSE); bitmap_clear_all(map2); bitmap_clear_all(map3); for (i=0; i < no_loops; i++) { test_bit1=get_rand_bit(bitsize); bitmap_set_prefix(map, test_bit1); test_bit2=get_rand_bit(bitsize); bitmap_set_prefix(map2, test_bit2); bitmap_intersect(map, map2); test_bit3= test_bit2 < test_bit1 ? test_bit2 : test_bit1; bitmap_set_prefix(map3, test_bit3); if (!bitmap_cmp(map, map3)) goto error1; bitmap_clear_all(map); bitmap_clear_all(map2); bitmap_clear_all(map3); test_bit1=get_rand_bit(bitsize); test_bit2=get_rand_bit(bitsize); test_bit3=get_rand_bit(bitsize); bitmap_set_prefix(map, test_bit1); bitmap_set_prefix(map2, test_bit2); test_bit3= test_bit2 > test_bit1 ? test_bit2 : test_bit1; bitmap_set_prefix(map3, test_bit3); bitmap_union(map, map2); if (!bitmap_cmp(map, map3)) goto error2; bitmap_clear_all(map); bitmap_clear_all(map2); bitmap_clear_all(map3); test_bit1=get_rand_bit(bitsize); test_bit2=get_rand_bit(bitsize); test_bit3=get_rand_bit(bitsize); bitmap_set_prefix(map, test_bit1); bitmap_set_prefix(map2, test_bit2); bitmap_xor(map, map2); test_bit3= test_bit2 > test_bit1 ? test_bit2 : test_bit1; test_bit4= test_bit2 < test_bit1 ? test_bit2 : test_bit1; bitmap_set_prefix(map3, test_bit3); for (j=0; j < test_bit4; j++) bitmap_clear_bit(map3, j); if (!bitmap_cmp(map, map3)) goto error3; bitmap_clear_all(map); bitmap_clear_all(map2); bitmap_clear_all(map3); test_bit1=get_rand_bit(bitsize); test_bit2=get_rand_bit(bitsize); test_bit3=get_rand_bit(bitsize); bitmap_set_prefix(map, test_bit1); bitmap_set_prefix(map2, test_bit2); bitmap_subtract(map, map2); if (test_bit2 < test_bit1) { bitmap_set_prefix(map3, test_bit1); for (j=0; j < test_bit2; j++) bitmap_clear_bit(map3, j); } if (!bitmap_cmp(map, map3)) goto error4; bitmap_clear_all(map); bitmap_clear_all(map2); bitmap_clear_all(map3); test_bit1=get_rand_bit(bitsize); bitmap_set_prefix(map, test_bit1); bitmap_invert(map); bitmap_set_all(map3); for (j=0; j < test_bit1; j++) bitmap_clear_bit(map3, j); if (!bitmap_cmp(map, map3)) goto error5; bitmap_clear_all(map); bitmap_clear_all(map3); } return FALSE; error1: diag("intersect error bitsize=%u,size1=%u,size2=%u", bitsize, test_bit1,test_bit2); return TRUE; error2: diag("union error bitsize=%u,size1=%u,size2=%u", bitsize, test_bit1,test_bit2); return TRUE; error3: diag("xor error bitsize=%u,size1=%u,size2=%u", bitsize, test_bit1,test_bit2); return TRUE; error4: diag("subtract error bitsize=%u,size1=%u,size2=%u", bitsize, test_bit1,test_bit2); return TRUE; error5: diag("invert error bitsize=%u,size=%u", bitsize, test_bit1); return TRUE; }
int router_nearest(struct router_t* router, const uint8_t id[N_NODEID], struct node_t* nodes[], size_t count) { int i, min, diff; uint8_t xor[N_NODEID]; heap_t* heap; struct rbitem_t* item; struct rbtree_node_t* node; const struct rbtree_node_t* prev; const struct rbtree_node_t* next; heap = heap_create(node_compare_less, (void*)id); heap_reserve(heap, count + 1); min = N_BITS; locker_lock(&router->locker); rbtree_find(&router->rbtree, id, &node); if (NULL == node) { locker_unlock(&router->locker); return 0; } item = rbtree_entry(node, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); min = min < diff ? min : diff; heap_push(heap, item->node); prev = rbtree_prev(node); next = rbtree_next(node); do { while (prev) { item = rbtree_entry(prev, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); heap_push(heap, item->node); if (heap_size(heap) > (int)count) heap_pop(heap); prev = rbtree_prev(prev); if (diff < min) { min = diff; break; // try right } } while (next) { item = rbtree_entry(next, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); heap_push(heap, item->node); if (heap_size(heap) > (int)count) heap_pop(heap); next = rbtree_next(next); if (diff < min) { min = diff; break; // try left } } } while (heap_size(heap) < (int)count && (prev || next)); for (i = 0; i < (int)count && !heap_empty(heap); i++) { nodes[i] = heap_top(heap); node_addref(nodes[i]); heap_pop(heap); } locker_unlock(&router->locker); heap_destroy(heap); return i; }