HTable.xcc
Benoit Dupont de Dinechin (Benoit.Dupont-de-Dinechin@st.com)
Copyright 2007 STMicroelectronics. Copyright 1995 - 1998 Commissariat a l'Energie Atomique.
This program is free software; you can redistribute it and/or modify it under the terms of either (at your option): the GNU General Public License (GPL) version 2; the GNU Lesser General Public License (LGPL) version 2.1; any later version of these licences as published by the Free Software Foundation.
HTable_Hash— Multiplicative hash using the golden ratio (Knuth).
The input number interpreted as Q0.32 fractional is multiplied by the Q0.32 fractional representation of the golden ratio (sqrt(5) - 1)/2. Actually, the constant used is 2654435761, a prime close enough to (sqrt(5) - 1)/2 * 2*32. As a final step, we apply a pseudo modular reduction by the prime 2*31 - 1.
static inline uint32_t HTable_Hash(uint32_t number) { uint64_t result = number*(uint64_t)2654435761U; uint32_t hash = result + (result >> 31); return hash + (hash >> 31); }
The HTableEntry_ structure implements the HTable entries. This structure is published for use in HTable_FOREACH.
struct HTableEntry_ { //@args HTableKey key, size_t valueSize, struct HTableEntry_ *link HTableKey KEY; // The key, which holds a pointer. struct HTableEntry_ *LINK; // Link to the next HTableEntry in bucket. //@access VALUE ((HTableValue)((HTableEntry_ *)(this) + 1)) };
HTable— Hash table implementation with chaining.
- memory
- Where the HTable entries are allocated.
- estimate
- Estimate of maximum number of entries in the hash table.
struct HTable_ { //@args Memory memory, uint32_t estimate Memory MEMORY; uint32_t MASK; // Mask for modulo clp2. int32_t COUNT; // Count this HTable ENTRIES. HTableEntry *BUCKETS; // This HTable buckets. };
HTable_resize— Resize this HTable for the given estimated count.
void HTable_resize(HTable this, uint32_t estimate);
HTable_empty— Empty this HTable.
void HTable_empty(HTable this, HTableValueRelease release);
HTable_memory— This HTable Memory.
static inline Memory HTable_memory(const_HTable this) { return HTable_MEMORY(this); }
HTable_isEmpty— True iff this HTable is empty.
#define HTable_isEmpty(this) (HTable_count(this) == 0)
HTable_isSingle— True iff this HTable has a single entry.
#define HTable_isSingle(this) (HTable_count(this) == 1)
HTable_count— Count entries in the HTable.
- Return
- The count of entries in the HTable.
static inline int32_t HTable_count(const_HTable this) { return HTable_COUNT(this); }
HTable_mask— For use by HTable_FOREACH.
static inline uint32_t HTable_mask(const_HTable this) { return HTable_MASK(this); }
HTable_buckets— For use by HTable_FOREACH.
- Return
- This HTable_ENTRIES.
static inline HTableEntry * HTable_buckets(const_HTable this) { return HTable_BUCKETS(this); }
HTable_FOREACH— Iterates over the HTable entries.
key
- Variable set for each key in this HTable.
Type
- the
value
type. - iter
- Pointer set to each value associated to
key
.
Exiting HTable_FOREACH with break
or return
is allowed.
Calling HTable_remove on the current entry is allowed.
#define HTable_FOREACH(this, key, Type, iter) { \ HTableEntry *HTable_BUCKETS = HTable_buckets(this); \ int32_t HTable_MASK = HTable_mask(this), HTable_INDEX; \ for (HTable_INDEX = 0; HTable_INDEX <= HTable_MASK; HTable_INDEX++) { \ HTableEntry HTable_ENTRY = HTable_BUCKETS[HTable_INDEX], HTableEntry_LINK; \ for (; HTable_ENTRY != NULL; HTable_ENTRY = HTableEntry_LINK) { \ HTableKey key = HTableEntry_key(HTable_ENTRY); \ Type *(iter) = (Type *)HTableEntry_value(HTable_ENTRY); \ HTableEntry_LINK = HTableEntry_link(HTable_ENTRY); #define HTable_ENDEACH \ } \ if (HTable_ENTRY != NULL) break; \ } \ }
HTable_search— Search the value associated to key
.
- Return
- The associated value if
key
is in HTable, else NULL.
HTableValue HTable_search(const_HTable this, HTableKey key);
HTable_lookup_— Lookup key
and insert if not found.
- Return
- Pointer to the associated value (never return NULL).
In case of insertion, the new value is left uninitialized.
HTableValue HTable_lookup_(HTable this, HTableKey key, size_t valueSize);
HTable_lookup— Lookup key
and insert if not found.
- Return
- Pointer to the associated value (never return NULL).
In case of insertion, the new value is cleared.
static inline HTableValue HTable_lookup(HTable this, HTableKey key, size_t valueSize) { int32_t count = HTable_count(this); HTableValue value = HTable_lookup_(this, key, valueSize); if (count != HTable_count(this)) memset(value, 0, valueSize); return value; }
HTable_insert— Insert key
and return the associated value.
- Return
- Pointer to the associated value if
key
was inserted in HTable, NULL ifkey
is already in HTable.
HTableValue HTable_insert(HTable this, HTableKey key, size_t valueSize);
HTable_remove_— Specialized HTable_remove
that does not release the HTableEntry.
HTableEntry HTable_remove_(HTable this, HTableKey key);
HTable_remove— Remove key
and the associated value.
- Return
true
ifkey
was in HTable, elsefalse
.
static inline bool HTable_remove(HTable this, HTableKey key, HTableValueRelease release) { Memory memory = HTable_MEMORY(this); HTableEntry entry = HTable_remove_(this, key); if (entry != NULL) { HTableValue value = HTableEntry_VALUE(entry); if (release != NULL) (*release)(value); Memory_free_(memory, entry); return true; } return false; }
HTable_map— Map the HTable_map entries using the supplied map
function.
map
- The function that will be called for each entry in the HTable.
First argument of
(map)
is the current key. Second argument of(map)
is thevoid
value associated to the current key. Third argument of (map) is theva_list
corresponding to the...
arguments of HTable_map. ...
- The other arguments if any to be passed to
(*map)
asva_list
.
void HTable_map(HTable this, void (*map)(HTableKey, HTableValue, va_list), ...);