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

[PATCH 2/6] refs: minor restructuring of cached refs data.

From
Junio C Hamano <junkio@cox.net>
Date
Sep 30, 2006, 22:30 UTC
Message-ID
<7vr6xt9edt.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<7v1wptc7ou.fsf@assigned-by-dhcp.cox.net>

Once we read packed and loose refs, for_each_ref() and friends kept using them even after write_ref_sha1() and delete_ref() changed the refs. This adds invalidate_cached_refs() as a way to flush the cached information.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 * This and the previous one are essentially the same as my previous
   two patch series.
   getting rid of "we run only once" mentality.  otherwise we
   can never libify the thing...
 refs.c |   56 +++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/refs.c b/refs.c
index b433c0c..6ee5f96 100644
--- a/refs.c
+++ b/refs.c
@@ -66,12 +66,42 @@ static struct ref_list *add_ref(const ch
 	return list;
 }
 
-static struct ref_list *get_packed_refs(void)
+/*
+ * Future: need to be in "struct repository"
+ * when doing a full libification.
+ */
+struct cached_refs {
+	char did_loose;
+	char did_packed;
+	struct ref_list *loose;
+	struct ref_list *packed;
+} cached_refs;
+
+static void free_ref_list(struct ref_list *list)
+{
+	struct ref_list *next;
+	for ( ; list; list = next) {
+		next = list->next;
+		free(list);
+	}
+}
+
+static void invalidate_cached_refs(void)
 {
-	static int did_refs = 0;
-	static struct ref_list *refs = NULL;
+	struct cached_refs *ca = &cached_refs;
+
+	if (ca->did_loose && ca->loose)
+		free_ref_list(ca->loose);
+	if (ca->did_packed && ca->packed)
+		free_ref_list(ca->packed);
+	ca->loose = ca->packed = NULL;
+	ca->did_loose = ca->did_packed = 0;
+}
 
-	if (!did_refs) {
+static struct ref_list *get_packed_refs(void)
+{
+	if (!cached_refs.did_packed) {
+		struct ref_list *refs = NULL;
 		FILE *f = fopen(git_path("packed-refs"), "r");
 		if (f) {
 			struct ref_list *list = NULL;
@@ -86,9 +116,10 @@ static struct ref_list *get_packed_refs(
 			fclose(f);
 			refs = list;
 		}
-		did_refs = 1;
+		cached_refs.packed = refs;
+		cached_refs.did_packed = 1;
 	}
-	return refs;
+	return cached_refs.packed;
 }
 
 static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
@@ -138,14 +169,11 @@ static struct ref_list *get_ref_dir(cons
 
 static struct ref_list *get_loose_refs(void)
 {
-	static int did_refs = 0;
-	static struct ref_list *refs = NULL;
-
-	if (!did_refs) {
-		refs = get_ref_dir("refs", NULL);
-		did_refs = 1;
+	if (!cached_refs.did_loose) {
+		cached_refs.loose = get_ref_dir("refs", NULL);
+		cached_refs.did_loose = 1;
 	}
-	return refs;
+	return cached_refs.loose;
 }
 
 /* We allow "recursive" symbolic refs. Only within reason, though */
@@ -401,6 +429,7 @@ int delete_ref(const char *refname, unsi
 		fprintf(stderr, "warning: unlink(%s) failed: %s",
 			lock->log_file, strerror(errno));
 
+	invalidate_cached_refs();
 	return ret;
 }
 
@@ -665,6 +694,7 @@ int write_ref_sha1(struct ref_lock *lock
 		unlock_ref(lock);
 		return -1;
 	}
+	invalidate_cached_refs();
 	if (log_ref_write(lock, sha1, logmsg) < 0) {
 		unlock_ref(lock);
 		return -1;
-- 
1.4.2.1.g5a98f
Previous: Junio C HamanoNext: Junio C Hamano
Message 5 of 14 in “Move code resolving packed refs into its own function.”
  1. 1/2 Move code resolving packed refs into its own function.Christian Couder, Sep 30, 2006
  2. Junio C HamanoSep 30, 2006
  3. 0/6 ref deletion and D/F conflict avoidance with packed-refs.Junio C Hamano, Sep 30, 2006
  4. 1/6 ref locking: allow 'foo' when 'foo/bar' used to exist but not anymore.Junio C Hamano, Sep 30, 2006
  5. 2/6 refs: minor restructuring of cached refs data.Junio C Hamano, Sep 30, 2006
  6. 3/6 lock_ref_sha1(): do not sometimes error() and sometimes die().Junio C Hamano, Sep 30, 2006
  7. 4/6 lock_ref_sha1(): check D/F conflict with packed ref when creating.Junio C Hamano, Sep 30, 2006
  8. 5/6 delete_ref(): delete packed refJunio C Hamano, Sep 30, 2006
  9. 6/6 git-branch: remove D/F check done by hand.Junio C Hamano, Sep 30, 2006
  10. Jeff KingSep 30, 2006
  11. Christian CouderOct 1, 2006
  12. Junio C HamanoOct 1, 2006
  13. Jakub NarebskiOct 3, 2006
  14. Junio C HamanoOct 3, 2006

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.