1: #if !defined(PETSC_HASHSET_H)
  2: #define PETSC_HASHSET_H
  4: #include <petsc/private/hashtable.h>
  6: /*MC
  7:   PETSC_HASH_SET - Instantiate a PETSc hash table set type
  9:   Synopsis:
 10: #include <petsc/private/hashset.h>
 11:   PETSC_HASH_SET(HSetT, KeyType, HashFunc, EqualFunc)
 13:   Input Parameters:
 14: + HSetT - The hash table set type name suffix
 15: . KeyType - The type of entries
 16: . HashFunc - Routine or function-like macro computing hash values from entries
 17: - EqualFunc - Routine or function-like macro computing whether two values are equal
 19:   Level: developer
 21: .seealso: PetscHSetT, PetscHSetTCreate()
 22: M*/
 24: /*S
 25:   PetscHSetT - Hash table set
 27:   Synopsis:
 28:   typedef khash_t(HSetT) *PetscHSetT;
 30:   Level: developer
 32: .seealso:  PETSC_HASH_SET(), PetscHSetTCreate()
 33: S*/
 35: /*MC
 36:   PetscHSetTCreate - Create a hash table
 38:   Synopsis:
 39: #include <petsc/private/hashset.h>
 40:   PetscErrorCode PetscHSetTCreate(PetscHSetT *ht)
 42:   Output Parameter:
 43: . ht - The hash table
 45:   Level: developer
 47: .seealso: PetscHSetTDestroy()
 48: M*/
 50: /*MC
 51:   PetscHSetTDestroy - Destroy a hash table
 53:   Synopsis:
 54: #include <petsc/private/hashset.h>
 55:   PetscErrorCode PetscHSetTDestroy(PetscHSetT *ht)
 57:   Input Parameter:
 58: . ht - The hash table
 60:   Level: developer
 62: .seealso: PetscHSetTCreate()
 63: M*/
 65: /*MC
 66:   PetscHSetTReset - Reset a hash table
 68:   Synopsis:
 69: #include <petsc/private/hashset.h>
 70:   PetscErrorCode PetscHSetTReset(PetscHSetT ht)
 72:   Input Parameter:
 73: . ht - The hash table
 75:   Level: developer
 77: .seealso: PetscHSetTClear()
 78: M*/
 80: /*MC
 81:   PetscHSetTDuplicate - Duplicate a hash table
 83:   Synopsis:
 84: #include <petsc/private/hashset.h>
 85:   PetscErrorCode PetscHSetTDuplicate(PetscHSetT ht,PetscHSetT *hd)
 87:   Input Parameter:
 88: . ht - The source hash table
 90:   Output Parameter:
 91: . ht - The duplicated hash table
 93:   Level: developer
 95: .seealso: PetscHSetTCreate()
 96: M*/
 98: /*MC
 99:   PetscHSetTUpdate - Add entries from a hash table to another
101:   Synopsis:
102: #include <petsc/private/hashset.h>
103:   PetscErrorCode PetscHSetTUpdate(PetscHSetT ht,PetscHSetT hda)
105:   Input Parameter:
106: + ht - The hash table to which elements are added
107: - hta - The hash table from which the elements are retrieved
109:   Output Parameter:
110: . ht - The hash table filled with the elements from the other hash table
112:   Level: developer
114: .seealso: PetscHSetTCreate(), PetscHSetTDuplicate()
115: M*/
117: /*MC
118:   PetscHSetTClear - Clear a hash table
120:   Synopsis:
121: #include <petsc/private/hashset.h>
122:   PetscErrorCode PetscHSetTClear(PetscHSetT ht)
124:   Input Parameter:
125: . ht - The hash table
127:   Level: developer
129: .seealso: PetscHSetTReset()
130: M*/
132: /*MC
133:   PetscHSetTResize - Set the number of buckets in a hash table
135:   Synopsis:
136: #include <petsc/private/hashset.h>
137:   PetscErrorCode PetscHSetTResize(PetscHSetT ht,PetscInt nb)
139:   Input Parameters:
140: + ht - The hash table
141: - nb - The number of buckets
143:   Level: developer
145: .seealso: PetscHSetTCreate()
146: M*/
148: /*MC
149:   PetscHSetTGetSize - Get the number of entries in a hash table
151:   Synopsis:
152: #include <petsc/private/hashset.h>
153:   PetscErrorCode PetscHSetTGetSize(PetscHSetT ht,PetscInt *n)
155:   Input Parameter:
156: . ht - The hash table
158:   Output Parameter:
159: . n - The number of entries
161:   Level: developer
163: .seealso: PetscHSetTResize()
164: M*/
166: /*MC
167:   PetscHSetTGetCapacity - Get the current size of the array in the hash table
169:   Synopsis:
170: #include <petsc/private/hashset.h>
171:   PetscErrorCode PetscHSetTGetCapacity(PetscHSetT ht,PetscInt *n)
173:   Input Parameter:
174: . ht - The hash table
176:   Output Parameter:
177: . n - The capacity
179:   Level: developer
181: .seealso: PetscHSetTResize(), PetscHSetTGetSize()
182: M*/
184: /*MC
185:   PetscHSetTHas - Query for an entry in the hash table
187:   Synopsis:
188: #include <petsc/private/hashset.h>
189:   PetscErrorCode PetscHSetTHas(PetscHSetT ht,KeyType key,PetscBool *has)
191:   Input Parameters:
192: + ht  - The hash table
193: - key - The entry
195:   Output Parameter:
196: . has - Boolean indicating whether the entry is in the hash table
198:   Level: developer
200: .seealso:  PetscHSetTAdd(), PetscHSetTDel()
201: M*/
203: /*MC
204:   PetscHSetTAdd - Set an entry in the hash table
206:   Synopsis:
207: #include <petsc/private/hashset.h>
208:   PetscErrorCode PetscHSetTAdd(PetscHSetT ht,KeyType key)
210:   Input Parameters:
211: + ht  - The hash table
212: - key - The entry
214:   Level: developer
216: .seealso: PetscHSetTDel(), PetscHSetTHas()
217: M*/
219: /*MC
220:   PetscHSetTDel - Remove an entry from the hash table
222:   Synopsis:
223: #include <petsc/private/hashset.h>
224:   PetscErrorCode PetscHSetTDel(PetscHSetT ht,KeyType key)
226:   Input Parameters:
227: + ht  - The hash table
228: - key - The entry
230:   Level: developer
232: .seealso: PetscHSetTAdd(), PetscHSetTHas()
233: M*/
235: /*MC
236:   PetscHSetTQueryAdd - Query and add an entry in the hash table
238:   Synopsis:
239: #include <petsc/private/hashset.h>
240:   PetscErrorCode PetscHSetTQueryAdd(PetscHSetT ht,KeyType key,PetscBool *missing)
242:   Input Parameters:
243: + ht  - The hash table
244: - key - The entry
246:   Output Parameter:
247: . missing - Boolean indicating whether the entry was missing
249:   Level: developer
251: .seealso: PetscHSetTQueryDel(), PetscHSetTAdd()
252: M*/
254: /*MC
255:   PetscHSetTQueryDel - Query and remove an entry from the hash table
257:   Synopsis:
258: #include <petsc/private/hashset.h>
259:   PetscErrorCode PetscHSetTQueryDel(PetscHSetT ht,KeyType key,PetscBool *present)
261:   Input Parameters:
262: + ht  - The hash table
263: - key - The entry
265:   Output Parameter:
266: . present - Boolean indicating whether the entry was present
268:   Level: developer
270: .seealso: PetscHSetTQueryAdd(), PetscHSetTDel()
271: M*/
273: /*MC
274:   PetscHSetTGetElems - Get all entries from a hash table
276:   Synopsis:
277: #include <petsc/private/hashset.h>
278:   PetscErrorCode PetscHSetTGetElems(PetscHSetT ht,PetscInt *off,KeyType array[])
280:   Input Parameters:
281: + ht    - The hash table
282: . off   - Input offset in array (usually zero)
283: - array - Array where to put hash table entries into
285:   Output Parameter:
286: + off   - Output offset in array (output offset = input offset + hash table size)
287: - array - Array filled with the hash table entries
289:   Level: developer
291: .seealso: PetscHSetTGetSize()
292: M*/
294: #define PETSC_HASH_SET(HashT, KeyType, HashFunc, EqualFunc)                                          \
295:                                                                                                      \
296: KHASH_INIT(HashT, KeyType, char, 0, HashFunc, EqualFunc)                                             \
297:                                                                                                      \
298: typedef khash_t(HashT) *Petsc##HashT;                                                                \
299:                                                                                                      \
300: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
301: PetscErrorCode Petsc##HashT##Create(Petsc##HashT *ht)                                                \
302: {                                                                                                    \
305:   *ht = kh_init(HashT);                                                                              \
306:   return(0);                                                                            \
307: }                                                                                                    \
308:                                                                                                      \
309: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
310: PetscErrorCode Petsc##HashT##Destroy(Petsc##HashT *ht)                                               \
311: {                                                                                                    \
314:   if (!*ht) return(0);                                                                  \
315:   kh_destroy(HashT,*ht); *ht = NULL;                                                                 \
316:   return(0);                                                                            \
317: }                                                                                                    \
318:                                                                                                      \
319: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
320: PetscErrorCode Petsc##HashT##Reset(Petsc##HashT ht)                                                  \
321: {                                                                                                    \
324:   kh_reset(HashT,ht);                                                                                \
325:   return(0);                                                                            \
326: }                                                                                                    \
327:                                                                                                      \
328: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
329: PetscErrorCode Petsc##HashT##Duplicate(Petsc##HashT ht,Petsc##HashT *hd)                             \
330: {                                                                                                    \
331:   int     ret;                                                                                       \
332:   KeyType key;                                                                                       \
336:   *hd = kh_init(HashT);                                                                              \
337:   ret = kh_resize(HashT,*hd,kh_size(ht));                                                            \
338:   PetscHashAssert(ret==0);                                                                           \
339:   kh_foreach_key(ht,key,{                                                                            \
340:       kh_put(HashT,*hd,key,&ret);                                                                    \
341:       PetscHashAssert(ret>=0);})                                                                     \
342:   return(0);                                                                            \
343: }                                                                                                    \
344:                                                                                                      \
345: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
346: PetscErrorCode Petsc##HashT##Update(Petsc##HashT ht,Petsc##HashT hta)                                \
347: {                                                                                                    \
348:   int     ret;                                                                                       \
349:   KeyType key;                                                                                       \
353:   kh_foreach_key(hta,key,{                                                                           \
354:       kh_put(HashT,ht,key,&ret);                                                                     \
355:       PetscHashAssert(ret>=0);})                                                                     \
356:   return(0);                                                                            \
357: }                                                                                                    \
358:                                                                                                      \
359: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
360: PetscErrorCode Petsc##HashT##Clear(Petsc##HashT ht)                                                  \
361: {                                                                                                    \
364:   kh_clear(HashT,ht);                                                                                \
365:   return(0);                                                                            \
366: }                                                                                                    \
367:                                                                                                      \
368: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
369: PetscErrorCode Petsc##HashT##Resize(Petsc##HashT ht,PetscInt nb)                                     \
370: {                                                                                                    \
371:   int ret;                                                                                           \
374:   ret = kh_resize(HashT,ht,(khint_t)nb);                                                             \
375:   PetscHashAssert(ret==0);                                                                           \
376:   return(0);                                                                            \
377: }                                                                                                    \
378:                                                                                                      \
379: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
380: PetscErrorCode Petsc##HashT##GetSize(Petsc##HashT ht,PetscInt *n)                                    \
381: {                                                                                                    \
385:   *n = (PetscInt)kh_size(ht);                                                                        \
386:   return(0);                                                                            \
387: }                                                                                                    \
388:                                                                                                      \
389: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
390: PetscErrorCode Petsc##HashT##GetCapacity(Petsc##HashT ht,PetscInt *n)                                \
391: {                                                                                                    \
395:   *n = (PetscInt)kh_n_buckets(ht);                                                                   \
396:   return(0);                                                                            \
397: }                                                                                                    \
398:                                                                                                      \
399: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
400: PetscErrorCode Petsc##HashT##Has(Petsc##HashT ht,KeyType key,PetscBool *has)                         \
401: {                                                                                                    \
402:   khiter_t iter;                                                                                     \
406:   iter = kh_get(HashT,ht,key);                                                                       \
407:   *has = (iter != kh_end(ht)) ? PETSC_TRUE : PETSC_FALSE;                                            \
408:   return(0);                                                                            \
409: }                                                                                                    \
410:                                                                                                      \
411: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
412: PetscErrorCode Petsc##HashT##Add(Petsc##HashT ht,KeyType key)                                        \
413: {                                                                                                    \
414:   int      ret;                                                                                      \
415:   khiter_t iter;                                                                                     \
418:   iter = kh_put(HashT,ht,key,&ret); (void)iter;                                                      \
419:   PetscHashAssert(ret>=0);                                                                           \
420:   return(0);                                                                            \
421: }                                                                                                    \
422:                                                                                                      \
423: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
424: PetscErrorCode Petsc##HashT##Del(Petsc##HashT ht,KeyType key)                                        \
425: {                                                                                                    \
426:   khiter_t iter;                                                                                     \
429:   iter = kh_get(HashT,ht,key);                                                                       \
430:   kh_del(HashT,ht,iter);                                                                             \
431:   return(0);                                                                            \
432: }                                                                                                    \
433:                                                                                                      \
434: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
435: PetscErrorCode Petsc##HashT##QueryAdd(Petsc##HashT ht,KeyType key,PetscBool *missing)                \
436: {                                                                                                    \
437:   int      ret;                                                                                      \
438:   khiter_t iter;                                                                                     \
442:   iter = kh_put(HashT,ht,key,&ret); (void)iter;                                                      \
443:   PetscHashAssert(ret>=0);                                                                           \
444:   *missing = ret ? PETSC_TRUE : PETSC_FALSE;                                                         \
445:   return(0);                                                                            \
446: }                                                                                                    \
447:                                                                                                      \
448: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
449: PetscErrorCode Petsc##HashT##QueryDel(Petsc##HashT ht,KeyType key,PetscBool *present)                \
450: {                                                                                                    \
451:   khiter_t iter;                                                                                     \
455:   iter = kh_get(HashT,ht,key);                                                                       \
456:   if (iter != kh_end(ht)) {                                                                          \
457:     kh_del(HashT,ht,iter);                                                                           \
458:     *present = PETSC_TRUE;                                                                           \
459:   } else {                                                                                           \
460:     *present = PETSC_FALSE;                                                                          \
461:   }                                                                                                  \
462:   return(0);                                                                            \
463: }                                                                                                    \
464:                                                                                                      \
465: PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
466: PetscErrorCode Petsc##HashT##GetElems(Petsc##HashT ht,PetscInt *off,KeyType array[])                 \
467: {                                                                                                    \
468:   KeyType  key;                                                                                      \
469:   PetscInt pos;                                                                                      \
473:   pos = *off;                                                                                        \
474:   kh_foreach_key(ht,key,array[pos++] = key);                                                         \
475:   *off = pos;                                                                                        \
476:   return(0);                                                                            \
477: }                                                                                                    \
479: #endif /* PETSC_HASHSET_H */