From 7ef670c34a197af55116371615d9e31d5a5f649f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 13 Oct 2018 16:30:49 +0900 Subject: [PATCH] hashmap: introduce hashmap_first_key_and_value() and friends --- src/basic/hashmap.c | 52 ++++++++------------------------------ src/basic/hashmap.h | 61 ++++++++++++++++++++++++++++----------------- src/basic/set.h | 4 +-- 3 files changed, 50 insertions(+), 67 deletions(-) diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c index 018ef5e7d8..eba56add1f 100644 --- a/src/basic/hashmap.c +++ b/src/basic/hashmap.c @@ -1543,47 +1543,9 @@ static unsigned find_first_entry(HashmapBase *h) { return hashmap_iterate_entry(h, &i); } -void *internal_hashmap_first(HashmapBase *h) { - unsigned idx; - - idx = find_first_entry(h); - if (idx == IDX_NIL) - return NULL; - - return entry_value(h, bucket_at(h, idx)); -} - -void *internal_hashmap_first_key(HashmapBase *h) { +void *internal_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key) { struct hashmap_base_entry *e; - unsigned idx; - - idx = find_first_entry(h); - if (idx == IDX_NIL) - return NULL; - - e = bucket_at(h, idx); - return (void*) e->key; -} - -void *internal_hashmap_steal_first(HashmapBase *h) { - struct hashmap_base_entry *e; - void *data; - unsigned idx; - - idx = find_first_entry(h); - if (idx == IDX_NIL) - return NULL; - - e = bucket_at(h, idx); - data = entry_value(h, e); - remove_entry(h, idx); - - return data; -} - -void *internal_hashmap_steal_first_key(HashmapBase *h) { - struct hashmap_base_entry *e; - void *key; + void *key, *data; unsigned idx; idx = find_first_entry(h); @@ -1592,9 +1554,15 @@ void *internal_hashmap_steal_first_key(HashmapBase *h) { e = bucket_at(h, idx); key = (void*) e->key; - remove_entry(h, idx); + data = entry_value(h, e); - return key; + if (remove) + remove_entry(h, idx); + + if (ret_key) + *ret_key = key; + + return data; } unsigned internal_hashmap_size(HashmapBase *h) { diff --git a/src/basic/hashmap.h b/src/basic/hashmap.h index b771ceccdc..bb2a5c76ec 100644 --- a/src/basic/hashmap.h +++ b/src/basic/hashmap.h @@ -290,36 +290,51 @@ static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) { * the first entry is O(1). */ -void *internal_hashmap_steal_first(HashmapBase *h); +void *internal_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key); +static inline void *hashmap_steal_first_key_and_value(Hashmap *h, void **ret) { + return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret); +} +static inline void *ordered_hashmap_steal_first_key_and_value(OrderedHashmap *h, void **ret) { + return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret); +} +static inline void *hashmap_first_key_and_value(Hashmap *h, void **ret) { + return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret); +} +static inline void *ordered_hashmap_first_key_and_value(OrderedHashmap *h, void **ret) { + return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret); +} + + static inline void *hashmap_steal_first(Hashmap *h) { - return internal_hashmap_steal_first(HASHMAP_BASE(h)); + return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL); } static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) { - return internal_hashmap_steal_first(HASHMAP_BASE(h)); + return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL); } - -void *internal_hashmap_steal_first_key(HashmapBase *h); -static inline void *hashmap_steal_first_key(Hashmap *h) { - return internal_hashmap_steal_first_key(HASHMAP_BASE(h)); -} -static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) { - return internal_hashmap_steal_first_key(HASHMAP_BASE(h)); -} - -void *internal_hashmap_first_key(HashmapBase *h) _pure_; -static inline void *hashmap_first_key(Hashmap *h) { - return internal_hashmap_first_key(HASHMAP_BASE(h)); -} -static inline void *ordered_hashmap_first_key(OrderedHashmap *h) { - return internal_hashmap_first_key(HASHMAP_BASE(h)); -} - -void *internal_hashmap_first(HashmapBase *h) _pure_; static inline void *hashmap_first(Hashmap *h) { - return internal_hashmap_first(HASHMAP_BASE(h)); + return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL); } static inline void *ordered_hashmap_first(OrderedHashmap *h) { - return internal_hashmap_first(HASHMAP_BASE(h)); + return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL); +} + +static inline void *internal_hashmap_first_key(HashmapBase *h, bool remove) { + void *key = NULL; + + (void) internal_hashmap_first_key_and_value(HASHMAP_BASE(h), remove, &key); + return key; +} +static inline void *hashmap_steal_first_key(Hashmap *h) { + return internal_hashmap_first_key(HASHMAP_BASE(h), true); +} +static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) { + return internal_hashmap_first_key(HASHMAP_BASE(h), true); +} +static inline void *hashmap_first_key(Hashmap *h) { + return internal_hashmap_first_key(HASHMAP_BASE(h), false); +} +static inline void *ordered_hashmap_first_key(OrderedHashmap *h) { + return internal_hashmap_first_key(HASHMAP_BASE(h), false); } #define hashmap_clear_with_destructor(_s, _f) \ diff --git a/src/basic/set.h b/src/basic/set.h index 664713810d..0d99d5550d 100644 --- a/src/basic/set.h +++ b/src/basic/set.h @@ -86,7 +86,7 @@ static inline void set_clear_free(Set *s) { /* no set_clear_free_free */ static inline void *set_steal_first(Set *s) { - return internal_hashmap_steal_first(HASHMAP_BASE(s)); + return internal_hashmap_first_key_and_value(HASHMAP_BASE(s), true, NULL); } #define set_clear_with_destructor(_s, _f) \ @@ -105,7 +105,7 @@ static inline void *set_steal_first(Set *s) { /* no set_first_key */ static inline void *set_first(Set *s) { - return internal_hashmap_first(HASHMAP_BASE(s)); + return internal_hashmap_first_key_and_value(HASHMAP_BASE(s), false, NULL); } /* no set_next */