dte test coverage


Directory: ./
File: src/util/hashset.h
Date: 2025-11-12 12:04:10
Coverage Exec Excl Total
Lines: 100.0% 13 0 13
Functions: 100.0% 2 0 2
Branches: 100.0% 8 0 8

Line Branch Exec Source
1 #ifndef UTIL_HASHSET_H
2 #define UTIL_HASHSET_H
3
4 #include <stdbool.h>
5 #include <stddef.h>
6 #include "macros.h"
7
8 // A container type for holding a set of strings, using hashing for
9 // primary lookups and separate chaining for collision resolution.
10 typedef struct {
11 struct HashSetEntry **table;
12 size_t table_size;
13 size_t nr_entries;
14 size_t grow_at;
15 size_t (*hash)(const char *str, size_t len);
16 bool (*equal)(const void *s1, const void *s2, size_t n);
17 } HashSet;
18
19 typedef struct HashSetEntry {
20 struct HashSetEntry *next;
21 size_t str_len;
22 char str[];
23 } HashSetEntry;
24
25 typedef struct {
26 const HashSet *set;
27 const HashSetEntry *entry;
28 size_t idx;
29 } HashSetIter;
30
31 3 static inline HashSetIter hashset_iter(const HashSet *set)
32 {
33 3 return (HashSetIter){.set = set};
34 }
35
36 // Set `iter->entry` to the next active HashSetEntry in iter->set and
37 // return true, or return false when there are no remaining entries to
38 // visit. Note that `iter->entry` is only NULL prior to the first call.
39 18 static inline bool hashset_next(HashSetIter *iter)
40 {
41
4/4
✓ Branch 2 → 3 taken 14 times.
✓ Branch 2 → 5 taken 4 times.
✓ Branch 3 → 4 taken 3 times.
✓ Branch 3 → 5 taken 11 times.
18 if (likely(iter->entry) && iter->entry->next) {
42 // Traverse linked entries
43 3 iter->entry = iter->entry->next;
44 3 return true;
45 }
46
47 // Traverse table entries
48 15 const HashSet *set = iter->set;
49
2/2
✓ Branch 9 → 6 taken 98 times.
✓ Branch 9 → 10 taken 5 times.
103 for (size_t i = iter->idx, n = set->table_size; i < n; i++) {
50 98 const HashSetEntry *e = set->table[i];
51
2/2
✓ Branch 6 → 7 taken 10 times.
✓ Branch 6 → 8 taken 88 times.
98 if (e) {
52 10 iter->entry = e;
53 10 iter->idx = i + 1;
54 10 return true;
55 }
56 }
57
58 return false;
59 }
60
61 void hashset_init(HashSet *set, size_t initial_size, bool icase);
62 void hashset_free(HashSet *set);
63 HashSetEntry *hashset_get(const HashSet *set, const char *str, size_t str_len);
64 HashSetEntry *hashset_insert(HashSet *set, const char *str, size_t str_len);
65
66 #endif
67