22typedef struct hashtable_ref {
29typedef struct HTChunkInfo HTChunkInfo;
33typedef struct HashTableHeader {
57typedef struct htiter {
65#define HT_CHUNK_SHIFT 6
67#define HT_CHUNK_SHIFT 5
69#define HT_SLOTS_PER_CHUNK (1 << HT_CHUNK_SHIFT)
70#define HT_CHUNK_MASK (HT_SLOTS_PER_CHUNK - 1)
71#define HT_QUARTER_CHUNK (HT_SLOTS_PER_CHUNK >> 2)
72#define HT_QCHUNK_MASK (HT_QUARTER_CHUNK - 1)
75#define HTABLE_HDRSIZE (offsetof(HashTableHeader, index))
76#define HTABLE_HDR(ref) ((HashTableHeader*)(((uintptr)(&((ref)->_is_hashtable))) - HTABLE_HDRSIZE))
79_Ret_valid_ _meta_inline HashTableHeader* _htHdr(_In_ hashtable ref)
81 return HTABLE_HDR(ref);
89#define htSize(ref) ((ref) ? _htHdr((ref))->valid : 0)
97#define htKeyType(ref) ((ref) ? _htHdr((ref))->keytype : stType(none))
107#define htValType(ref) ((ref) ? _htHdr((ref))->valtype : stType(none))
117#define hteKeyPtrHdr(hdr, type, elem) ((stStorageType(type)*)_hteElemKeyPtr(hdr, elem))
127#define hteValPtrHdr(hdr, type, elem) ((stStorageType(type)*)_hteElemValPtr(hdr, elem))
137#define hteKeyPtr(ref, type, elem) hteKeyPtrHdr(_htHdr(ref), type, elem)
147#define hteValPtr(ref, type, elem) hteValPtrHdr(_htHdr(ref), type, elem)
156#define hteKey(ref, type, elem) (*hteKeyPtr(ref, type, elem))
165#define hteVal(ref, type, elem) (*hteValPtr(ref, type, elem))
173#define htiKeyPtr(type, iter) (hteKeyPtrHdr((iter).hdr, type, (iter).slot))
181#define htiValPtr(type, iter) (hteValPtrHdr((iter).hdr, type, (iter).slot))
189#define htiKey(type, iter) (*htiKeyPtr(type, iter))
197#define htiVal(type, iter) (*htiValPtr(type, iter))
234 HTINT_Metadata = 0x1000,
235 HTINT_Quadratic = 0x2000,
240enum HASHTABLE_GROWBY_ENUM {
241 HT_GROW_By100 = 0x00,
242 HT_GROW_By200 = 0x10,
243 HT_GROW_By300 = 0x20,
245 HT_GROW_BY_MASK = 0xf0,
249enum HASHTABLE_GROW_ENUM {
253 HT_GROW_AT_MASK = 0x0f,
256 HT_GROW_MaxSpeed = (uint32)HT_GROW_At50 | (uint32)HT_GROW_By300,
257 HT_GROW_MinSize = (uint32)HT_GROW_At90 | (uint32)HT_GROW_By50,
272 HTINT_Consume = 0x10000000,
277#define HT_GROW_MASK (0xff000000)
322#define HT_Grow(flag) (((uint32)HT_GROW_##flag) << 24)
325#define HT_GET_GROW(flags) ((flags) >> 24)
327void _htInit(_Outptr_ hashtable* out,
stype keytype,
stype valtype, uint32 initsz, flags_t flags);
344#define htInit(out, keytype, valtype, initsz, ...) \
345 _htInit(out, stType(keytype), stType(valtype), initsz, opt_flags(__VA_ARGS__))
375void htReindex(_Inout_ptr_ hashtable* htbl, uint32 minsz);
390void htClone(_Outptr_ hashtable* out, _In_ hashtable ref);
393htelem _htInsert(_Inout_ptr_ hashtable* htbl, _In_ stgeneric key, _In_ stgeneric val,
397_meta_inline htelem _htInsertChecked(_Inout_ptr_ hashtable* htbl,
stype keytype, _In_ stgeneric key,
398 stype valtype, _In_ stgeneric val, flags_t flags)
402 return _htInsert(htbl, key, val, flags);
406#define _ht_Consume_Arg_ \
407 _When_(flags& HTINT_Consume, _Pre_notnull_ _Post_invalid_) \
408 _When_(!(flags & HTINT_Consume), _Inout_)
411htelem _htInsertPtr(_Inout_ptr_ hashtable* htbl, _In_ stgeneric key,
412 _ht_Consume_Arg_ stgeneric* val, flags_t flags);
415_meta_inline htelem _htInsertCheckedC(_Inout_ptr_ hashtable* htbl,
stype keytype,
416 _In_ stgeneric key,
stype valtype,
417 _ht_Consume_Arg_ stgeneric* val, flags_t flags)
421 return _htInsertPtr(htbl, key, val, flags);
443#define htInsert(htbl, ktype, key, vtype, val, ...) \
444 _htInsertChecked(htbl, \
445 stCheckedArg(ktype, key), \
446 stCheckedArg(vtype, val), \
447 opt_flags(__VA_ARGS__))
470#define htInsertC(htbl, ktype, key, vtype, val, ...) \
471 _htInsertCheckedC(htbl, \
472 stCheckedArg(ktype, key), \
473 stCheckedPtrArg(vtype, val), \
474 opt_flags(__VA_ARGS__) | HTINT_Consume)
477_Success_(
return != 0) htelem _htFind(_In_ hashtable htbl, _In_ stgeneric key, _Inout_opt_ stgeneric* val,
481_Success_(return != 0) _meta_inline htelem
482_htFindChecked(_In_ hashtable htbl,
stype keytype, _In_ stgeneric key,
stype valtype,
483 _stCopyDest_Anno_opt_(valtype) stgeneric* val, flags_t flags)
488 return _htFind(htbl, key, val, flags);
517#define htFind(htbl, ktype, key, vtype, val_copy_out, ...) \
518 _htFindChecked(htbl, \
519 stCheckedArg(ktype, key), \
520 stCheckedPtrArg(vtype, val_copy_out), \
521 opt_flags(__VA_ARGS__))
524_Success_(
return)
bool
525_htExtract(_Inout_ptr_ hashtable* htbl, _In_ stgeneric key, _Inout_opt_ stgeneric* val);
528_Success_(
return) _meta_inline
bool
529_htExtractChecked(_Inout_ptr_ hashtable* htbl,
stype keytype, _In_ stgeneric key,
stype valtype,
530 _stCopyDest_Anno_opt_(valtype) stgeneric* val)
535 return _htExtract(htbl, key, val);
559#define htExtract(htbl, ktype, key, vtype, val_copy_out) \
560 _htExtractChecked(htbl, stCheckedArg(ktype, key), stCheckedPtrArg(vtype, val_copy_out))
575#define htRemove(htbl, ktype, key) \
576 _htExtractChecked(htbl, stCheckedArg(ktype, key), stType(none), NULL)
579bool _htHasKey(_In_ hashtable htbl, _In_ stgeneric key);
582_meta_inline
bool _htHasKeyChecked(_In_ hashtable htbl,
stype keytype, _In_ stgeneric key)
586 return _htHasKey(htbl, key);
604#define htHasKey(htbl, ktype, key) _htHasKeyChecked(htbl, stCheckedArg(ktype, key))
610_Pre_satisfies_(elem > 0) void* _hteElemKeyPtr(_Inout_ HashTableHeader* hdr, htelem elem);
614_Pre_satisfies_(elem > 0)
void* _hteElemValPtr(_Inout_ HashTableHeader* hdr, htelem elem);
638#define _htiInitAnno \
639 _Success_(return) _Post_satisfies_(iter->slot > 0) \
640 _On_failure_(_Post_satisfies_(iter->slot == 0))
651_htiInitAnno
bool htiInit(_Out_ htiter* iter, _In_ hashtable htbl);
653#define _htiNextAnno \
654 _Success_(return) _Post_satisfies_(iter->slot > 0) \
655 _On_failure_(_Post_satisfies_(iter->slot == 0))
663_htiNextAnno
bool htiNext(_Inout_ htiter* iter);
670void htiFinish(_Pre_notnull_ _Post_invalid_ htiter* iter);
676_Post_equal_to_(iter->slot > 0) _meta_inline
bool htiValid(_In_ htiter* iter)
678 return iter->slot > 0;
Runtime assertion macros and failure handling.
HASHTABLE_FUNC_FLAGS_ENUM
Function-specific flags.
void htClear(hashtable *htbl)
HASHTABLE_FLAGS_ENUM
Hash table configuration flags.
void htDestroy(hashtable *htbl)
@ HT_CaseInsensitive
Case-insensitive key matching - only valid for string keys.
struct hashtable_ref * hashtable
void htiFinish(htiter *iter)
bool htiValid(htiter *iter)
_htiInitAnno bool htiInit(htiter *iter, hashtable htbl)
_htiNextAnno bool htiNext(htiter *iter)
void htClone(hashtable *out, hashtable ref)
void htRepack(hashtable *htbl)
void htReindex(hashtable *htbl, uint32 minsz)
bool stEq(stype s1, stype s2)