diff options
author | Michal Schmidt <mschmidt@redhat.com> | 2015-06-16 14:44:43 +0200 |
---|---|---|
committer | Michal Schmidt <mschmidt@redhat.com> | 2015-06-16 14:44:43 +0200 |
commit | 9ef41ffeec0a677f0c8006b17e5ff1c8434418a3 (patch) | |
tree | b0f66b97ddf0e13c4cd1240fc0fd7ef6ad618a82 /src/basic | |
parent | aab723074c368f65aaf2748d0c530ba9a1e6ad3e (diff) | |
parent | 8927b1dad2d4a7330174cb924090b4635a2547fb (diff) |
Merge pull request #197 from dvdhrm/hashmap
hashmap: fix iterators to not skip entries
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/fdset.c | 3 | ||||
-rw-r--r-- | src/basic/hashmap.c | 14 | ||||
-rw-r--r-- | src/basic/hashmap.h | 27 | ||||
-rw-r--r-- | src/basic/ordered-set.h | 6 | ||||
-rw-r--r-- | src/basic/set.h | 4 |
5 files changed, 25 insertions, 29 deletions
diff --git a/src/basic/fdset.c b/src/basic/fdset.c index 6101b628ec..a4823e6659 100644 --- a/src/basic/fdset.c +++ b/src/basic/fdset.c @@ -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); diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c index 20d599d04b..0ee2f3bd31 100644 --- a/src/basic/hashmap.c +++ b/src/basic/hashmap.c @@ -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) \ diff --git a/src/basic/hashmap.h b/src/basic/hashmap.h index a03ee5812a..5723f09ca9 100644 --- a/src/basic/hashmap.h +++ b/src/basic/hashmap.h @@ -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); diff --git a/src/basic/ordered-set.h b/src/basic/ordered-set.h index 766a1f2e83..6c617ab305 100644 --- a/src/basic/ordered-set.h +++ b/src/basic/ordered-set.h @@ -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); diff --git a/src/basic/set.h b/src/basic/set.h index 4dffecd39d..51e40d3a6c 100644 --- a/src/basic/set.h +++ b/src/basic/set.h @@ -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); |