master
h 91 lines 7.68 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #ifndef NETDATA_JUDYL_TYPED_H
4 #define NETDATA_JUDYL_TYPED_H
5
6 #include <Judy.h>
7
8 #ifdef __cplusplus
9 #define DEFINED_JUDYL_CHECK_SIZE(TYPE, NAME)
10 #else
11 #define DEFINED_JUDYL_CHECK_SIZE(TYPE, NAME) _Static_assert(sizeof(TYPE) <= sizeof(Word_t), #NAME "_type_must_have_same_size_as_Word_t")
12 #endif
13
14
15 // Advanced macro for types requiring conversion
16 #define DEFINE_JUDYL_TYPED_ADVANCED(NAME, TYPE, PACK_MACRO, UNPACK_MACRO, EXTRA_MEMBERS) \
17 DEFINED_JUDYL_CHECK_SIZE(TYPE, NAME); \
18 \
19 typedef struct { \
20 Pvoid_t judyl; \
21 EXTRA_MEMBERS \
22 } NAME##_JudyLSet; \
23 ALWAYS_INLINE \
24 static __attribute__((unused)) void NAME##_INIT(NAME##_JudyLSet *set) { \
25 set->judyl = NULL; \
26 } \
27 \
28 ALWAYS_INLINE \
29 static bool __attribute__((unused)) NAME##_SET(NAME##_JudyLSet *set, Word_t index, TYPE value) { \
30 Pvoid_t *pValue = JudyLIns(&set->judyl, index, PJE0); \
31 if (pValue == PJERR) return false; \
32 *pValue = (void *)PACK_MACRO(value); \
33 return true; \
34 } \
35 \
36 ALWAYS_INLINE \
37 static TYPE __attribute__((unused)) NAME##_GET(NAME##_JudyLSet *set, Word_t index) { \
38 Pvoid_t *pValue = JudyLGet(set->judyl, index, PJE0); \
39 return (pValue != NULL) ? (TYPE)UNPACK_MACRO(*pValue) : (TYPE){0}; \
40 } \
41 \
42 ALWAYS_INLINE \
43 static bool __attribute__((unused)) NAME##_DEL(NAME##_JudyLSet *set, Word_t index) { \
44 return JudyLDel(&set->judyl, index, PJE0) == 1; \
45 } \
46 \
47 ALWAYS_INLINE \
48 static TYPE __attribute__((unused)) NAME##_FIRST(NAME##_JudyLSet *set, Word_t *index) { \
49 Pvoid_t *pValue = JudyLFirst(set->judyl, index, PJE0); \
50 return (pValue != NULL) ? (TYPE)UNPACK_MACRO(*pValue) : (TYPE){0}; \
51 } \
52 \
53 ALWAYS_INLINE \
54 static TYPE __attribute__((unused)) NAME##_NEXT(NAME##_JudyLSet *set, Word_t *index) { \
55 Pvoid_t *pValue = JudyLNext(set->judyl, index, PJE0); \
56 return (pValue != NULL) ? (TYPE)UNPACK_MACRO(*pValue) : (TYPE){0}; \
57 } \
58 \
59 ALWAYS_INLINE \
60 static TYPE __attribute__((unused)) NAME##_LAST(NAME##_JudyLSet *set, Word_t *index) { \
61 Pvoid_t *pValue = JudyLLast(set->judyl, index, PJE0); \
62 return (pValue != NULL) ? (TYPE)UNPACK_MACRO(*pValue) : (TYPE){0}; \
63 } \
64 \
65 ALWAYS_INLINE \
66 static TYPE __attribute__((unused)) NAME##_PREV(NAME##_JudyLSet *set, Word_t *index) { \
67 Pvoid_t *pValue = JudyLPrev(set->judyl, index, PJE0); \
68 return (pValue != NULL) ? (TYPE)UNPACK_MACRO(*pValue) : (TYPE){0}; \
69 } \
70 \
71 ALWAYS_INLINE \
72 static void __attribute__((unused)) NAME##_FREE(NAME##_JudyLSet *set, void (*callback)(Word_t, TYPE, void *), void *data) { \
73 Word_t index = 0; \
74 Pvoid_t *pValue; \
75 if (callback) { \
76 for (pValue = JudyLFirst(set->judyl, &index, PJE0); \
77 pValue != NULL; \
78 pValue = JudyLNext(set->judyl, &index, PJE0)) { \
79 callback(index, (TYPE)UNPACK_MACRO(*pValue), data); \
80 } \
81 } \
82 JudyLFreeArray(&set->judyl, PJE0); \
83 }
84
85 // Basic macro for types with no conversion
86 #define JUDYL_TYPED_NO_CONVERSION(value) (uintptr_t)(value)
87
88 #define DEFINE_JUDYL_TYPED(NAME, TYPE) \
89 DEFINE_JUDYL_TYPED_ADVANCED(NAME, TYPE, JUDYL_TYPED_NO_CONVERSION, JUDYL_TYPED_NO_CONVERSION,)
90
91 #endif //NETDATA_JUDYL_TYPED_H