20typedef struct hashtable_ref {
27typedef struct HTChunkInfo HTChunkInfo;
31typedef struct HashTableHeader {
59typedef struct htiter {
67#define HT_CHUNK_SHIFT 6
69#define HT_CHUNK_SHIFT 5
71#define HT_SLOTS_PER_CHUNK (1 << HT_CHUNK_SHIFT)
72#define HT_CHUNK_MASK (HT_SLOTS_PER_CHUNK - 1)
73#define HT_QUARTER_CHUNK (HT_SLOTS_PER_CHUNK >> 2)
74#define HT_QCHUNK_MASK (HT_QUARTER_CHUNK - 1)
77#define HTABLE_HDRSIZE (offsetof(HashTableHeader, index))
78#define HTABLE_HDR(ref) ((HashTableHeader*)(((uintptr)(&((ref)->_is_hashtable))) - HTABLE_HDRSIZE))
81_Ret_valid_ _meta_inline HashTableHeader* _htHdr(_In_ hashtable ref)
83 return HTABLE_HDR(ref);
91#define htSize(ref) ((ref) ? _htHdr((ref))->valid : 0)
98#define htKeyType(ref) ((ref) ? _htHdr((ref))->keytype : 0)
105#define htValType(ref) ((ref) ? _htHdr((ref))->valtype : 0)
115#define hteKeyPtrHdr(hdr, type, elem) ((stStorageType(type)*)_hteElemKeyPtr(hdr, elem))
125#define hteValPtrHdr(hdr, type, elem) ((stStorageType(type)*)_hteElemValPtr(hdr, elem))
135#define hteKeyPtr(ref, type, elem) hteKeyPtrHdr(_htHdr(ref), type, elem)
145#define hteValPtr(ref, type, elem) hteValPtrHdr(_htHdr(ref), type, elem)
154#define hteKey(ref, type, elem) (*hteKeyPtr(ref, type, elem))
163#define hteVal(ref, type, elem) (*hteValPtr(ref, type, elem))
171#define htiKeyPtr(type, iter) (hteKeyPtrHdr((iter).hdr, type, (iter).slot))
179#define htiValPtr(type, iter) (hteValPtrHdr((iter).hdr, type, (iter).slot))
187#define htiKey(type, iter) (*htiKeyPtr(type, iter))
195#define htiVal(type, iter) (*htiValPtr(type, iter))
232 HTINT_Metadata = 0x1000,
233 HTINT_Quadratic = 0x2000,
235 HTINT_Extended = 0x8000,
239enum HASHTABLE_GROWBY_ENUM {
240 HT_GROW_By100 = 0x00,
241 HT_GROW_By200 = 0x10,
242 HT_GROW_By300 = 0x20,
244 HT_GROW_BY_MASK = 0xf0,
248enum HASHTABLE_GROW_ENUM {
252 HT_GROW_AT_MASK = 0x0f,
255 HT_GROW_MaxSpeed = (uint32)HT_GROW_At50 | (uint32)HT_GROW_By300,
256 HT_GROW_MinSize = (uint32)HT_GROW_At90 | (uint32)HT_GROW_By50,
271 HTINT_Consume = 0x10000000,
276#define HT_GROW_MASK (0xff000000)
321#define HT_Grow(flag) (((uint32)HT_GROW_##flag) << 24)
324#define HT_GET_GROW(flags) ((flags) >> 24)
326void _htInit(_Outptr_ hashtable* out, stype keytype, _In_opt_ STypeOps* keyops, stype valtype,
327 _In_opt_ STypeOps* valops, uint32 initsz, flags_t flags);
344#define htInit(out, keytype, valtype, initsz, ...) \
345 _htInit(out, stFullType(keytype), stFullType(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)
478htelem _htFind(_In_ hashtable htbl, _In_ stgeneric key, _Inout_opt_ stgeneric* val, flags_t flags);
481_Success_(return != 0) _meta_inline
482htelem _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);
529_meta_inline
bool _htExtractChecked(_Inout_ptr_ hashtable* htbl, stype keytype, _In_ stgeneric key,
530 stype valtype, _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 sta, stype stb)