diff options
| author | Tyge Løvset <[email protected]> | 2021-04-16 16:14:25 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2021-04-16 16:14:25 +0200 |
| commit | 6cbbac922e43e50bd29d72ea74df20c2ebe8ceba (patch) | |
| tree | b2b74a13e2a0e7b65079331953b5057375853bf9 | |
| parent | 25df7b52622b62a167d5fe7d50b7aa9e075ad814 (diff) | |
| download | STC-modified-6cbbac922e43e50bd29d72ea74df20c2ebe8ceba.tar.gz STC-modified-6cbbac922e43e50bd29d72ea74df20c2ebe8ceba.zip | |
Corrections in cmap.
| -rw-r--r-- | docs/cmap_api.md | 12 | ||||
| -rw-r--r-- | stc/cmap.h | 18 |
2 files changed, 19 insertions, 11 deletions
diff --git a/docs/cmap_api.md b/docs/cmap_api.md index f43afa44..5e8d4d26 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -1,10 +1,14 @@ # STC [cmap](../stc/cmap.h): Unordered Map  -A **cmap** is an associative container that contains key-value pairs with unique keys. Search, insertion, -and removal of elements have average constant-time complexity. Internally, the elements are not sorted in any particular order, but organized into buckets. Which bucket an element is placed into depends entirely on the hash of its key. This allows fast access to individual elements, since once the hash is computed, it refers to the exact bucket the element is placed into. It is implemented as closed hashing (aka open addressing) with linear probing, and without leaving tombstones on erase. - -***Iterator invalidation***: References and iterators are invalidated after erase. No iterators are invalidated after insert. +A **cmap** is an associative container that contains key-value pairs with unique keys. Search, insertion, and removal of elements +have average constant-time complexity. Internally, the elements are not sorted in any particular order, but organized into +buckets. Which bucket an element is placed into depends entirely on the hash of its key. This allows fast access to individual +elements, since once the hash is computed, it refers to the exact bucket the element is placed into. It is implemented as closed +hashing (aka open addressing) with linear probing, and without leaving tombstones on erase. + +***Iterator invalidation***: References and iterators are invalidated after erase. No iterators are invalidated after insert, +unless the hash-table need to be extended. The hash table size can be reserved prior to inserts if the total max size is known. The order of elements is preserved after erase and insert. This makes it possible to erase individual elements while iterating through the container by using the returned iterator from *erase_it()*, which references the next element. @@ -200,6 +200,7 @@ STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored) STC_INLINE bool CX##_contains(const CX* self, RawKey rkey) \
{return self->size && self->_hashx[CX##_bucket_(self, &rkey).idx];} \
STC_API void CX##_erase_entry(CX* self, CX##_value_t* val); \
+ STC_API CX##_iter_t CX##_erase_it(CX* self, CX##_iter_t it); \
\
STC_INLINE CX##_value_t \
CX##_value_clone(CX##_value_t val) { \
@@ -292,13 +293,6 @@ STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored) return self->_hashx[b.idx] ? CX##_erase_entry(self, self->table + b.idx), 1 : 0; \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_erase_it(CX* self, CX##_iter_t it) { \
- CX##_erase_entry(self, it.ref); \
- if (*it._hx == 0) CX##_next(&it); \
- return it; \
- } \
-\
_c_implement_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \
mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
keyDel, keyFromRaw, keyToRaw, RawKey) \
@@ -443,8 +437,18 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) \ hashx[i] = 0, k = --self->size; \
if (k < cap*self->min_load_factor && k > 512) \
CX##_reserve(self, k*1.2); \
+ } \
+\
+ STC_DEF CX##_iter_t \
+ CX##_erase_it(CX* self, CX##_iter_t it) { \
+ size_t idx = it.ref - self->table; \
+ CX##_erase_entry(self, it.ref); \
+ it.ref = self->table + idx, it._hx = self->_hashx + idx; \
+ if (*it._hx == 0) CX##_next(&it); \
+ return it; \
}
+
STC_DEF uint64_t c_default_hash(const void *key, size_t len) {
const uint64_t m = 0xb5ad4eceda1ce2a9;
uint64_t k, h = m + len;
|
