refs: store submodule ref stores in a hashmap
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> Reviewed-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael Haggerty committed
Feb 10, 2017 at 12:16 UTC
7d4558c462f0d1a280abec59e8c64a2f2b42a9f2
2 files changed
+45
-19
refs.c
+45
-13
@@ -3,6 +3,7 @@
3
*/
4
5
#include "cache.h"
6
+#include "hashmap.h"
7
#include "lockfile.h"
8
#include "refs.h"
9
#include "refs/refs-internal.h"
@@ -1352,11 +1353,41 @@ int resolve_gitlink_ref(const char *submodule, const char *refname,
1353
return 0;
1354
}
1355
1356
+struct submodule_hash_entry
1357
+{
1358
+ struct hashmap_entry ent; /* must be the first member! */
1359
+
1360
+ struct ref_store *refs;
1361
+
1362
+ /* NUL-terminated name of submodule: */
1363
+ char submodule[FLEX_ARRAY];
1364
+};
1365
+
1366
+static int submodule_hash_cmp(const void *entry, const void *entry_or_key,
1367
+ const void *keydata)
1368
+{
1369
+ const struct submodule_hash_entry *e1 = entry, *e2 = entry_or_key;
1370
+ const char *submodule = keydata ? keydata : e2->submodule;
1371
+
1372
+ return strcmp(e1->submodule, submodule);
1373
+}
1374
+
1375
+static struct submodule_hash_entry *alloc_submodule_hash_entry(
1376
+ const char *submodule, struct ref_store *refs)
1377
+{
1378
+ struct submodule_hash_entry *entry;
1379
+
1380
+ FLEX_ALLOC_STR(entry, submodule, submodule);
1381
+ hashmap_entry_init(entry, strhash(submodule));
1382
+ entry->refs = refs;
1383
+ return entry;
1384
+}
1385
+
1386
/* A pointer to the ref_store for the main repository: */
1387
static struct ref_store *main_ref_store;
1388
1358
-/* A linked list of ref_stores for submodules: */
1359
-static struct ref_store *submodule_ref_stores;
1389
+/* A hashmap of ref_stores, stored by submodule name: */
1390
+static struct hashmap submodule_ref_stores;
1391
1392
/*
1393
* Return the ref_store instance for the specified submodule (or the
@@ -1365,17 +1396,18 @@ static struct ref_store *submodule_ref_stores;
1396
*/
1397
static struct ref_store *lookup_ref_store(const char *submodule)
1398
{
1368
- struct ref_store *refs;
1399
+ struct submodule_hash_entry *entry;
1400
1401
if (!submodule)
1402
return main_ref_store;
1403
1373
- for (refs = submodule_ref_stores; refs; refs = refs->next) {
1374
- if (!strcmp(submodule, refs->submodule))
1375
- return refs;
1376
- }
1404
+ if (!submodule_ref_stores.tablesize)
1405
+ /* It's initialized on demand in register_ref_store(). */
1406
+ return NULL;
1407
1378
- return NULL;
1408
+ entry = hashmap_get_from_hash(&submodule_ref_stores,
1409
+ strhash(submodule), submodule);
1410
+ return entry ? entry->refs : NULL;
1411
}
1412
1413
/*
@@ -1389,15 +1421,15 @@ static void register_ref_store(struct ref_store *refs, const char *submodule)
1421
if (main_ref_store)
1422
die("BUG: main_ref_store initialized twice");
1423
1392
- refs->next = NULL;
1424
main_ref_store = refs;
1425
} else {
1395
- if (lookup_ref_store(submodule))
1426
+ if (!submodule_ref_stores.tablesize)
1427
+ hashmap_init(&submodule_ref_stores, submodule_hash_cmp, 0);
1428
+
1429
+ if (hashmap_put(&submodule_ref_stores,
1430
+ alloc_submodule_hash_entry(submodule, refs)))
1431
die("BUG: ref_store for submodule '%s' initialized twice",
1432
submodule);
1398
-
1399
- refs->next = submodule_ref_stores;
1400
- submodule_ref_stores = refs;
1433
}
1434
}
1435
refs/refs-internal.h
-6
@@ -636,12 +636,6 @@ struct ref_store {
636
* reference store:
637
*/
638
const char *submodule;
639
-
640
- /*
641
- * Submodule reference store instances are stored in a linked
642
- * list using this pointer.
643
- */
644
- struct ref_store *next;
639
};
640
641
/*