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

[PATCH 04/16] refs: track ref stores via strmap

From
Patrick Steinhardt <ps@pks.im>
Date
May 16, 2024, 08:04 UTC
Message-ID
<52798936a290ffa64b244f9bbd1c5f17d1b24db3.1715836916.git.ps@pks.im>
In-Reply-To
<cover.1715836916.git.ps@pks.im>

The refs code has two global maps that track the submodule and worktree ref stores. Even though both of these maps track values by strings, we still use a `struct hashmap` instead of a `struct strmap`. This has the benefit of saving us an allocation because we can combine key and value in a single struct. But it does introduce significant complexity that is completely unneeded.

Refactor the code to use `struct strmap`s instead to reduce complexity. It's unlikely that this will have any real-world impact on performance given that most repositories likely won't have all that many ref stores. Furthermore, this refactoring allows us to de-globalize those maps and move them into `struct repository` in a subsequent commit more easily.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 refs.c | 71 ++++++++++++----------------------------------------------
 1 file changed, 14 insertions(+), 57 deletions(-)
diff --git a/refs.c b/refs.c
index edb0a633d1..542acb25ff 100644
--- a/refs.c
+++ b/refs.c
@@ -6,7 +6,7 @@
 #include "advice.h"
 #include "config.h"
 #include "environment.h"
-#include "hashmap.h"
+#include "strmap.h"
 #include "gettext.h"
 #include "hex.h"
 #include "lockfile.h"
@@ -1960,66 +1960,27 @@ int resolve_gitlink_ref(const char *submodule, const char *refname,
 	return 0;
 }
 
-struct ref_store_hash_entry
-{
-	struct hashmap_entry ent;
-
-	struct ref_store *refs;
-
-	/* NUL-terminated identifier of the ref store: */
-	char name[FLEX_ARRAY];
-};
+/* A strmap of ref_stores, stored by submodule name: */
+static struct strmap submodule_ref_stores;
 
-static int ref_store_hash_cmp(const void *cmp_data UNUSED,
-			      const struct hashmap_entry *eptr,
-			      const struct hashmap_entry *entry_or_key,
-			      const void *keydata)
-{
-	const struct ref_store_hash_entry *e1, *e2;
-	const char *name;
-
-	e1 = container_of(eptr, const struct ref_store_hash_entry, ent);
-	e2 = container_of(entry_or_key, const struct ref_store_hash_entry, ent);
-	name = keydata ? keydata : e2->name;
-
-	return strcmp(e1->name, name);
-}
-
-static struct ref_store_hash_entry *alloc_ref_store_hash_entry(
-		const char *name, struct ref_store *refs)
-{
-	struct ref_store_hash_entry *entry;
-
-	FLEX_ALLOC_STR(entry, name, name);
-	hashmap_entry_init(&entry->ent, strhash(name));
-	entry->refs = refs;
-	return entry;
-}
-
-/* A hashmap of ref_stores, stored by submodule name: */
-static struct hashmap submodule_ref_stores;
-
-/* A hashmap of ref_stores, stored by worktree id: */
-static struct hashmap worktree_ref_stores;
+/* A strmap of ref_stores, stored by worktree id: */
+static struct strmap worktree_ref_stores;
 
 /*
  * Look up a ref store by name. If that ref_store hasn't been
  * registered yet, return NULL.
  */
