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>
This commit is contained in:
parent
ba88add581
commit
7d4558c462
58
refs.c
58
refs.c
@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "hashmap.h"
|
||||||
#include "lockfile.h"
|
#include "lockfile.h"
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
#include "refs/refs-internal.h"
|
#include "refs/refs-internal.h"
|
||||||
@ -1352,11 +1353,41 @@ int resolve_gitlink_ref(const char *submodule, const char *refname,
|
|||||||
return 0;
|
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: */
|
/* A pointer to the ref_store for the main repository: */
|
||||||
static struct ref_store *main_ref_store;
|
static struct ref_store *main_ref_store;
|
||||||
|
|
||||||
/* A linked list of ref_stores for submodules: */
|
/* A hashmap of ref_stores, stored by submodule name: */
|
||||||
static struct ref_store *submodule_ref_stores;
|
static struct hashmap submodule_ref_stores;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the ref_store instance for the specified submodule (or the
|
* 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)
|
static struct ref_store *lookup_ref_store(const char *submodule)
|
||||||
{
|
{
|
||||||
struct ref_store *refs;
|
struct submodule_hash_entry *entry;
|
||||||
|
|
||||||
if (!submodule)
|
if (!submodule)
|
||||||
return main_ref_store;
|
return main_ref_store;
|
||||||
|
|
||||||
for (refs = submodule_ref_stores; refs; refs = refs->next) {
|
if (!submodule_ref_stores.tablesize)
|
||||||
if (!strcmp(submodule, refs->submodule))
|
/* It's initialized on demand in register_ref_store(). */
|
||||||
return refs;
|
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)
|
if (main_ref_store)
|
||||||
die("BUG: main_ref_store initialized twice");
|
die("BUG: main_ref_store initialized twice");
|
||||||
|
|
||||||
refs->next = NULL;
|
|
||||||
main_ref_store = refs;
|
main_ref_store = refs;
|
||||||
} else {
|
} 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",
|
die("BUG: ref_store for submodule '%s' initialized twice",
|
||||||
submodule);
|
submodule);
|
||||||
|
|
||||||
refs->next = submodule_ref_stores;
|
|
||||||
submodule_ref_stores = refs;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,12 +636,6 @@ struct ref_store {
|
|||||||
* reference store:
|
* reference store:
|
||||||
*/
|
*/
|
||||||
const char *submodule;
|
const char *submodule;
|
||||||
|
|
||||||
/*
|
|
||||||
* Submodule reference store instances are stored in a linked
|
|
||||||
* list using this pointer.
|
|
||||||
*/
|
|
||||||
struct ref_store *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user