LCOV - code coverage report
Current view: top level - ccan/heap - heap.c (source / functions) Hit Total Coverage
Test: skiboot.info Lines: 61 64 95.3 %
Date: 2020-09-09 23:54:02 Functions: 8 8 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* Licensed under BSD-MIT - see LICENSE file for details */
       2                 :            : #include <ccan/heap/heap.h>
       3                 :            : 
       4                 :            : /*
       5                 :            :  * Allocating memory in chunks greater than needed does not yield measurable
       6                 :            :  * speedups of the test program when linking against glibc 2.15.
       7                 :            :  *
       8                 :            :  * When the data array has to be shrunk though, limiting calls to realloc
       9                 :            :  * does help a little bit (~7% speedup), hence the following parameter.
      10                 :            :  */
      11                 :            : #define HEAP_MEM_HYSTERESIS     4096
      12                 :            : 
      13                 :     140194 : static inline void swap(struct heap *h, size_t i, size_t j)
      14                 :            : {
      15                 :     140194 :         void *foo = h->data[i];
      16                 :            : 
      17                 :     140194 :         h->data[i] = h->data[j];
      18                 :     140194 :         h->data[j] = foo;
      19                 :     140194 : }
      20                 :            : 
      21                 :      10068 : static void __up(struct heap *h, size_t j)
      22                 :            : {
      23                 :            :         size_t i; /* parent */
      24                 :            : 
      25                 :      23256 :         while (j) {
      26                 :      23224 :                 i = (j - 1) / 2;
      27                 :            : 
      28                 :      23224 :                 if (h->less(h->data[j], h->data[i])) {
      29                 :      13188 :                         swap(h, i, j);
      30                 :      13188 :                         j = i;
      31                 :            :                 } else {
      32                 :      10036 :                         break;
      33                 :            :                 }
      34                 :            :         }
      35                 :      10068 : }
      36                 :            : 
      37                 :      10068 : int heap_push(struct heap *h, void *data)
      38                 :            : {
      39                 :      10068 :         if (h->len == h->cap) {
      40                 :      10068 :                 void *m = realloc(h->data, (h->cap + 1) * sizeof(void *));
      41                 :      10068 :                 if (m == NULL)
      42                 :          0 :                         return -1;
      43                 :      10068 :                 h->data = m;
      44                 :      10068 :                 h->cap++;
      45                 :            :         }
      46                 :      10068 :         h->data[h->len++] = data;
      47                 :      10068 :         __up(h, h->len - 1);
      48                 :      10068 :         return 0;
      49                 :            : }
      50                 :            : 
      51                 :     137032 : static void __down(struct heap *h, size_t i)
      52                 :            : {
      53                 :            :         size_t l, r, j; /* left, right, min child */
      54                 :            : 
      55                 :            :         while (1) {
      56                 :     137032 :                 l = 2 * i + 1;
      57                 :     137032 :                 if (l >= h->len)
      58                 :      18554 :                         break;
      59                 :     118478 :                 r = l + 1;
      60                 :     118478 :                 if (r >= h->len)
      61                 :         50 :                         j = l;
      62                 :            :                 else
      63                 :     118428 :                         j = h->less(h->data[l], h->data[r]) ? l : r;
      64                 :            : 
      65                 :     118478 :                 if (h->less(h->data[j], h->data[i])) {
      66                 :     116938 :                         swap(h, i, j);
      67                 :     116938 :                         i = j;
      68                 :            :                 } else {
      69                 :       1540 :                         break;
      70                 :            :                 }
      71                 :            :         }
      72                 :      20094 : }
      73                 :            : 
      74                 :      10068 : void *heap_pop(struct heap *h)
      75                 :            : {
      76                 :      10068 :         void *ret = h->data[0];
      77                 :            :         void *m;
      78                 :            : 
      79                 :      10068 :         swap(h, 0, --h->len);
      80                 :      10068 :         if (h->len) {
      81                 :      10062 :                 __down(h, 0);
      82                 :      10062 :                 if (h->len == h->cap - HEAP_MEM_HYSTERESIS) {
      83                 :          2 :                         m = realloc(h->data, h->len * sizeof(void *));
      84                 :          2 :                         if (m == NULL)
      85                 :          0 :                                 return NULL;
      86                 :          2 :                         h->data = m;
      87                 :          2 :                         h->cap = h->len;
      88                 :            :                 }
      89                 :            :         }
      90                 :            : 
      91                 :      10068 :         return ret;
      92                 :            : }
      93                 :            : 
      94                 :          6 : struct heap *heap_init(heap_less_func_t less)
      95                 :            : {
      96                 :          6 :         struct heap *heap = calloc(1, sizeof(*heap));
      97                 :            : 
      98                 :          6 :         if (heap == NULL)
      99                 :          0 :                 return NULL;
     100                 :          6 :         heap->less = less;
     101                 :          6 :         return heap;
     102                 :            : }
     103                 :            : 
     104                 :         10 : void heap_ify(struct heap *h, heap_less_func_t less)
     105                 :            : {
     106                 :            :         int i;
     107                 :            : 
     108                 :         10 :         if (less)
     109                 :          8 :                 h->less = less;
     110                 :            : 
     111                 :      10042 :         for (i = h->len / 2 - 1; i >= 0; i--)
     112                 :      10032 :                 __down(h, i);
     113                 :         10 : }
     114                 :            : 
     115                 :          6 : void heap_free(struct heap *heap)
     116                 :            : {
     117                 :          6 :         free(heap->data);
     118                 :          6 :         free(heap);
     119                 :          6 : }

Generated by: LCOV version 1.14