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

1.1     ! misho       1: /*
        !             2:  *     BIRD Library -- Universal Heap Macros 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: #include "test/birdtest.h"
        !            10: #include "sysdep/config.h"
        !            11: #include "lib/heap.h"
        !            12: 
        !            13: #define MAX_NUM 1000
        !            14: #define SPECIAL_KEY -3213
        !            15: 
        !            16: #define MY_CMP(x, y) ((x) < (y))
        !            17: 
        !            18: #define MY_HEAP_SWAP(heap,a,b,t)               \
        !            19:     do {                                       \
        !            20:       bt_debug("swap(%u %u) ", a, b);          \
        !            21:       HEAP_SWAP(heap,a,b,t);                   \
        !            22:     } while(0)
        !            23: 
        !            24: static int heap[MAX_NUM+1];
        !            25: static uint num;
        !            26: 
        !            27: /*
        !            28:  * A valid heap must follow these rules:
        !            29:  *   - `num >= 0`
        !            30:  *   - `heap[i] >= heap[i / 2]` for each `i` in `[2, num]`
        !            31:  */
        !            32: static int
        !            33: is_heap_valid(int heap[], uint num)
        !            34: {
        !            35:   uint i;
        !            36: 
        !            37:   if (num > MAX_NUM)
        !            38:     return 0;
        !            39: 
        !            40:   for (i = 2; i <= num; i++)
        !            41:     if (heap[i] < heap[i / 2])
        !            42:       return 0;
        !            43: 
        !            44:   return 1;
        !            45: }
        !            46: 
        !            47: static void
        !            48: show_heap(void)
        !            49: {
        !            50:   uint i;
        !            51:   bt_debug("\n");
        !            52:   bt_debug("numbers %u; ", num);
        !            53:   for (i = 0; i <= num; i++)
        !            54:     bt_debug("%d ", heap[i]);
        !            55:   bt_debug(is_heap_valid(heap, num) ? "OK" : "NON-VALID HEAP!");
        !            56:   bt_debug("\n");
        !            57: }
        !            58: 
        !            59: static void
        !            60: init_heap(void)
        !            61: {
        !            62:   uint i;
        !            63:   num = 0;
        !            64:   heap[0] = SPECIAL_KEY;               /* heap[0] should be unused */
        !            65:   for (i = 1; i <= MAX_NUM; i++)
        !            66:     heap[i] = 0;
        !            67: }
        !            68: 
        !            69: static int
        !            70: t_heap_insert(void)
        !            71: {
        !            72:   uint i;
        !            73: 
        !            74:   init_heap();
        !            75: 
        !            76:   for (i = MAX_NUM; i >= 1; i--)
        !            77:   {
        !            78:     bt_debug("ins %u at pos %u ", i, MAX_NUM - i);
        !            79:     heap[MAX_NUM - i + 1] = i;
        !            80:     HEAP_INSERT(heap, ++num, int, MY_CMP, MY_HEAP_SWAP);
        !            81:     show_heap();
        !            82:     bt_assert(is_heap_valid(heap, num));
        !            83:   }
        !            84: 
        !            85:   return 1;
        !            86: }
        !            87: 
        !            88: static int
        !            89: t_heap_increase_decrease(void)
        !            90: {
        !            91:   uint i;
        !            92: 
        !            93:   t_heap_insert();
        !            94: 
        !            95:   for (i = 1; i <= MAX_NUM; i++)
        !            96:   {
        !            97:     if ((int)i > heap[i])
        !            98:     {
        !            99:       bt_debug("inc %u ", i);
        !           100:       heap[i] = i;
        !           101:       HEAP_INCREASE(heap, num, int, MY_CMP, MY_HEAP_SWAP, i);
        !           102:     }
        !           103:     else if ((int)i < heap[i])
        !           104:     {
        !           105:       bt_debug("dec %u ", i);
        !           106:       heap[i] = i;
        !           107:       HEAP_INCREASE(heap, num, int, MY_CMP, MY_HEAP_SWAP, i);
        !           108:     }
        !           109:     show_heap();
        !           110:     bt_assert(is_heap_valid(heap, num));
        !           111:   }
        !           112: 
        !           113:   return 1;
        !           114: }
        !           115: 
        !           116: static int
        !           117: t_heap_delete(void)
        !           118: {
        !           119:   uint i;
        !           120: 
        !           121:   t_heap_insert();
        !           122: 
        !           123:   for (i = 1; i <= num; i++)
        !           124:   {
        !           125:     bt_debug("del at pos %u ", i);
        !           126:     HEAP_DELETE(heap, num, int, MY_CMP, MY_HEAP_SWAP, i);
        !           127:     show_heap();
        !           128:     bt_assert(is_heap_valid(heap, num));
        !           129:   }
        !           130: 
        !           131:   return 1;
        !           132: }
        !           133: 
        !           134: static int
        !           135: t_heap_0(void)
        !           136: {
        !           137:   init_heap();
        !           138:   t_heap_insert();
        !           139:   t_heap_increase_decrease();
        !           140:   t_heap_delete();
        !           141: 
        !           142:   return heap[0] == SPECIAL_KEY;
        !           143: }
        !           144: 
        !           145: static int
        !           146: t_heap_insert_random(void)
        !           147: {
        !           148:   int i, j;
        !           149:   int expected[MAX_NUM+1];
        !           150: 
        !           151:   init_heap();
        !           152: 
        !           153:   for (i = 1; i <= MAX_NUM; i++)
        !           154:   {
        !           155:     heap[i] = expected[i] = bt_random();
        !           156:     HEAP_INSERT(heap, ++num, int, MY_CMP, MY_HEAP_SWAP);
        !           157:     show_heap();
        !           158:     bt_assert(is_heap_valid(heap, num));
        !           159:   }
        !           160: 
        !           161:   for (i = 1; i <= MAX_NUM; i++)
        !           162:     for (j = 1; j <= MAX_NUM; j++)
        !           163:       if(expected[i] == heap[j])
        !           164:        break;
        !           165:       else if (j == MAX_NUM)
        !           166:       {
        !           167:        show_heap();
        !           168:        bt_abort_msg("Did not find a number %d in heap.", expected[i]);
        !           169:       }
        !           170: 
        !           171:   return 1;
        !           172: }
        !           173: 
        !           174: int
        !           175: main(int argc, char *argv[])
        !           176: {
        !           177:   bt_init(argc, argv);
        !           178: 
        !           179:   bt_test_suite(t_heap_insert, "Inserting a descending sequence of numbers (the worst case)");
        !           180:   bt_test_suite(t_heap_insert_random, "Inserting pseudo-random numbers");
        !           181:   bt_test_suite(t_heap_increase_decrease, "Increasing/Decreasing");
        !           182:   bt_test_suite(t_heap_delete, "Deleting");
        !           183:   bt_test_suite(t_heap_0, "Is a heap[0] really unused?");
        !           184: 
        !           185:   return bt_exit_value();
        !           186: }

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