Annotation of embedaddon/bird2/lib/hash_test.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  *     BIRD Library -- Hash Tests
        !             3:  *
        !             4:  *     (c) 2015 CZ.NIC z.s.p.o.
        !             5:  *
        !             6:  *     Can be freely distributed and used under the terms of the GNU GPL.
        !             7:  */
        !             8: 
        !             9: #undef LOCAL_DEBUG
        !            10: 
        !            11: #include "test/birdtest.h"
        !            12: 
        !            13: #include "lib/hash.h"
        !            14: 
        !            15: struct test_node {
        !            16:   struct test_node *next;      /* Hash chain */
        !            17:   u32 key;
        !            18: };
        !            19: 
        !            20: #define TEST_KEY(n)            n->key
        !            21: #define TEST_NEXT(n)           n->next
        !            22: #define TEST_EQ(n1,n2)         n1 == n2
        !            23: #define TEST_FN(n)             (n) ^ u32_hash((n))
        !            24: #define TEST_ORDER             13
        !            25: #define TEST_PARAMS            /TEST_ORDER, *2, 2, 2, TEST_ORDER, 20
        !            26: #define TEST_REHASH            test_rehash
        !            27: 
        !            28: HASH_DEFINE_REHASH_FN(TEST, struct test_node);
        !            29: 
        !            30: HASH(struct test_node) hash;
        !            31: struct pool *my_pool;
        !            32: 
        !            33: #define MAX_NUM                        (1 << TEST_ORDER)
        !            34: 
        !            35: struct test_node nodes[MAX_NUM];
        !            36: 
        !            37: static void
        !            38: print_rate_of_fulfilment(void)
        !            39: {
        !            40:   int i;
        !            41:   int num_stacked_items = 0;
        !            42: 
        !            43:   for (i = 0; i < MAX_NUM; i++)
        !            44:     if (!hash.data[i])
        !            45:       num_stacked_items++;
        !            46: 
        !            47:   double percent_stacked_items = ((double)num_stacked_items/(double)MAX_NUM)*100.;
        !            48:   bt_debug("%d (%.2f %%) chained of %d hashes \n", num_stacked_items, percent_stacked_items, MAX_NUM);
        !            49: }
        !            50: 
        !            51: #ifdef LOCAL_DEBUG
        !            52: static void
        !            53: dump_nodes(void)
        !            54: {
        !            55:   int i;
        !            56:   for (i = 0; i < MAX_NUM; i++)
        !            57:     bt_debug("nodes[%3d] is at address %14p has .key %3d, .next %14p \n", i, &nodes[i], nodes[i].key, nodes[i].next);
        !            58: }
        !            59: #endif
        !            60: 
        !            61: static void
        !            62: init_hash_(uint order)
        !            63: {
        !            64:   resource_init();
        !            65:   my_pool = rp_new(&root_pool, "Test pool");
        !            66: 
        !            67:   HASH_INIT(hash, my_pool, order);
        !            68: 
        !            69:   int i;
        !            70:   for (i = 0; i < MAX_NUM; i++)
        !            71:   {
        !            72:     nodes[i].key  = i;
        !            73:     nodes[i].next = NULL;
        !            74:   }
        !            75: 
        !            76:   bt_debug("MAX_NUM %d \n", MAX_NUM);
        !            77: }
        !            78: 
        !            79: static void
        !            80: init_hash(void)
        !            81: {
        !            82:   init_hash_(TEST_ORDER);
        !            83: }
        !            84: 
        !            85: static void
        !            86: validate_filled_hash(void)
        !            87: {
        !            88:   int i;
        !            89:   struct test_node *node;
        !            90:   for (i = 0; i < MAX_NUM; i++)
        !            91:   {
        !            92:     node = HASH_FIND(hash, TEST, nodes[i].key);
        !            93:     bt_assert_msg(node->key == nodes[i].key, "Hash should be filled, to find (%p) the node[%d] (%p) with .key = %u, .next %p", node, i, &nodes[i], nodes[i].key, nodes[i].next);
        !            94:   }
        !            95: 
        !            96:   print_rate_of_fulfilment();
        !            97: }
        !            98: 
        !            99: static void
        !           100: validate_empty_hash(void)
        !           101: {
        !           102:   int i;
        !           103:   struct test_node *node;
        !           104:   for (i = 0; i < MAX_NUM; i++)
        !           105:   {
        !           106:     node = HASH_FIND(hash, TEST, nodes[i].key);
        !           107:     bt_assert_msg(node == NULL, "Hash should be empty, to find (%p) the node[%d] (%p) with .key %u, .next %p", node, i, &nodes[i], nodes[i].key, nodes[i].next);
        !           108:   }
        !           109: }
        !           110: 
        !           111: static void
        !           112: fill_hash(void)
        !           113: {
        !           114:   int i;
        !           115:   struct test_node *node;
        !           116: 
        !           117:   for (i = 0; i < MAX_NUM; i++)
        !           118:   {
        !           119:     nodes[i].key = i;
        !           120:     node = &nodes[i];
        !           121:     HASH_INSERT(hash, TEST, node);
        !           122:   }
        !           123: }
        !           124: 
        !           125: static int
        !           126: t_insert_find(void)
        !           127: {
        !           128:   init_hash();
        !           129:   fill_hash();
        !           130:   validate_filled_hash();
        !           131: 
        !           132:   return 1;
        !           133: }
        !           134: 
        !           135: static int
        !           136: t_insert_find_random(void)
        !           137: {
        !           138:   init_hash();
        !           139: 
        !           140:   int i;
        !           141:   struct test_node *node;
        !           142:   for (i = 0; i < MAX_NUM; i++)
        !           143:   {
        !           144:     nodes[i].key = bt_random();
        !           145:     node = &nodes[i];
        !           146:     HASH_INSERT(hash, TEST, node);
        !           147:   }
        !           148: 
        !           149:   validate_filled_hash();
        !           150: 
        !           151:   return 1;
        !           152: }
        !           153: 
        !           154: static int
        !           155: t_insert2_find(void)
        !           156: {
        !           157:   init_hash_(1);
        !           158: 
        !           159:   int i;
        !           160:   struct test_node *node;
        !           161:   for (i = 0; i < MAX_NUM; i++)
        !           162:   {
        !           163:     nodes[i].key = i;
        !           164:     node = &nodes[i];
        !           165:     HASH_INSERT2(hash, TEST, my_pool, node);
        !           166:   }
        !           167:   bt_assert_msg(hash.order != 1, "The hash should auto-resize from order 2^1. The order of the hash is 2^%u.", hash.order);
        !           168: 
        !           169:   validate_filled_hash();
        !           170: 
        !           171:   return 1;
        !           172: }
        !           173: 
        !           174: static int
        !           175: t_walk(void)
        !           176: {
        !           177:   init_hash();
        !           178:   fill_hash();
        !           179: 
        !           180:   uint i;
        !           181:   uint check[MAX_NUM];
        !           182:   for (i = 0; i < MAX_NUM; i++)
        !           183:     check[i] = 0;
        !           184: 
        !           185:   HASH_WALK(hash, next, n)
        !           186:   {
        !           187:     check[n->key]++;
        !           188:   }
        !           189:   HASH_WALK_END;
        !           190: 
        !           191:   for (i = 0; i < MAX_NUM; i++)
        !           192:     bt_assert(check[i] == 1);
        !           193: 
        !           194:   return 1;
        !           195: }
        !           196: 
        !           197: static int
        !           198: t_walk_delsafe_delete(void)
        !           199: {
        !           200:   init_hash();
        !           201:   fill_hash();
        !           202: 
        !           203:   HASH_WALK_DELSAFE(hash, next, n)
        !           204:   {
        !           205:     HASH_DELETE(hash, TEST, n->key);
        !           206:   }
        !           207:   HASH_WALK_DELSAFE_END;
        !           208: 
        !           209:   validate_empty_hash();
        !           210: 
        !           211:   return 1;
        !           212: }
        !           213: 
        !           214: static int
        !           215: t_walk_delsafe_remove(void)
        !           216: {
        !           217:   init_hash();
        !           218:   fill_hash();
        !           219: 
        !           220:   HASH_WALK_DELSAFE(hash, next, n)
        !           221:   {
        !           222:     HASH_REMOVE(hash, TEST, n);
        !           223:   }
        !           224:   HASH_WALK_DELSAFE_END;
        !           225: 
        !           226:   validate_empty_hash();
        !           227: 
        !           228:   return 1;
        !           229: }
        !           230: 
        !           231: static int
        !           232: t_walk_delsafe_delete2(void)
        !           233: {
        !           234:   init_hash();
        !           235:   fill_hash();
        !           236: 
        !           237:   HASH_WALK_DELSAFE(hash, next, n)
        !           238:   {
        !           239:     HASH_DELETE2(hash, TEST, my_pool, n->key);
        !           240:   }
        !           241:   HASH_WALK_DELSAFE_END;
        !           242: 
        !           243:   validate_empty_hash();
        !           244: 
        !           245:   return 1;
        !           246: }
        !           247: 
        !           248: static int
        !           249: t_walk_delsafe_remove2(void)
        !           250: {
        !           251:   init_hash();
        !           252:   fill_hash();
        !           253: 
        !           254:   HASH_WALK_DELSAFE(hash, next, n)
        !           255:   {
        !           256:     HASH_REMOVE2(hash, TEST, my_pool, n);
        !           257:   }
        !           258:   HASH_WALK_DELSAFE_END;
        !           259: 
        !           260:   validate_empty_hash();
        !           261: 
        !           262:   return 1;
        !           263: }
        !           264: 
        !           265: static int
        !           266: t_walk_filter(void)
        !           267: {
        !           268:   init_hash();
        !           269:   fill_hash();
        !           270: 
        !           271:   uint i;
        !           272:   uint check[MAX_NUM];
        !           273:   for (i = 0; i < MAX_NUM; i++)
        !           274:     check[i] = 0;
        !           275: 
        !           276:   HASH_WALK_FILTER(hash, next, n, m)
        !           277:   {
        !           278:     bt_assert(n == *m);
        !           279:     check[n->key]++;
        !           280:   }
        !           281:   HASH_WALK_FILTER_END;
        !           282: 
        !           283:   for (i = 0; i < MAX_NUM; i++)
        !           284:     bt_assert(check[i] == 1);
        !           285: 
        !           286:   return 1;
        !           287: }
        !           288: 
        !           289: int
        !           290: main(int argc, char *argv[])
        !           291: {
        !           292:   bt_init(argc, argv);
        !           293: 
        !           294:   bt_test_suite(t_insert_find,                 "HASH_INSERT and HASH_FIND");
        !           295:   bt_test_suite(t_insert_find_random,  "HASH_INSERT pseudo-random keys and HASH_FIND");
        !           296:   bt_test_suite(t_insert2_find,        "HASH_INSERT2 and HASH_FIND. HASH_INSERT2 is HASH_INSERT and a smart auto-resize function");
        !           297:   bt_test_suite(t_walk,                "HASH_WALK");
        !           298:   bt_test_suite(t_walk_delsafe_delete,         "HASH_WALK_DELSAFE and HASH_DELETE");
        !           299:   bt_test_suite(t_walk_delsafe_delete2,        "HASH_WALK_DELSAFE and HASH_DELETE2. HASH_DELETE2 is HASH_DELETE and smart auto-resize function");
        !           300:   bt_test_suite(t_walk_delsafe_remove,         "HASH_WALK_DELSAFE and HASH_REMOVE");
        !           301:   bt_test_suite(t_walk_delsafe_remove2,        "HASH_WALK_DELSAFE and HASH_REMOVE2. HASH_REMOVE2 is HASH_REMOVE and smart auto-resize function");
        !           302:   bt_test_suite(t_walk_filter,         "HASH_WALK_FILTER");
        !           303: 
        !           304:   return bt_exit_value();
        !           305: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>