-static struct ref_store *lookup_ref_store_map(struct hashmap *map,
+static struct ref_store *lookup_ref_store_map(struct strmap *map,
 					      const char *name)
 {
-	struct ref_store_hash_entry *entry;
-	unsigned int hash;
+	struct strmap_entry *entry;
 
-	if (!map->tablesize)
+	if (!map->map.tablesize)
 		/* It's initialized on demand in register_ref_store(). */
 		return NULL;
 
-	hash = strhash(name);
-	entry = hashmap_get_entry_from_hash(map, hash, name,
-					struct ref_store_hash_entry, ent);
-	return entry ? entry->refs : NULL;
+	entry = strmap_get_entry(map, name);
+	return entry ? entry->value : NULL;
 }
 
 /*
@@ -2064,18 +2025,14 @@ struct ref_store *get_main_ref_store(struct repository *r)
  * Associate a ref store with a name. It is a fatal error to call this
  * function twice for the same name.
  */
-static void register_ref_store_map(struct hashmap *map,
+static void register_ref_store_map(struct strmap *map,
 				   const char *type,
 				   struct ref_store *refs,
 				   const char *name)
 {
-	struct ref_store_hash_entry *entry;
-
-	if (!map->tablesize)
-		hashmap_init(map, ref_store_hash_cmp, NULL, 0);
-
-	entry = alloc_ref_store_hash_entry(name, refs);
-	if (hashmap_put(map, &entry->ent))
+	if (!map->map.tablesize)
+		strmap_init(map);
+	if (strmap_put(map, name, refs))
 		BUG("%s ref_store '%s' initialized twice", type, name);
 }
 
-- 
2.45.1.190.g19fe900cfc.dirty
Previous: Patrick SteinhardtNext: Junio C Hamano
Message 13 of 33 in “refs: drop all references to `the_repository`”
  1. 00/16 refs: drop all references to `the_repository`Patrick Steinhardt, May 16, 2024
  2. 01/16 refs: adjust names for `init` and `init_db` callbacksPatrick Steinhardt, May 16, 2024
  3. Karthik NayakMay 16, 2024
  4. 02/16 refs: rename `init_db` callback to avoid confusionPatrick Steinhardt, May 16, 2024
  5. Karthik NayakMay 16, 2024
  6. Junio C HamanoMay 16, 2024
  7. Patrick SteinhardtMay 17, 2024
  8. 03/16 refs: implement releasing ref storagesPatrick Steinhardt, May 16, 2024
  9. Karthik NayakMay 16, 2024
  10. Junio C HamanoMay 16, 2024
  11. Patrick SteinhardtMay 17, 2024
  12. Patrick SteinhardtMay 17, 2024
  13. 04/16 refs: track ref stores via strmapPatrick Steinhardt, May 16, 2024
  14. Junio C HamanoMay 16, 2024
  15. 05/16 refs: pass repo when retrieving submodule ref storePatrick Steinhardt, May 16, 2024
  16. Junio C HamanoMay 16, 2024
  17. Patrick SteinhardtMay 17, 2024
  18. 06/16 refs: refactor `resolve_gitlink_ref()` to accept a repositoryPatrick Steinhardt, May 16, 2024
  19. Junio C HamanoMay 16, 2024
  20. 07/16 refs: retrieve worktree ref stores via associated repositoryPatrick Steinhardt, May 16, 2024
  21. 08/16 refs: convert iteration over replace refs to accept ref storePatrick Steinhardt, May 16, 2024
  22. 09/16 refs: pass ref store when detecting dangling symrefsPatrick Steinhardt, May 16, 2024
  23. 10/16 refs: move object peeling into "object.c"Patrick Steinhardt, May 16, 2024
  24. Junio C HamanoMay 16, 2024
  25. 11/16 refs: pass repo when peeling objectsPatrick Steinhardt, May 16, 2024
  26. 12/16 refs: drop `git_default_branch_name()`Patrick Steinhardt, May 16, 2024
  27. Karthik NayakMay 16, 2024
  28. 13/16 refs: remove `dwim_log()`Patrick Steinhardt, May 16, 2024
  29. 14/16 refs/files: use correct repositoryPatrick Steinhardt, May 16, 2024
  30. 15/16 refs/files: remove references to `the_hash_algo`Patrick Steinhardt, May 16, 2024
  31. 16/16 refs/packed: remove references to `the_hash_algo`Patrick Steinhardt, May 16, 2024
  32. Karthik NayakMay 16, 2024
  33. Patrick SteinhardtMay 17, 2024

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.