Merge pull request #197 from dvdhrm/hashmap
hashmap: fix iterators to not skip entries
This commit is contained in:
+1
-2
@@ -267,8 +267,7 @@ bool fdset_isempty(FDSet *fds) {
|
||||
int fdset_iterate(FDSet *s, Iterator *i) {
|
||||
void *p;
|
||||
|
||||
p = set_iterate(MAKE_SET(s), i);
|
||||
if (!p)
|
||||
if (!set_iterate(MAKE_SET(s), i, &p))
|
||||
return -ENOENT;
|
||||
|
||||
return PTR_TO_FD(p);
|
||||
|
||||
+9
-5
@@ -733,29 +733,33 @@ static unsigned hashmap_iterate_entry(HashmapBase *h, Iterator *i) {
|
||||
: hashmap_iterate_in_internal_order(h, i);
|
||||
}
|
||||
|
||||
void *internal_hashmap_iterate(HashmapBase *h, Iterator *i, const void **key) {
|
||||
bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key) {
|
||||
struct hashmap_base_entry *e;
|
||||
void *data;
|
||||
unsigned idx;
|
||||
|
||||
idx = hashmap_iterate_entry(h, i);
|
||||
if (idx == IDX_NIL) {
|
||||
if (value)
|
||||
*value = NULL;
|
||||
if (key)
|
||||
*key = NULL;
|
||||
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
e = bucket_at(h, idx);
|
||||
data = entry_value(h, e);
|
||||
if (value)
|
||||
*value = data;
|
||||
if (key)
|
||||
*key = e->key;
|
||||
|
||||
return data;
|
||||
return true;
|
||||
}
|
||||
|
||||
void *set_iterate(Set *s, Iterator *i) {
|
||||
return internal_hashmap_iterate(HASHMAP_BASE(s), i, NULL);
|
||||
bool set_iterate(Set *s, Iterator *i, void **value) {
|
||||
return internal_hashmap_iterate(HASHMAP_BASE(s), i, value, NULL);
|
||||
}
|
||||
|
||||
#define HASHMAP_FOREACH_IDX(idx, h, i) \
|
||||
|
||||
+10
-17
@@ -65,6 +65,7 @@ typedef struct {
|
||||
} Iterator;
|
||||
|
||||
#define _IDX_ITERATOR_FIRST (UINT_MAX - 1)
|
||||
#define _IDX_ITERATOR_NIL (UINT_MAX)
|
||||
#define ITERATOR_FIRST ((Iterator) { .idx = _IDX_ITERATOR_FIRST, .next_key = NULL })
|
||||
|
||||
typedef unsigned long (*hash_func_t)(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]);
|
||||
@@ -296,12 +297,12 @@ static inline unsigned ordered_hashmap_buckets(OrderedHashmap *h) {
|
||||
return internal_hashmap_buckets(HASHMAP_BASE(h));
|
||||
}
|
||||
|
||||
void *internal_hashmap_iterate(HashmapBase *h, Iterator *i, const void **key);
|
||||
static inline void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key) {
|
||||
return internal_hashmap_iterate(HASHMAP_BASE(h), i, key);
|
||||
bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key);
|
||||
static inline bool hashmap_iterate(Hashmap *h, Iterator *i, void **value, const void **key) {
|
||||
return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
|
||||
}
|
||||
static inline void *ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, const void **key) {
|
||||
return internal_hashmap_iterate(HASHMAP_BASE(h), i, key);
|
||||
static inline bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void **value, const void **key) {
|
||||
return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
|
||||
}
|
||||
|
||||
void internal_hashmap_clear(HashmapBase *h);
|
||||
@@ -386,24 +387,16 @@ static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) {
|
||||
* It is safe to remove the current entry.
|
||||
*/
|
||||
#define HASHMAP_FOREACH(e, h, i) \
|
||||
for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), NULL); \
|
||||
(e); \
|
||||
(e) = hashmap_iterate((h), &(i), NULL))
|
||||
for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), NULL); )
|
||||
|
||||
#define ORDERED_HASHMAP_FOREACH(e, h, i) \
|
||||
for ((i) = ITERATOR_FIRST, (e) = ordered_hashmap_iterate((h), &(i), NULL); \
|
||||
(e); \
|
||||
(e) = ordered_hashmap_iterate((h), &(i), NULL))
|
||||
for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), NULL); )
|
||||
|
||||
#define HASHMAP_FOREACH_KEY(e, k, h, i) \
|
||||
for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), (const void**) &(k)); \
|
||||
(e); \
|
||||
(e) = hashmap_iterate((h), &(i), (const void**) &(k)))
|
||||
for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
|
||||
|
||||
#define ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i) \
|
||||
for ((i) = ITERATOR_FIRST, (e) = ordered_hashmap_iterate((h), &(i), (const void**) &(k)); \
|
||||
(e); \
|
||||
(e) = ordered_hashmap_iterate((h), &(i), (const void**) &(k)))
|
||||
for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free);
|
||||
|
||||
@@ -47,12 +47,12 @@ static inline bool ordered_set_isempty(OrderedSet *s) {
|
||||
return ordered_hashmap_isempty((OrderedHashmap*) s);
|
||||
}
|
||||
|
||||
static inline void *ordered_set_iterate(OrderedSet *s, Iterator *i) {
|
||||
return ordered_hashmap_iterate((OrderedHashmap*) s, i, NULL);
|
||||
static inline bool ordered_set_iterate(OrderedSet *s, Iterator *i, void **value) {
|
||||
return ordered_hashmap_iterate((OrderedHashmap*) s, i, value, NULL);
|
||||
}
|
||||
|
||||
#define ORDERED_SET_FOREACH(e, s, i) \
|
||||
for ((i) = ITERATOR_FIRST, (e) = ordered_set_iterate((s), &(i)); (e); (e) = ordered_set_iterate((s), &(i)))
|
||||
for ((i) = ITERATOR_FIRST; ordered_set_iterate((s), &(i), (void**)&(e)); )
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedSet*, ordered_set_free);
|
||||
|
||||
|
||||
+2
-2
@@ -91,7 +91,7 @@ static inline unsigned set_buckets(Set *s) {
|
||||
return internal_hashmap_buckets(HASHMAP_BASE(s));
|
||||
}
|
||||
|
||||
void *set_iterate(Set *s, Iterator *i);
|
||||
bool set_iterate(Set *s, Iterator *i, void **value);
|
||||
|
||||
static inline void set_clear(Set *s) {
|
||||
internal_hashmap_clear(HASHMAP_BASE(s));
|
||||
@@ -125,7 +125,7 @@ int set_put_strdup(Set *s, const char *p);
|
||||
int set_put_strdupv(Set *s, char **l);
|
||||
|
||||
#define SET_FOREACH(e, s, i) \
|
||||
for ((i) = ITERATOR_FIRST, (e) = set_iterate((s), &(i)); (e); (e) = set_iterate((s), &(i)))
|
||||
for ((i) = ITERATOR_FIRST; set_iterate((s), &(i), (void**)&(e)); )
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free);
|
||||
|
||||
Reference in New Issue
Block a user