There is common pattern to traverse a hashmap in git source code:

        hashmap_iter_init(map, &iter);
        while ((entry = hashmap_iter_next(&iter)))
             // do something with entry

This patch introduces the for_each_hashmap_entry() macro for more
simple and clean usage of this pattern. It encapsulates loop over
a hashmap and makes bypass of a hashmap more readable.

This patch has not functioal changes, so behaviour still the same
as before.

Signed-off-by: Alexander Kuleshov <kuleshovm...@gmail.com>
---
 Documentation/technical/api-hashmap.txt | 5 +++++
 builtin/describe.c                      | 5 +++--
 config.c                                | 7 ++++---
 hashmap.c                               | 8 ++++----
 hashmap.h                               | 4 ++++
 submodule-config.c                      | 3 +--
 test-hashmap.c                          | 4 ++--
 7 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/Documentation/technical/api-hashmap.txt 
b/Documentation/technical/api-hashmap.txt
index ad7a5bd..7cb7d2a 100644
--- a/Documentation/technical/api-hashmap.txt
+++ b/Documentation/technical/api-hashmap.txt
@@ -193,6 +193,11 @@ more entries.
 `hashmap_iter_first` is a combination of both (i.e. initializes the iterator
 and returns the first entry, if any).
 
+`for_each_hashmap_entry`::
+
+       Allows iterate over entries of the given map with the given entry
+       and iterator.
+
 `const char *strintern(const char *string)`::
 `const void *memintern(const void *data, size_t len)`::
 
diff --git a/builtin/describe.c b/builtin/describe.c
index 8a25abe..50e3377 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -274,8 +274,9 @@ static void describe(const char *arg, int last_one)
        if (!have_util) {
                struct hashmap_iter iter;
                struct commit *c;
-               struct commit_name *n = hashmap_iter_first(&names, &iter);
-               for (; n; n = hashmap_iter_next(&iter)) {
+               struct commit_name *n;
+
+               for_each_hashmap_entry(&names, n, &iter) {
                        c = lookup_commit_reference_gently(n->peeled, 1);
                        if (c)
                                c->util = n;
diff --git a/config.c b/config.c
index 7ddb287..392d5a2 100644
--- a/config.c
+++ b/config.c
@@ -1382,16 +1382,17 @@ void git_configset_init(struct config_set *cs)
 
 void git_configset_clear(struct config_set *cs)
 {
-       struct config_set_element *entry;
        struct hashmap_iter iter;
+       struct config_set_element *entry;
+
        if (!cs->hash_initialized)
                return;
 
-       hashmap_iter_init(&cs->config_hash, &iter);
-       while ((entry = hashmap_iter_next(&iter))) {
+       for_each_hashmap_entry(&cs->config_hash, entry, &iter) {
                free(entry->key);
                string_list_clear(&entry->value_list, 1);
        }
+
        hashmap_free(&cs->config_hash, 1);
        cs->hash_initialized = 0;
        free(cs->list.items);
diff --git a/hashmap.c b/hashmap.c
index b10b642..c41c12b 100644
--- a/hashmap.c
+++ b/hashmap.c
@@ -141,10 +141,10 @@ void hashmap_free(struct hashmap *map, int free_entries)
                return;
        if (free_entries) {
                struct hashmap_iter iter;
-               struct hashmap_entry *e;
-               hashmap_iter_init(map, &iter);
-               while ((e = hashmap_iter_next(&iter)))
-                       free(e);
+               struct hashmap_entry *entry;
+
+               for_each_hashmap_entry(map, entry, &iter)
+                       free(entry);
        }
        free(map->table);
        memset(map, 0, sizeof(*map));
diff --git a/hashmap.h b/hashmap.h
index ab7958a..772caf2 100644
--- a/hashmap.h
+++ b/hashmap.h
@@ -95,4 +95,8 @@ static inline const char *strintern(const char *string)
        return memintern(string, strlen(string));
 }
 
+#define for_each_hashmap_entry(map, entry, iter)               \
+       for (entry = hashmap_iter_first(map, iter); entry;      \
+            entry = hashmap_iter_next(iter))
+
 #endif
diff --git a/submodule-config.c b/submodule-config.c
index b82d1fb..5a8d7fa 100644
--- a/submodule-config.c
+++ b/submodule-config.c
@@ -73,8 +73,7 @@ static void cache_free(struct submodule_cache *cache)
         * allocation of struct submodule entries. Each is allocated by
         * their .gitmodule blob sha1 and submodule name.
         */
-       hashmap_iter_init(&cache->for_name, &iter);
-       while ((entry = hashmap_iter_next(&iter)))
+       for_each_hashmap_entry(&cache->for_name, entry, &iter)
                free_one_config(entry);
 
        hashmap_free(&cache->for_path, 1);
diff --git a/test-hashmap.c b/test-hashmap.c
index cc2891d..917d188 100644
--- a/test-hashmap.c
+++ b/test-hashmap.c
@@ -225,8 +225,8 @@ int main(int argc, char *argv[])
                } else if (!strcmp("iterate", cmd)) {
 
                        struct hashmap_iter iter;
-                       hashmap_iter_init(&map, &iter);
-                       while ((entry = hashmap_iter_next(&iter)))
+
+                       for_each_hashmap_entry(&map, entry, &iter)
                                printf("%s %s\n", entry->key, get_value(entry));
 
                } else if (!strcmp("size", cmd)) {
-- 
2.8.0.rc3.212.g1f992f2.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to