"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
gotwebd got_get_repo_age simplification
To:
gameoftrees@openbsd.org
Date:
Thu, 21 Nov 2024 10:08:34 +0100

Download raw body.

Thread
Instead of sorting refs by name and then hunting for the youngest
commits in that list, obtain an appropriately sorted list via
got_ref_cmp_by_commit_timestamp_descending and then pick the first
ref from this list.

And in the case were we already know which ref to check, just open
this ref directly instead of listing all the refs.

Easier to read and should improve performance in both cases.

This diff is hard to read. I'd recommend applying it and reviewing
the result.

ok?

diff /home/stsp/src/got
commit - ece731b025b35fd112ea1faebfabb163b61aacbe
path + /home/stsp/src/got
blob - f4a93f9f22c2a2ae93a2bf822794bade8af45b6c
file + gotwebd/got_operations.c
--- gotwebd/got_operations.c
+++ gotwebd/got_operations.c
@@ -116,60 +116,46 @@ got_get_repo_owner(char **owner, struct request *c)
 	return NULL;
 }
 
+/*
+ * Find the youngest branch tip in the repository, or the age of
+ * a specific branch tip if a name was provided by the caller.
+ */
 const struct got_error *
 got_get_repo_age(time_t *repo_age, struct request *c, const char *refname)
 {
 	const struct got_error *error = NULL;
 	struct transport *t = c->t;
 	struct got_repository *repo = t->repo;
-	struct got_commit_object *commit = NULL;
-	struct got_reflist_head refs;
-	struct got_reflist_entry *re;
-	time_t committer_time = 0, cmp_time = 0;
 
-	TAILQ_INIT(&refs);
-
 	*repo_age = 0;
 
-	error = got_ref_list(&refs, repo, "refs/heads",
-	    got_ref_cmp_by_name, NULL);
-	if (error)
-		goto done;
+	if (refname) {
+		struct got_reference *ref;
+		
+		error = got_ref_open(&ref, repo, refname, 0);
+		if (error)
+			return error;
 
-	/*
-	 * Find the youngest branch tip in the repository, or the age of
-	 * the a specific branch tip if a name was provided by the caller.
-	 */
-	TAILQ_FOREACH(re, &refs, entry) {
-		struct got_object_id *id = NULL;
+		*repo_age = got_ref_get_mtime(ref);
+		got_ref_close(ref);
+	} else {
+		struct got_reflist_head refs;
+		struct got_reflist_entry *re;
 
-		if (refname && strcmp(got_ref_get_name(re->ref), refname) != 0)
-			continue;
+		TAILQ_INIT(&refs);
 
-		error = got_ref_resolve(&id, repo, re->ref);
+		error = got_ref_list(&refs, repo, "refs/heads",
+		    got_ref_cmp_by_commit_timestamp_descending, repo);
 		if (error)
-			goto done;
+			return error;
 
-		error = got_object_open_as_commit(&commit, repo, id);
-		free(id);
-		if (error)
-			goto done;
-
-		committer_time =
-		    got_object_commit_get_committer_time(commit);
-		got_object_commit_close(commit);
-		if (cmp_time < committer_time)
-			cmp_time = committer_time;
-
-		if (refname)
-			break;
+		re = TAILQ_FIRST(&refs);
+		if (re)
+			*repo_age = got_ref_get_mtime(re->ref);
+		got_ref_list_free(&refs);
 	}
 
-	if (cmp_time != 0)
-		*repo_age = cmp_time;
- done:
-	got_ref_list_free(&refs);
-	return error;
+	return NULL;
 }
 
 static const struct got_error *