1 #if !defined(PETSC_HASHMAP_H)
2 #define PETSC_HASHMAP_H
3 
4 #include <petsc/private/hashtable.h>
5 
6 /*MC
7   PETSC_HASH_MAP - Instantiate a PETSc hash table map type
8 
9   Synopsis:
10   #include <petsc/private/hashmap.h>
11   PETSC_HASH_MAP(HMapT, KeyType, ValType, HashFunc, EqualFunc, DefaultValue)
12 
13   Input Parameters:
14 + HMapT - The hash table map type name suffix
15 . KeyType - The type of keys
16 . ValType - The type of values
17 . HashFunc - Routine or function-like macro computing hash values from keys
18 . EqualFunc - Routine or function-like macro computing whether two values are equal
19 - DefaultValue - Default value to use for queries in case of missing keys
20 
21   Level: developer
22 
23 .seealso: PetscHMapT, PetscHMapTCreate()
24 M*/
25 
26 /*S
27   PetscHMapT - Hash table map
28 
29   Synopsis:
30   typedef khash_t(HMapT) *PetscHMapT;
31 
32   Level: developer
33 
34 .seealso:  PETSC_HASH_MAP(), PetscHMapTCreate()
35 S*/
36 
37 /*MC
38   PetscHMapTCreate - Create a hash table
39 
40   Synopsis:
41   #include <petsc/private/hashmap.h>
42   PetscErrorCode PetscHMapTCreate(PetscHMapT *ht)
43 
44   Output Parameter:
45 . ht - The hash table
46 
47   Level: developer
48 
49 .seealso: PetscHMapTDestroy()
50 M*/
51 
52 /*MC
53   PetscHMapTDestroy - Destroy a hash table
54 
55   Synopsis:
56   #include <petsc/private/hashmap.h>
57   PetscErrorCode PetscHMapTDestroy(PetscHMapT *ht)
58 
59   Input Parameter:
60 . ht - The hash table
61 
62   Level: developer
63 
64 .seealso: PetscHMapTCreate()
65 M*/
66 
67 /*MC
68   PetscHMapTReset - Reset a hash table
69 
70   Synopsis:
71   #include <petsc/private/hashmap.h>
72   PetscErrorCode PetscHMapTReset(PetscHMapT ht)
73 
74   Input Parameter:
75 . ht - The hash table
76 
77   Level: developer
78 
79 .seealso: PetscHMapTClear()
80 M*/
81 
82 /*MC
83   PetscHMapTDuplicate - Duplicate a hash table
84 
85   Synopsis:
86   #include <petsc/private/hashmap.h>
87   PetscErrorCode PetscHMapTDuplicate(PetscHMapT ht,PetscHMapT *hd)
88 
89   Input Parameter:
90 . ht - The source hash table
91 
92   Output Parameter:
93 . ht - The duplicated hash table
94 
95   Level: developer
96 
97 .seealso: PetscHMapTCreate()
98 M*/
99 
100 /*MC
101   PetscHMapTClear - Clear a hash table
102 
103   Synopsis:
104   #include <petsc/private/hashmap.h>
105   PetscErrorCode PetscHMapTClear(PetscHMapT ht)
106 
107   Input Parameter:
108 . ht - The hash table
109 
110   Level: developer
111 
112 .seealso: PetscHMapTReset()
113 M*/
114 
115 /*MC
116   PetscHMapTResize - Set the number of buckets in a hash table
117 
118   Synopsis:
119   #include <petsc/private/hashmap.h>
120   PetscErrorCode PetscHMapTResize(PetscHMapT ht,PetscInt nb)
121 
122   Input Parameters:
123 + ht - The hash table
124 - nb - The number of buckets
125 
126   Level: developer
127 
128 .seealso: PetscHMapTCreate()
129 M*/
130 
131 /*MC
132   PetscHMapTGetSize - Get the number of entries in a hash table
133 
134   Synopsis:
135   #include <petsc/private/hashmap.h>
136   PetscErrorCode PetscHMapTGetSize(PetscHMapT ht,PetscInt *n)
137 
138   Input Parameter:
139 . ht - The hash table
140 
141   Output Parameter:
142 . n - The number of entries
143 
144   Level: developer
145 
146 .seealso: PetscHMapTResize()
147 M*/
148 
149 /*MC
150   PetscHMapTGetCapacity - Get the current size of the array in the hash table
151 
152   Synopsis:
153   #include <petsc/private/hashmap.h>
154   PetscErrorCode PetscHMapTGetCapacity(PetscHMapT ht,PetscInt *n)
155 
156   Input Parameter:
157 . ht - The hash table
158 
159   Output Parameter:
160 . n - The capacity
161 
162   Level: developer
163 
164 .seealso: PetscHMapTResize(), PetscHMapTGetSize()
165 M*/
166 
167 /*MC
168   PetscHMapTHas - Query for a key in the hash table
169 
170   Synopsis:
171   #include <petsc/private/hashmap.h>
172   PetscErrorCode PetscHMapTHas(PetscHMapT ht,KeyType key,PetscBool *has)
173 
174   Input Parameters:
175 + ht  - The hash table
176 - key - The key
177 
178   Output Parameter:
179 . has - Boolean indicating whether key is in the hash table
180 
181   Level: developer
182 
183 .seealso:  PetscHMapTGet(), PetscHMapTSet(), PetscHMapTFind()
184 M*/
185 
186 /*MC
187   PetscHMapTGet - Get the value for a key in the hash table
188 
189   Synopsis:
190   #include <petsc/private/hashmap.h>
191   PetscErrorCode PetscHMapTGet(PetscHMapT ht,KeyType key,ValType *val)
192 
193   Input Parameters:
194 + ht  - The hash table
195 - key - The key
196 
197   Output Parameter:
198 . val - The value
199 
200   Level: developer
201 
202 .seealso:  PetscHMapTSet(), PetscHMapTIterGet()
203 M*/
204 
205 /*MC
206   PetscHMapTSet - Set a (key,value) entry in the hash table
207 
208   Synopsis:
209   #include <petsc/private/hashmap.h>
210   PetscErrorCode PetscHMapTSet(PetscHMapT ht,KeyType key,ValType val)
211 
212   Input Parameters:
213 + ht  - The hash table
214 . key - The key
215 - val - The value
216 
217   Level: developer
218 
219 .seealso: PetscHMapTGet(), PetscHMapTIterSet()
220 M*/
221 
222 /*MC
223   PetscHMapTDel - Remove a key and its value from the hash table
224 
225   Synopsis:
226   #include <petsc/private/hashmap.h>
227   PetscErrorCode PetscHMapTDel(PetscHMapT ht,KeyType key)
228 
229   Input Parameters:
230 + ht  - The hash table
231 - key - The key
232 
233   Level: developer
234 
235 .seealso: PetscHMapTHas(), PetscHMapTIterDel()
236 M*/
237 
238 /*MC
239   PetscHMapTQuerySet - Query and set a (key,value) entry in the hash table
240 
241   Synopsis:
242   #include <petsc/private/hashmap.h>
243   PetscErrorCode PetscHMapTQuerySet(PetscHMapT ht,KeyType key,ValType val,PetscBool *missing)
244 
245   Input Parameters:
246 + ht  - The hash table
247 . key - The key
248 - val - The value
249 
250   Output Parameter:
251 . missing - Boolean indicating whether the key was missing
252 
253   Level: developer
254 
255 .seealso: PetscHMapTQueryDel(), PetscHMapTSet()
256 M*/
257 
258 /*MC
259   PetscHMapTQueryDel - Query and remove a (key,value) entry from the hash table
260 
261   Synopsis:
262   #include <petsc/private/hashmap.h>
263   PetscErrorCode PetscHMapTQueryDel(PetscHMapT ht,KeyType key,PetscBool *present)
264 
265   Input Parameters:
266 + ht  - The hash table
267 - key - The key
268 
269   Output Parameter:
270 . present - Boolean indicating whether the key was present
271 
272   Level: developer
273 
274 .seealso: PetscHMapTQuerySet(), PetscHMapTDel()
275 M*/
276 
277 /*MC
278   PetscHMapTFind - Query for key in the hash table
279 
280   Synopsis:
281   #include <petsc/private/hashmap.h>
282   PetscErrorCode PetscHMapTFind(PetscHMapT ht,KeyType key,PetscHashIter *iter,PetscBool *found)
283 
284   Input Parameters:
285 + ht  - The hash table
286 - key - The key
287 
288   Output Parameter:
289 + iter - Iterator referencing the value for key
290 - found - Boolean indicating whether the key was present
291 
292   Level: developer
293 
294 .seealso: PetscHMapTIterGet(), PetscHMapTIterDel()
295 M*/
296 
297 /*MC
298   PetscHMapTPut - Set a key in the hash table
299 
300   Synopsis:
301   #include <petsc/private/hashmap.h>
302   PetscErrorCode PetscHMapTPut(PetscHMapT ht,KeyType key,PetscHashIter *iter,PetscBool *missing)
303 
304   Input Parameters:
305 + ht  - The hash table
306 - key - The key
307 
308   Output Parameter:
309 + iter - Iterator referencing the value for key
310 - missing - Boolean indicating whether the key was missing
311 
312   Level: developer
313 
314 .seealso: PetscHMapTIterSet(), PetscHMapTQuerySet(), PetscHMapTSet()
315 M*/
316 
317 /*MC
318   PetscHMapTIterGet - Get the value referenced by an iterator in the hash table
319 
320   Synopsis:
321   #include <petsc/private/hashmap.h>
322   PetscErrorCode PetscHMapTIterGet(PetscHMapT ht,PetscHashIter iter,ValType *val)
323 
324   Input Parameters:
325 + ht   - The hash table
326 - iter - The iterator
327 
328   Output Parameter:
329 . val  - The value
330 
331   Level: developer
332 
333 .seealso: PetscHMapTFind(), PetscHMapTGet()
334 M*/
335 
336 /*MC
337   PetscHMapTIterSet - Set the value referenced by an iterator in the hash
338 
339   Synopsis:
340   #include <petsc/private/hashmap.h>
341   PetscErrorCode PetscHMapTIterSet(PetscHMapT ht,PetscHashIter iter,ValType val)
342 
343   Input Parameters:
344 + ht   - The hash table
345 . iter - The iterator
346 - val  - The value
347 
348   Level: developer
349 
350 .seealso: PetscHMapTPut(), PetscHMapTQuerySet(), PetscHMapTSet()
351 M*/
352 
353 /*MC
354   PetscHMapTIterDel - Remove the (key,value) referenced by an iterator from the hash table
355 
356   Synopsis:
357   #include <petsc/private/hashmap.h>
358   PetscErrorCode PetscHMapTIterDel(PetscHMapT ht,PetscHashIter iter)
359 
360   Input Parameters:
361 + ht   - The hash table
362 - iter - The iterator
363 
364   Level: developer
365 
366 .seealso: PetscHMapTFind(), PetscHMapTQueryDel(), PetscHMapTDel()
367 M*/
368 
369 /*MC
370   PetscHMapTGetKeys - Get all keys from a hash table
371 
372   Synopsis:
373   #include <petsc/private/hashmap.h>
374   PetscErrorCode PetscHMapTGetKeys(PetscHMapT ht,PetscInt *off,KeyType array[])
375 
376   Input Parameters:
377 + ht    - The hash table
378 . off   - Input offset in array (usually zero)
379 - array - Array where to put hash table keys into
380 
381   Output Parameter:
382 + off   - Output offset in array (output offset = input offset + hash table size)
383 - array - Array filled with the hash table keys
384 
385   Level: developer
386 
387 .seealso: PetscHSetTGetSize(), PetscHMapTGetVals()
388 M*/
389 
390 /*MC
391   PetscHMapTGetVals - Get all values from a hash table
392 
393   Synopsis:
394   #include <petsc/private/hashmap.h>
395   PetscErrorCode PetscHMapTGetVals(PetscHMapT ht,PetscInt *off,ValType array[])
396 
397   Input Parameters:
398 + ht    - The hash table
399 . off   - Input offset in array (usually zero)
400 - array - Array where to put hash table values into
401 
402   Output Parameter:
403 + off   - Output offset in array (output offset = input offset + hash table size)
404 - array - Array filled with the hash table values
405 
406   Level: developer
407 
408 .seealso: PetscHSetTGetSize(), PetscHMapTGetKeys()
409 M*/
410 
411 /*MC
412   PetscHMapTGetPairs - Get all (key,value) pairs from a hash table
413 
414   Synopsis:
415   #include <petsc/private/hashmap.h>
416   PetscErrorCode PetscHMapTGetPairs(PetscHMapT ht,PetscInt *off,KeyType karray[],ValType varray[])
417 
418   Input Parameters:
419 + ht    - The hash table
420 . off   - Input offset in array (usually zero)
421 - karray - Array where to put hash table keys into
422 - varray - Array where to put hash table values into
423 
424   Output Parameter:
425 + off   - Output offset in array (output offset = input offset + hash table size)
426 - karray - Array filled with the hash table keys
427 - varray - Array filled with the hash table values
428 
429   Level: developer
430 
431 .seealso: PetscHSetTGetSize(), PetscHMapTGetKeys(), PetscHMapTGetVals()
432 M*/
433 
434 #define PETSC_HASH_MAP(HashT, KeyType, ValType, HashFunc, EqualFunc, DefaultValue)                   \
435                                                                                                      \
436 KHASH_INIT(HashT, KeyType, ValType, 1, HashFunc, EqualFunc)                                          \
437                                                                                                      \
438 typedef khash_t(HashT) *Petsc##HashT;                                                                \
439                                                                                                      \
440 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
441 PetscErrorCode Petsc##HashT##Create(Petsc##HashT *ht)                                                \
442 {                                                                                                    \
443   PetscFunctionBegin;                                                                                \
444   PetscValidPointer(ht,1);                                                                           \
445   *ht = kh_init(HashT);                                                                              \
446   PetscHashAssert(*ht!=NULL);                                                                        \
447   PetscFunctionReturn(0);                                                                            \
448 }                                                                                                    \
449                                                                                                      \
450 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
451 PetscErrorCode Petsc##HashT##Destroy(Petsc##HashT *ht)                                               \
452 {                                                                                                    \
453   PetscFunctionBegin;                                                                                \
454   PetscValidPointer(ht,1);                                                                           \
455   if (!*ht) PetscFunctionReturn(0);                                                                  \
456   kh_destroy(HashT,*ht); *ht = NULL;                                                                 \
457   PetscFunctionReturn(0);                                                                            \
458 }                                                                                                    \
459                                                                                                      \
460 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
461 PetscErrorCode Petsc##HashT##Reset(Petsc##HashT ht)                                                  \
462 {                                                                                                    \
463   PetscFunctionBegin;                                                                                \
464   PetscValidPointer(ht,1);                                                                           \
465   kh_reset(HashT,ht);                                                                                \
466   PetscFunctionReturn(0);                                                                            \
467 }                                                                                                    \
468                                                                                                      \
469 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
470 PetscErrorCode Petsc##HashT##Duplicate(Petsc##HashT ht,Petsc##HashT *hd)                             \
471 {                                                                                                    \
472   int     ret;                                                                                       \
473   KeyType key;                                                                                       \
474   ValType val;                                                                                       \
475   PetscFunctionBegin;                                                                                \
476   PetscValidPointer(ht,1);                                                                           \
477   PetscValidPointer(hd,2);                                                                           \
478   *hd = kh_init(HashT);                                                                              \
479   PetscHashAssert(*hd!=NULL);                                                                        \
480   ret = kh_resize(HashT,*hd,kh_size(ht));                                                            \
481   PetscHashAssert(ret==0);                                                                           \
482   kh_foreach(ht,key,val,{ khiter_t i;                                                                \
483       i = kh_put(HashT,*hd,key,&ret);                                                                \
484       PetscHashAssert(ret>=0);                                                                       \
485       kh_val(*hd,i) = val;})                                                                         \
486   PetscFunctionReturn(0);                                                                            \
487 }                                                                                                    \
488                                                                                                      \
489 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
490 PetscErrorCode Petsc##HashT##Clear(Petsc##HashT ht)                                                  \
491 {                                                                                                    \
492   PetscFunctionBegin;                                                                                \
493   PetscValidPointer(ht,1);                                                                           \
494   kh_clear(HashT,ht);                                                                                \
495   PetscFunctionReturn(0);                                                                            \
496 }                                                                                                    \
497                                                                                                      \
498 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
499 PetscErrorCode Petsc##HashT##Resize(Petsc##HashT ht,PetscInt nb)                                     \
500 {                                                                                                    \
501   int ret;                                                                                           \
502   PetscFunctionBegin;                                                                                \
503   PetscValidPointer(ht,1);                                                                           \
504   ret = kh_resize(HashT,ht,(khint_t)nb);                                                             \
505   PetscHashAssert(ret>=0);                                                                           \
506   PetscFunctionReturn(0);                                                                            \
507 }                                                                                                    \
508                                                                                                      \
509 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
510 PetscErrorCode Petsc##HashT##GetSize(Petsc##HashT ht,PetscInt *n)                                    \
511 {                                                                                                    \
512   PetscFunctionBegin;                                                                                \
513   PetscValidPointer(ht,1);                                                                           \
514   PetscValidIntPointer(n,2);                                                                         \
515   *n = (PetscInt)kh_size(ht);                                                                        \
516   PetscFunctionReturn(0);                                                                            \
517 }                                                                                                    \
518                                                                                                      \
519 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
520 PetscErrorCode Petsc##HashT##GetCapacity(Petsc##HashT ht,PetscInt *n)                                \
521 {                                                                                                    \
522   PetscFunctionBegin;                                                                                \
523   PetscValidPointer(ht,1);                                                                           \
524   PetscValidIntPointer(n,2);                                                                         \
525   *n = (PetscInt)kh_n_buckets(ht);                                                                   \
526   PetscFunctionReturn(0);                                                                            \
527 }                                                                                                    \
528                                                                                                      \
529 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
530 PetscErrorCode Petsc##HashT##Has(Petsc##HashT ht,KeyType key,PetscBool *has)                         \
531 {                                                                                                    \
532   khiter_t iter;                                                                                     \
533   PetscFunctionBeginHot;                                                                             \
534   PetscValidPointer(ht,1);                                                                           \
535   PetscValidPointer(has,3);                                                                          \
536   iter = kh_get(HashT,ht,key);                                                                       \
537   *has = (iter != kh_end(ht)) ? PETSC_TRUE : PETSC_FALSE;                                            \
538   PetscFunctionReturn(0);                                                                            \
539 }                                                                                                    \
540                                                                                                      \
541 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
542 PetscErrorCode Petsc##HashT##Get(Petsc##HashT ht,KeyType key,ValType *val)                           \
543 {                                                                                                    \
544   khiter_t iter;                                                                                     \
545   PetscFunctionBeginHot;                                                                             \
546   PetscValidPointer(ht,1);                                                                           \
547   PetscValidIntPointer(val,3);                                                                       \
548   iter = kh_get(HashT,ht,key);                                                                       \
549   *val = (iter != kh_end(ht)) ? kh_val(ht,iter) : (DefaultValue);                                    \
550   PetscFunctionReturn(0);                                                                            \
551 }                                                                                                    \
552                                                                                                      \
553 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
554 PetscErrorCode Petsc##HashT##Set(Petsc##HashT ht,KeyType key,ValType val)                            \
555 {                                                                                                    \
556   int      ret;                                                                                      \
557   khiter_t iter;                                                                                     \
558   PetscFunctionBeginHot;                                                                             \
559   PetscValidPointer(ht,1);                                                                           \
560   iter = kh_put(HashT,ht,key,&ret);                                                                  \
561   PetscHashAssert(ret>=0);                                                                           \
562   kh_val(ht,iter) = val;                                                                             \
563   PetscFunctionReturn(0);                                                                            \
564 }                                                                                                    \
565                                                                                                      \
566 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
567 PetscErrorCode Petsc##HashT##Del(Petsc##HashT ht,KeyType key)                                        \
568 {                                                                                                    \
569   khiter_t iter;                                                                                     \
570   PetscFunctionBeginHot;                                                                             \
571   PetscValidPointer(ht,1);                                                                           \
572   iter = kh_get(HashT,ht,key);                                                                       \
573   kh_del(HashT,ht,iter);                                                                             \
574   PetscFunctionReturn(0);                                                                            \
575 }                                                                                                    \
576                                                                                                      \
577 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
578 PetscErrorCode Petsc##HashT##QuerySet(Petsc##HashT ht,KeyType key,ValType val,PetscBool *missing)    \
579 {                                                                                                    \
580   int      ret;                                                                                      \
581   khiter_t iter;                                                                                     \
582   PetscFunctionBeginHot;                                                                             \
583   PetscValidPointer(ht,1);                                                                           \
584   PetscValidPointer(missing,3);                                                                      \
585   iter = kh_put(HashT,ht,key,&ret);                                                                  \
586   PetscHashAssert(ret>=0);                                                                           \
587   kh_val(ht,iter) = val;                                                                             \
588   *missing = ret ? PETSC_TRUE : PETSC_FALSE;                                                         \
589   PetscFunctionReturn(0);                                                                            \
590 }                                                                                                    \
591                                                                                                      \
592 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
593 PetscErrorCode Petsc##HashT##QueryDel(Petsc##HashT ht,KeyType key,PetscBool *present)                \
594 {                                                                                                    \
595   khiter_t iter;                                                                                     \
596   PetscFunctionBeginHot;                                                                             \
597   PetscValidPointer(ht,1);                                                                           \
598   PetscValidPointer(present,3);                                                                      \
599   iter = kh_get(HashT,ht,key);                                                                       \
600   if (iter != kh_end(ht)) {                                                                          \
601     kh_del(HashT,ht,iter);                                                                           \
602     *present = PETSC_TRUE;                                                                           \
603   } else {                                                                                           \
604     *present = PETSC_FALSE;                                                                          \
605   }                                                                                                  \
606   PetscFunctionReturn(0);                                                                            \
607 }                                                                                                    \
608                                                                                                      \
609 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
610 PetscErrorCode Petsc##HashT##Find(Petsc##HashT ht,KeyType key,PetscHashIter *iter,PetscBool *found)  \
611                                                                                                      \
612 {                                                                                                    \
613   PetscFunctionBeginHot;                                                                             \
614   PetscValidPointer(ht,1);                                                                           \
615   PetscValidPointer(iter,2);                                                                         \
616   PetscValidPointer(found,3);                                                                        \
617   *iter = kh_get(HashT,ht,key);                                                                      \
618   *found = (*iter != kh_end(ht)) ? PETSC_TRUE : PETSC_FALSE;                                         \
619   PetscFunctionReturn(0);                                                                            \
620 }                                                                                                    \
621                                                                                                      \
622 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
623 PetscErrorCode Petsc##HashT##Put(Petsc##HashT ht,KeyType key,PetscHashIter *iter,PetscBool *missing) \
624 {                                                                                                    \
625   int ret;                                                                                           \
626   PetscFunctionBeginHot;                                                                             \
627   PetscValidPointer(ht,1);                                                                           \
628   PetscValidPointer(iter,2);                                                                         \
629   PetscValidPointer(missing,3);                                                                      \
630   *iter = kh_put(HashT,ht,key,&ret);                                                                 \
631   PetscHashAssert(ret>=0);                                                                           \
632   *missing = ret ? PETSC_TRUE : PETSC_FALSE;                                                         \
633   PetscFunctionReturn(0);                                                                            \
634 }                                                                                                    \
635                                                                                                      \
636 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
637 PetscErrorCode Petsc##HashT##IterGet(Petsc##HashT ht,PetscHashIter iter,ValType *val)                \
638 {                                                                                                    \
639   PetscFunctionBeginHot;                                                                             \
640   PetscValidPointer(ht,1);                                                                           \
641   PetscValidPointer(val,3);                                                                          \
642   *val = PetscLikely(iter < kh_end(ht) && kh_exist(ht,iter)) ? kh_val(ht,iter) : (DefaultValue);     \
643   PetscFunctionReturn(0);                                                                            \
644 }                                                                                                    \
645                                                                                                      \
646 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
647 PetscErrorCode Petsc##HashT##IterSet(Petsc##HashT ht,PetscHashIter iter,ValType val)                 \
648 {                                                                                                    \
649   PetscFunctionBeginHot;                                                                             \
650   PetscValidPointer(ht,1);                                                                           \
651   if (PetscLikely(iter < kh_end(ht) && kh_exist(ht,iter))) kh_val(ht,iter) = val;                    \
652   PetscFunctionReturn(0);                                                                            \
653 }                                                                                                    \
654                                                                                                      \
655 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
656 PetscErrorCode Petsc##HashT##IterDel(Petsc##HashT ht,PetscHashIter iter)                             \
657 {                                                                                                    \
658   PetscFunctionBeginHot;                                                                             \
659   PetscValidPointer(ht,1);                                                                           \
660   if (PetscLikely(iter < kh_end(ht))) kh_del(HashT,ht,iter);                                         \
661   PetscFunctionReturn(0);                                                                            \
662 }                                                                                                    \
663                                                                                                      \
664 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
665 PetscErrorCode Petsc##HashT##GetKeys(Petsc##HashT ht,PetscInt *off,KeyType array[])                  \
666 {                                                                                                    \
667   KeyType  key;                                                                                      \
668   PetscInt pos;                                                                                      \
669   PetscFunctionBegin;                                                                                \
670   PetscValidPointer(ht,1);                                                                           \
671   PetscValidIntPointer(off,2);                                                                       \
672   pos = *off;                                                                                        \
673   kh_foreach_key(ht,key,array[pos++] = key);                                                         \
674   *off = pos;                                                                                        \
675   PetscFunctionReturn(0);                                                                            \
676 }                                                                                                    \
677                                                                                                      \
678 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
679 PetscErrorCode Petsc##HashT##GetVals(Petsc##HashT ht,PetscInt *off,ValType array[])                  \
680 {                                                                                                    \
681   ValType  val;                                                                                      \
682   PetscInt pos;                                                                                      \
683   PetscFunctionBegin;                                                                                \
684   PetscValidPointer(ht,1);                                                                           \
685   PetscValidIntPointer(off,2);                                                                       \
686   pos = *off;                                                                                        \
687   kh_foreach_value(ht,val,array[pos++] = val);                                                       \
688   *off = pos;                                                                                        \
689   PetscFunctionReturn(0);                                                                            \
690 }                                                                                                    \
691                                                                                                      \
692                                                                                                      \
693 PETSC_STATIC_INLINE PETSC_UNUSED                                                                     \
694 PetscErrorCode Petsc##HashT##GetPairs(Petsc##HashT ht,PetscInt *off,KeyType karray[],ValType varray[]) \
695 {                                                                                                    \
696   ValType  val;                                                                                      \
697   KeyType  key;                                                                                      \
698   PetscInt pos;                                                                                      \
699   PetscFunctionBegin;                                                                                \
700   PetscValidPointer(ht,1);                                                                           \
701   PetscValidIntPointer(off,2);                                                                       \
702   pos = *off;                                                                                        \
703   kh_foreach(ht,key,val,                                                                             \
704   { karray[pos] = key;                                                                               \
705   varray[pos++] = val;})                                                                             \
706   *off = pos;                                                                                        \
707   PetscFunctionReturn(0);                                                                            \
708 }                                                                                                    \
709 
710 #endif /* PETSC_HASHMAP_H */
711