Annotation of embedaddon/bird2/lib/heap_test.c, revision 1.1.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>