Merge pull request #197 from dvdhrm/hashmap

hashmap: fix iterators to not skip entries
This commit is contained in:
Michal Schmidt
2015-06-16 14:44:43 +02:00
9 changed files with 56 additions and 41 deletions
+1 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+3 -3
View File
@@ -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
View File
@@ -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);