From: Alexander Kuleshov <kuleshovmail@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: Git <git@vger.kernel.org>, Alexander Kuleshov <kuleshovmail@gmail.com>
Subject: [PATCH v2] hashmap API: introduce for_each_hashmap_entry() helper macro
Date: Thu, 17 Mar 2016 16:38:47 +0600 [thread overview]
Message-ID: <1458211127-26963-1-git-send-email-kuleshovmail@gmail.com> (raw)
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 <kuleshovmail@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
next reply other threads:[~2016-03-17 10:39 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-17 10:38 Alexander Kuleshov [this message]
2016-03-17 22:39 ` [PATCH v2] hashmap API: introduce for_each_hashmap_entry() helper macro Karsten Blees
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1458211127-26963-1-git-send-email-kuleshovmail@gmail.com \
--to=kuleshovmail@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).