dte test coverage


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 50.0% high: ≥ 85.0%
Coverage Exec / Excl / Total
Lines: 100.0% 74 / 0 / 74
Functions: 100.0% 11 / 0 / 11
Branches: 88.2% 30 / 16 / 50

src/util/ptr-array.c
Line Branch Exec Source
1 #include <errno.h>
2 #include <string.h>
3 #include "ptr-array.h"
4
5 13840 static void ptr_array_grow(PointerArray *array)
6 {
7 13840 BUG_ON(array->alloc < array->count);
8 13840 const size_t alloc_min = 8;
9
2/2
✓ Branch 4 → 5 taken 491 times.
✓ Branch 4 → 6 taken 13349 times.
13840 size_t alloc = MAX((array->alloc * 3) / 2, alloc_min);
10
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 13840 times.
13840 FATAL_ERROR_ON(alloc <= array->count, EOVERFLOW);
11 13840 array->ptrs = xrenew(array->ptrs, alloc);
12 13840 array->alloc = alloc;
13 13840 }
14
15 // This is separate from ptr_array_append(), to allow the hot path to be
16 // inlined. It also duplicates the append operation so as to allow tail
17 // calling, which appears to improve code generation.
18 13840 void ptr_array_grow_and_append(PointerArray *array, void *ptr)
19 {
20 13840 ptr_array_grow(array);
21 13840 array->ptrs[array->count++] = ptr;
22 13840 }
23
24 // Move a pointer from one index to another
25 34 void ptr_array_move(PointerArray *array, size_t from, size_t to)
26 {
27 34 BUG_ON(from >= array->count);
28 34 BUG_ON(to >= array->count);
29
2/2
✓ Branch 6 → 7 taken 24 times.
✓ Branch 6 → 17 taken 10 times.
34 if (unlikely(from == to)) {
30 return;
31 }
32
33 24 void **p = array->ptrs;
34 24 bool up = (from < to);
35
2/2
✓ Branch 7 → 8 taken 8 times.
✓ Branch 7 → 9 taken 16 times.
24 void *dest = up ? p + from : p + to + 1;
36
2/2
✓ Branch 10 → 11 taken 8 times.
✓ Branch 10 → 12 taken 16 times.
24 void *src = up ? p + from + 1 : p + to;
37
2/2
✓ Branch 13 → 14 taken 8 times.
✓ Branch 13 → 15 taken 16 times.
24 size_t difference = up ? to - from : from - to;
38
39 24 void *tmp = p[from];
40 24 memmove(dest, src, difference * sizeof(void*));
41 24 p[to] = tmp;
42 }
43
44 12 void ptr_array_insert(PointerArray *array, void *ptr, size_t idx)
45 {
46 12 size_t last = array->count;
47 12 BUG_ON(idx > last);
48 12 ptr_array_append(array, ptr); // last is now array->count - 1
49 12 ptr_array_move(array, last, idx);
50 12 }
51
52 // Free and remove `count` pointers from the end of the array
53 15216 void ptr_array_pop(PointerArray *array, FreeFunction free_ptr, size_t count)
54 {
55 15216 BUG_ON(count > array->count);
56
2/2
✓ Branch 7 → 5 taken 46730 times.
✓ Branch 7 → 8 taken 15216 times.
61946 for (size_t n = array->count, i = n - count; i < n; i++) {
57 46730 do_free_value(free_ptr, array->ptrs[i]);
58 46730 array->ptrs[i] = NULL;
59 }
60 15216 array->count -= count;
61 15216 }
62
63 // Free and remove and all pointers, without freeing the array itself
64 15216 void ptr_array_clear(PointerArray *array, FreeFunction free_ptr)
65 {
66 15216 ptr_array_pop(array, free_ptr, array->count);
67 15216 }
68
69 15216 void ptr_array_free_cb(PointerArray *array, FreeFunction free_ptr)
70 {
71 15216 ptr_array_clear(array, free_ptr);
72 15216 ptr_array_free_array(array);
73 15216 }
74
75 174 size_t ptr_array_remove(PointerArray *array, void *ptr)
76 {
77 174 size_t idx = ptr_array_xindex(array, ptr);
78 174 void *removed = ptr_array_remove_index(array, idx);
79 174 BUG_ON(removed != ptr);
80 174 return idx;
81 }
82
83 2254 void *ptr_array_remove_index(PointerArray *array, size_t idx)
84 {
85 2254 BUG_ON(idx >= array->count);
86 2254 void **ptrs = array->ptrs + idx;
87 2254 void *removed = *ptrs;
88 2254 memmove(ptrs, ptrs + 1, (--array->count - idx) * sizeof(void*));
89 2254 return removed;
90 }
91
92 // Return the first array index found to contain `ptr`, or SIZE_MAX
93 // if not found. See also: ptr_array_xindex(), ptr_array_bsearch().
94 2185 size_t ptr_array_index(const PointerArray *array, const void *ptr)
95 {
96
1/2
✓ Branch 5 → 3 taken 7360 times.
✗ Branch 5 → 6 not taken.
7360 for (size_t i = 0, n = array->count; i < n; i++) {
97
2/2
✓ Branch 3 → 4 taken 5175 times.
✓ Branch 3 → 6 taken 2185 times.
7360 if (array->ptrs[i] == ptr) {
98 return i;
99 }
100 }
101
102 // If `ptr` isn't found in the array, return -1 (SIZE_MAX). Callers
103 // should check that the returned index is less than `array->count`
104 // before indexing `array->ptrs` with it or use ptr_array_xindex()
105 // instead, if applicable.
106 return -1;
107 }
108
109 // Trim all leading NULLs and all but one trailing NULL (if any)
110 1967 void ptr_array_trim_nulls(PointerArray *array)
111 {
112 1967 size_t n = array->count;
113
2/2
✓ Branch 2 → 3 taken 1966 times.
✓ Branch 2 → 17 taken 1 time.
1967 if (n == 0) {
114 return;
115 }
116
117 1966 void **ptrs = array->ptrs;
118
4/4
✓ Branch 4 → 5 taken 3933 times.
✓ Branch 4 → 6 taken 2 times.
✓ Branch 5 → 4 taken 1969 times.
✓ Branch 5 → 6 taken 1964 times.
3935 while (n > 0 && ptrs[n - 1] == NULL) {
119 n--;
120 }
121
122
1/2
✓ Branch 6 → 7 taken 1966 times.
✗ Branch 6 → 8 not taken.
1966 if (n != array->count) {
123 // Leave 1 trailing NULL
124 1966 n++;
125 }
126
127
3/4
✓ Branch 8 → 9 taken 1966 times.
✗ Branch 8 → 10 not taken.
✓ Branch 9 → 10 taken 1963 times.
✓ Branch 9 → 12 taken 3 times.
1966 if (n == 0 || ptrs[0] != NULL) {
128 // No leading NULLs; simply adjust count and return early
129 1963 array->count = n;
130 1963 return;
131 }
132
133 size_t i = 0;
134
4/4
✓ Branch 12 → 13 taken 5 times.
✓ Branch 12 → 14 taken 2 times.
✓ Branch 13 → 11 taken 4 times.
✓ Branch 13 → 14 taken 1 time.
7 while (i < n && ptrs[i] == NULL) {
135 4 i++;
136 }
137
138 3 BUG_ON(i == 0);
139 3 n -= i;
140 3 array->count = n;
141 3 memmove(ptrs, ptrs + i, n * sizeof(void*));
142 }
143