Merge branch 'mh/ref-api'

* mh/ref-api:
  clear_ref_cache(): inline function
  write_ref_sha1(): only invalidate the loose ref cache
  clear_ref_cache(): extract two new functions
  clear_ref_cache(): rename parameter
  invalidate_ref_cache(): expose this function in the refs API
  invalidate_ref_cache(): take the submodule as parameter
  invalidate_ref_cache(): rename function from invalidate_cached_refs()
This commit is contained in:
Junio C Hamano
2011-10-21 16:04:36 -07:00
2 changed files with 39 additions and 28 deletions

59
refs.c
View File

@ -134,15 +134,15 @@ static struct ref_entry *search_ref_array(struct ref_array *array, const char *n
* Future: need to be in "struct repository" * Future: need to be in "struct repository"
* when doing a full libification. * when doing a full libification.
*/ */
static struct cached_refs { static struct ref_cache {
struct cached_refs *next; struct ref_cache *next;
char did_loose; char did_loose;
char did_packed; char did_packed;
struct ref_array loose; struct ref_array loose;
struct ref_array packed; struct ref_array packed;
/* The submodule name, or "" for the main repo. */ /* The submodule name, or "" for the main repo. */
char name[FLEX_ARRAY]; char name[FLEX_ARRAY];
} *cached_refs; } *ref_cache;
static struct ref_entry *current_ref; static struct ref_entry *current_ref;
@ -158,36 +158,41 @@ static void free_ref_array(struct ref_array *array)
array->refs = NULL; array->refs = NULL;
} }
static void clear_cached_refs(struct cached_refs *ca) static void clear_packed_ref_cache(struct ref_cache *refs)
{ {
if (ca->did_loose) if (refs->did_packed)
free_ref_array(&ca->loose); free_ref_array(&refs->packed);
if (ca->did_packed) refs->did_packed = 0;
free_ref_array(&ca->packed);
ca->did_loose = ca->did_packed = 0;
} }
static struct cached_refs *create_cached_refs(const char *submodule) static void clear_loose_ref_cache(struct ref_cache *refs)
{
if (refs->did_loose)
free_ref_array(&refs->loose);
refs->did_loose = 0;
}
static struct ref_cache *create_ref_cache(const char *submodule)
{ {
int len; int len;
struct cached_refs *refs; struct ref_cache *refs;
if (!submodule) if (!submodule)
submodule = ""; submodule = "";
len = strlen(submodule) + 1; len = strlen(submodule) + 1;
refs = xcalloc(1, sizeof(struct cached_refs) + len); refs = xcalloc(1, sizeof(struct ref_cache) + len);
memcpy(refs->name, submodule, len); memcpy(refs->name, submodule, len);
return refs; return refs;
} }
/* /*
* Return a pointer to a cached_refs for the specified submodule. For * Return a pointer to a ref_cache for the specified submodule. For
* the main repository, use submodule==NULL. The returned structure * the main repository, use submodule==NULL. The returned structure
* will be allocated and initialized but not necessarily populated; it * will be allocated and initialized but not necessarily populated; it
* should not be freed. * should not be freed.
*/ */
static struct cached_refs *get_cached_refs(const char *submodule) static struct ref_cache *get_ref_cache(const char *submodule)
{ {
struct cached_refs *refs = cached_refs; struct ref_cache *refs = ref_cache;
if (!submodule) if (!submodule)
submodule = ""; submodule = "";
while (refs) { while (refs) {
@ -196,19 +201,17 @@ static struct cached_refs *get_cached_refs(const char *submodule)
refs = refs->next; refs = refs->next;
} }
refs = create_cached_refs(submodule); refs = create_ref_cache(submodule);
refs->next = cached_refs; refs->next = ref_cache;
cached_refs = refs; ref_cache = refs;
return refs; return refs;
} }
static void invalidate_cached_refs(void) void invalidate_ref_cache(const char *submodule)
{ {
struct cached_refs *refs = cached_refs; struct ref_cache *refs = get_ref_cache(submodule);
while (refs) { clear_packed_ref_cache(refs);
clear_cached_refs(refs); clear_loose_ref_cache(refs);
refs = refs->next;
}
} }
static void read_packed_refs(FILE *f, struct ref_array *array) static void read_packed_refs(FILE *f, struct ref_array *array)
@ -257,7 +260,7 @@ void clear_extra_refs(void)
static struct ref_array *get_packed_refs(const char *submodule) static struct ref_array *get_packed_refs(const char *submodule)
{ {
struct cached_refs *refs = get_cached_refs(submodule); struct ref_cache *refs = get_ref_cache(submodule);
if (!refs->did_packed) { if (!refs->did_packed) {
const char *packed_refs_file; const char *packed_refs_file;
@ -379,7 +382,7 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
static struct ref_array *get_loose_refs(const char *submodule) static struct ref_array *get_loose_refs(const char *submodule)
{ {
struct cached_refs *refs = get_cached_refs(submodule); struct ref_cache *refs = get_ref_cache(submodule);
if (!refs->did_loose) { if (!refs->did_loose) {
get_ref_dir(submodule, "refs", &refs->loose); get_ref_dir(submodule, "refs", &refs->loose);
@ -1238,7 +1241,7 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
ret |= repack_without_ref(refname); ret |= repack_without_ref(refname);
unlink_or_warn(git_path("logs/%s", lock->ref_name)); unlink_or_warn(git_path("logs/%s", lock->ref_name));
invalidate_cached_refs(); invalidate_ref_cache(NULL);
unlock_ref(lock); unlock_ref(lock);
return ret; return ret;
} }
@ -1529,7 +1532,7 @@ int write_ref_sha1(struct ref_lock *lock,
unlock_ref(lock); unlock_ref(lock);
return -1; return -1;
} }
invalidate_cached_refs(); clear_loose_ref_cache(get_ref_cache(NULL));
if (log_ref_write(lock->ref_name, lock->old_sha1, sha1, logmsg) < 0 || if (log_ref_write(lock->ref_name, lock->old_sha1, sha1, logmsg) < 0 ||
(strcmp(lock->ref_name, lock->orig_ref_name) && (strcmp(lock->ref_name, lock->orig_ref_name) &&
log_ref_write(lock->orig_ref_name, lock->old_sha1, sha1, logmsg) < 0)) { log_ref_write(lock->orig_ref_name, lock->old_sha1, sha1, logmsg) < 0)) {

8
refs.h
View File

@ -80,6 +80,14 @@ extern void unlock_ref(struct ref_lock *lock);
/** Writes sha1 into the ref specified by the lock. **/ /** Writes sha1 into the ref specified by the lock. **/
extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, const char *msg); extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, const char *msg);
/*
* Invalidate the reference cache for the specified submodule. Use
* submodule=NULL to invalidate the cache for the main module. This
* function must be called if references are changed via a mechanism
* other than the refs API.
*/
extern void invalidate_ref_cache(const char *submodule);
/** Setup reflog before using. **/ /** Setup reflog before using. **/
int log_ref_setup(const char *ref_name, char *logfile, int bufsize); int log_ref_setup(const char *ref_name, char *logfile, int bufsize);