1 #pragma once 2 3 #include <petsc/private/hashtable.h> 4 5 /* MANSEC = Sys */ 6 /* SUBMANSEC = PetscH */ 7 8 /*MC 9 PETSC_HASH_SET - Instantiate a new PETSc hash set type 10 11 Synopsis: 12 #include <petsc/private/hashset.h> 13 PETSC_HASH_SET(HSetT, KeyType, HashFunc, EqualFunc) 14 15 Input Parameters: 16 + HSetT - The hash set type name suffix, i.e. the name of the object created is PetscHSet<HSetT> 17 . KeyType - The type of entries, may be a basic type such as int or a struct 18 . HashFunc - Routine or function-like macro that computes hash values from entries 19 - EqualFunc - Routine or function-like macro that computes whether two values are equal 20 21 Level: developer 22 23 Note: 24 This code uses the standalone and portable C language khash software <https://github.com/attractivechaos/klib> 25 26 Developer Note: 27 Each time this macro is used to create a new hash set type, the make rule for allmanpages in $PETSC_DIR/makefile should 28 be updated to cause the automatic generation of appropriate manual pages for that type. The manual pages 29 are generated from the templated version of the documentation in include/petsc/private/hashset.txt. 30 31 .seealso: `PetscHSetI`, `PetscHSetICreate()`, `PetscHSetIJ`, `PetscHSetIJCreate()`, `PETSC_HASH_MAP()` 32 M*/ 33 34 #define PETSC_HASH_SET(HashT, KeyType, HashFunc, EqualFunc) \ 35 \ 36 KHASH_INIT(HashT, KeyType, char, 0, HashFunc, EqualFunc) \ 37 \ 38 typedef khash_t(HashT) *Petsc##HashT; \ 39 \ 40 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##Create(Petsc##HashT *ht) \ 41 { \ 42 PetscFunctionBegin; \ 43 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 44 *ht = kh_init(HashT); \ 45 PetscFunctionReturn(PETSC_SUCCESS); \ 46 } \ 47 \ 48 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##Destroy(Petsc##HashT *ht) \ 49 { \ 50 PetscFunctionBegin; \ 51 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 52 if (!*ht) PetscFunctionReturn(PETSC_SUCCESS); \ 53 kh_destroy(HashT, *ht); \ 54 *ht = NULL; \ 55 PetscFunctionReturn(PETSC_SUCCESS); \ 56 } \ 57 \ 58 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##Reset(Petsc##HashT ht) \ 59 { \ 60 PetscFunctionBegin; \ 61 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 62 kh_reset(HashT, ht); \ 63 PetscFunctionReturn(PETSC_SUCCESS); \ 64 } \ 65 \ 66 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##Duplicate(Petsc##HashT ht, Petsc##HashT *hd) \ 67 { \ 68 int ret; \ 69 KeyType key; \ 70 PetscFunctionBegin; \ 71 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 72 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(hd, 2)); \ 73 *hd = kh_init(HashT); \ 74 ret = kh_resize(HashT, *hd, kh_size(ht)); \ 75 PetscHashAssert(ret == 0); \ 76 kh_foreach_key(ht, key, { \ 77 kh_put(HashT, *hd, key, &ret); \ 78 PetscHashAssert(ret >= 0); \ 79 }) PetscFunctionReturn(PETSC_SUCCESS); \ 80 } \ 81 \ 82 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##Update(Petsc##HashT ht, Petsc##HashT hta) \ 83 { \ 84 int ret; \ 85 KeyType key; \ 86 PetscFunctionBegin; \ 87 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 88 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(hta, 2)); \ 89 kh_foreach_key(hta, key, { \ 90 kh_put(HashT, ht, key, &ret); \ 91 PetscHashAssert(ret >= 0); \ 92 }) PetscFunctionReturn(PETSC_SUCCESS); \ 93 } \ 94 \ 95 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##Clear(Petsc##HashT ht) \ 96 { \ 97 PetscFunctionBegin; \ 98 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 99 kh_clear(HashT, ht); \ 100 PetscFunctionReturn(PETSC_SUCCESS); \ 101 } \ 102 \ 103 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##Resize(Petsc##HashT ht, PetscInt nb) \ 104 { \ 105 int ret; \ 106 PetscFunctionBegin; \ 107 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 108 ret = kh_resize(HashT, ht, (khint_t)nb); \ 109 PetscHashAssert(ret == 0); \ 110 PetscFunctionReturn(PETSC_SUCCESS); \ 111 } \ 112 \ 113 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##GetSize(Petsc##HashT ht, PetscInt *n) \ 114 { \ 115 PetscFunctionBegin; \ 116 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 117 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(n, 2)); \ 118 *n = (PetscInt)kh_size(ht); \ 119 PetscFunctionReturn(PETSC_SUCCESS); \ 120 } \ 121 \ 122 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##GetCapacity(Petsc##HashT ht, PetscInt *n) \ 123 { \ 124 PetscFunctionBegin; \ 125 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 126 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(n, 2)); \ 127 *n = (PetscInt)kh_n_buckets(ht); \ 128 PetscFunctionReturn(PETSC_SUCCESS); \ 129 } \ 130 \ 131 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##Has(Petsc##HashT ht, KeyType key, PetscBool *has) \ 132 { \ 133 khiter_t iter; \ 134 PetscFunctionBeginHot; \ 135 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 136 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(has, 3)); \ 137 iter = kh_get(HashT, ht, key); \ 138 *has = (iter != kh_end(ht)) ? PETSC_TRUE : PETSC_FALSE; \ 139 PetscFunctionReturn(PETSC_SUCCESS); \ 140 } \ 141 \ 142 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##Add(Petsc##HashT ht, KeyType key) \ 143 { \ 144 int ret; \ 145 PETSC_UNUSED khiter_t iter; \ 146 PetscFunctionBeginHot; \ 147 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 148 iter = kh_put(HashT, ht, key, &ret); \ 149 (void)iter; \ 150 PetscHashAssert(ret >= 0); \ 151 PetscFunctionReturn(PETSC_SUCCESS); \ 152 } \ 153 \ 154 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##Del(Petsc##HashT ht, KeyType key) \ 155 { \ 156 khiter_t iter; \ 157 PetscFunctionBeginHot; \ 158 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 159 iter = kh_get(HashT, ht, key); \ 160 kh_del(HashT, ht, iter); \ 161 PetscFunctionReturn(PETSC_SUCCESS); \ 162 } \ 163 \ 164 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##QueryAdd(Petsc##HashT ht, KeyType key, PetscBool *missing) \ 165 { \ 166 int ret; \ 167 PETSC_UNUSED khiter_t iter; \ 168 PetscFunctionBeginHot; \ 169 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 170 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(missing, 3)); \ 171 iter = kh_put(HashT, ht, key, &ret); \ 172 (void)iter; \ 173 PetscHashAssert(ret >= 0); \ 174 *missing = ret ? PETSC_TRUE : PETSC_FALSE; \ 175 PetscFunctionReturn(PETSC_SUCCESS); \ 176 } \ 177 \ 178 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##QueryDel(Petsc##HashT ht, KeyType key, PetscBool *present) \ 179 { \ 180 khiter_t iter; \ 181 PetscFunctionBeginHot; \ 182 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 183 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(present, 3)); \ 184 iter = kh_get(HashT, ht, key); \ 185 if (iter != kh_end(ht)) { \ 186 kh_del(HashT, ht, iter); \ 187 *present = PETSC_TRUE; \ 188 } else { \ 189 *present = PETSC_FALSE; \ 190 } \ 191 PetscFunctionReturn(PETSC_SUCCESS); \ 192 } \ 193 \ 194 static inline PETSC_UNUSED PetscErrorCode Petsc##HashT##GetElems(Petsc##HashT ht, PetscInt *off, KeyType array[]) \ 195 { \ 196 KeyType key; \ 197 PetscInt pos; \ 198 PetscFunctionBegin; \ 199 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(ht, 1)); \ 200 PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscAssertPointer(off, 2)); \ 201 pos = *off; \ 202 kh_foreach_key(ht, key, array[pos++] = key); \ 203 *off = pos; \ 204 PetscFunctionReturn(PETSC_SUCCESS); \ 205 } 206