git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 5/9] refs: store submodule ref stores in a hashmap

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Feb 10, 2017, 11:16 UTC
Message-ID
<3f4b16b0816d13283cb25885eb3fdafd70caa2e7.1486724698.git.mhagger@alum.mit.edu>
In-Reply-To
<cover.1486724698.git.mhagger@alum.mit.edu>

Aside from scaling better, this means that the submodule name needn't be stored in the ref_store instance anymore (which will be changed in a moment). This, in turn, will help loosen the strict 1:1 relationship between ref_stores and submodules.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 refs.c               | 58 ++++++++++++++++++++++++++++++++++++++++------------
 refs/refs-internal.h |  6 ------
 2 files changed, 45 insertions(+), 19 deletions(-)
diff --git a/refs.c b/refs.c
index d7158b6..5121c57 100644
--- a/refs.c
+++ b/refs.c
@@ -3,6 +3,7 @@
  */
 
 #include "cache.h"
+#include "hashmap.h"
 #include "lockfile.h"
 #include "refs.h"
 #include "refs/refs-internal.h"
@@ -1352,11 +1353,41 @@ int resolve_gitlink_ref(const char *submodule, const char *refname,
 	return 0;
 }
 
+struct submodule_hash_entry
+{
+	struct hashmap_entry ent; /* must be the first member! */
+
+	struct ref_store *refs;
+
+	/* NUL-terminated name of submodule: */
+	char submodule[FLEX_ARRAY];
+};
+
+static int submodule_hash_cmp(const void *entry, const void *entry_or_key,
+			      const void *keydata)
+{
+	const struct submodule_hash_entry *e1 = entry, *e2 = entry_or_key;
+	const char *submodule = keydata ? keydata : e2->submodule;
+
+	return strcmp(e1->submodule, submodule);
+}
+
+static struct submodule_hash_entry *alloc_submodule_hash_entry(
+		const char *submodule, struct ref_store *refs)
+{
+	struct submodule_hash_entry *entry;
+
+	FLEX_ALLOC_STR(entry, submodule, submodule);
+	hashmap_entry_init(entry, strhash(submodule));
+	entry->refs = refs;
+	return entry;
+}
+
 /* A pointer to the ref_store for the main repository: */
 static struct ref_store *main_ref_store;
 
-/* A linked list of ref_stores for submodules: */
-static struct ref_store *submodule_ref_stores;
+/* A hashmap of ref_stores, stored by submodule name: */
+static struct hashmap submodule_ref_stores;
 
 /*
  * Return the ref_store instance for the specified submodule (or the
@@ -1365,17 +1396,18 @@ static struct ref_store *submodule_ref_stores;
  */
 static struct ref_store *lookup_ref_store(const char *submodule)
 {
-	struct ref_store *refs;
+	struct submodule_hash_entry *entry;
 
 	if (!submodule)
 		return main_ref_store;
 
-	for (refs = submodule_ref_stores; refs; refs = refs->next) {
-		if (!strcmp(submodule, refs->submodule))
-			return refs;
-	}
+	if (!submodule_ref_stores.tablesize)
+		/* It's initialized on demand in register_ref_store(). */
+		return NULL;
 
-	return NULL;
+	entry = hashmap_get_from_hash(&submodule_ref_stores,
+				      strhash(submodule), submodule);
+	return entry ? entry->refs : NULL;
 }
 
 /*
@@ -1389,15 +1421,15 @@ static void register_ref_store(struct ref_store *refs, const char *submodule)
 		if (main_ref_store)
 			die("BUG: main_ref_store initialized twice");
 
-		refs->next = NULL;
 		main_ref_store = refs;
 	} else {
-		if (lookup_ref_store(submodule))
+		if (!submodule_ref_stores.tablesize)
+			hashmap_init(&submodule_ref_stores, submodule_hash_cmp, 0);
+
+		if (hashmap_put(&submodule_ref_stores,
+				alloc_submodule_hash_entry(submodule, refs)))
 			die("BUG: ref_store for submodule '%s' initialized twice",
 			    submodule);
-
-		refs->next = submodule_ref_stores;
-		submodule_ref_stores = refs;
 	}
 }
 
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index d8a7eb1..07fd208 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -636,12 +636,6 @@ struct ref_store {
 	 * reference store:
 	 */
 	const char *submodule;
-
-	/*
-	 * Submodule reference store instances are stored in a linked
-	 * list using this pointer.
-	 */
-	struct ref_store *next;
 };
 
 /*
-- 
2.9.3
Previous: Junio C HamanoNext: Jeff King
Message 14 of 18 in “Store submodules in a hash, not a linked list”
  1. 0/9 Store submodules in a hash, not a linked listMichael Haggerty, Feb 10, 2017
  2. 2/9 refs: make some ref_store lookup functions privateMichael Haggerty, Feb 10, 2017
  3. 7/9 base_ref_store_init(): remove submodule argumentMichael Haggerty, Feb 10, 2017
  4. 9/9 read_loose_refs(): read refs using resolve_ref_recursively()Michael Haggerty, Feb 10, 2017
  5. Junio C HamanoFeb 10, 2017
  6. Michael HaggertyFeb 13, 2017
  7. Junio C HamanoFeb 13, 2017
  8. 6/9 refs: push the submodule attribute downMichael Haggerty, Feb 10, 2017
  9. 4/9 register_ref_store(): new functionMichael Haggerty, Feb 10, 2017
  10. 8/9 files_ref_store::submodule: use NULL for the main repositoryMichael Haggerty, Feb 10, 2017
  11. 3/9 refs: remove some unnecessary handling of submodule == ""Michael Haggerty, Feb 10, 2017
  12. 1/9 refs: reorder some function definitionsMichael Haggerty, Feb 10, 2017
  13. Junio C HamanoFeb 10, 2017
  14. 5/9 refs: store submodule ref stores in a hashmapMichael Haggerty, Feb 10, 2017
  15. Jeff KingFeb 10, 2017
  16. Stefan BellerFeb 10, 2017
  17. Junio C HamanoFeb 10, 2017
  18. David TurnerFeb 13, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.