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

[PATCH 2/9] refs: add repo paramater to _iterator_peel()

From
JTJonathan Tan <jonathantanmy@google.com>
Date
Sep 21, 2021, 16:51 UTC
Message-ID
<e404b5eb1a961fcaf4534e4e31f1c45e03d6de3e.1632242495.git.jonathantanmy@google.com>
In-Reply-To
<cover.1632242495.git.jonathantanmy@google.com>

Split the ref_iterator_peel() function into two functions: one that returns information solely based on what the ref store contains (success, failure, inconclusive), and one that takes a repo parameter and accesses the object store if need be. Update the ref store's callbacks to not access the object store, and to return success/failure/inconclusive instead of a binary success/failure.

This makes it explicit whether a peel attempt may access the object store of a repository.

The approach taken in this commit for peeling is different from the approach taken in the parent commit for advancing:

- It is complicated to reuse the repo field (which determines if an
  object store is ever accessed during advancing, and if yes, which
  object store) added to ref stores in the parent commit; the files ref
  store wraps the packed ref store, and it does not want the packed ref
  store to access any object store during advancing (as described in
  files_ref_iterator_begin()) - thus repo is NULL - but it wants packed
  ref store peeling.
- Having the repo handy when peeling is not as cumbersome as it is when
  advancing. Firstly, the repo in this case is always non-NULL, and
  secondly, peeling is typically followed by reading the object, which
  requires the repo anyway.
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
---
 refs.c                |  2 +-
 refs/debug.c          |  9 +++++----
 refs/files-backend.c  | 12 +++++++-----
 refs/iterator.c       | 38 +++++++++++++++++++++++++++++---------
 refs/packed-backend.c | 14 ++++++++------
 refs/ref-cache.c      |  7 ++++---
 refs/refs-internal.h  | 27 ++++++++++++++++++++++-----
 7 files changed, 76 insertions(+), 33 deletions(-)
diff --git a/refs.c b/refs.c
index 49ddcdac53..3a57893032 100644
--- a/refs.c
+++ b/refs.c
@@ -2012,7 +2012,7 @@ int peel_iterated_oid(const struct object_id *base, struct object_id *peeled)
 	if (current_ref_iter &&
 	    (current_ref_iter->oid == base ||
 	     oideq(current_ref_iter->oid, base)))
-		return ref_iterator_peel(current_ref_iter, peeled);
+		return ref_iterator_peel(current_ref_iter, the_repository, peeled);
 
 	return peel_object(base, peeled) ? -1 : 0;
 }
diff --git a/refs/debug.c b/refs/debug.c
index 1a7a9e11cf..7592de0a4a 100644
--- a/refs/debug.c
+++ b/refs/debug.c
@@ -198,13 +198,14 @@ static int debug_ref_iterator_advance(struct ref_iterator *ref_iterator)
 	return res;
 }
 
-static int debug_ref_iterator_peel(struct ref_iterator *ref_iterator,
-				   struct object_id *peeled)
+static enum ref_iterator_peel_result debug_ref_iterator_peel(
+		struct ref_iterator *ref_iterator,
+		struct object_id *peeled)
 {
 	struct debug_ref_iterator *diter =
 		(struct debug_ref_iterator *)ref_iterator;
-	int res = diter->iter->vtable->peel(diter->iter, peeled);
-	trace_printf_key(&trace_refs, "iterator_peel: %s: %d\n", diter->iter->refname, res);
+	enum ref_iterator_peel_result res = diter->iter->vtable->peel(diter->iter, peeled);
+	trace_printf_key(&trace_refs, "iterator_peel: %s: %d\n", diter->iter->refname, (int) res);
 	return res;
 }
 
diff --git a/refs/files-backend.c b/refs/files-backend.c
index cd145301d0..1faab1cf66 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -757,13 +757,14 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator)
 	return ok;
 }
 
-static int files_ref_iterator_peel(struct ref_iterator *ref_iterator,
-				   struct object_id *peeled)
+static enum ref_iterator_peel_result files_ref_iterator_peel(
+		struct ref_iterator *ref_iterator,
+		struct object_id *peeled)
 {
 	struct files_ref_iterator *iter =
 		(struct files_ref_iterator *)ref_iterator;
 
-	return ref_iterator_peel(iter->iter0, peeled);
+	return ref_iterator_peel_raw(iter->iter0, peeled);
 }
 
 static int files_ref_iterator_abort(struct ref_iterator *ref_iterator)
@@ -2105,8 +2106,9 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator)
 	return ok;
 }
 
-static int files_reflog_iterator_peel(struct ref_iterator *ref_iterator,
-				   struct object_id *peeled)
+static enum ref_iterator_peel_result files_reflog_iterator_peel(
+		struct ref_iterator *ref_iterator,
+		struct object_id *peeled)
 {
 	BUG("ref_iterator_peel() called for reflog_iterator");
 }
diff --git a/refs/iterator.c b/refs/iterator.c
index 5af6554887..ee6b00a7be 100644
--- a/refs/iterator.c
+++ b/refs/iterator.c
@@ -29,10 +29,27 @@ int ref_iterator_advance(struct ref_iterator *ref_iterator)
 	return ok;
 }
 
+enum ref_iterator_peel_result ref_iterator_peel_raw(
+		struct ref_iterator *ref_iterator,
+		struct object_id *peeled)
+{
+	return ref_iterator->vtable->peel(ref_iterator, peeled);
+}
+
 int ref_iterator_peel(struct ref_iterator *ref_iterator,
+		      struct repository *repo,
 		      struct object_id *peeled)
 {
-	return ref_iterator->vtable->peel(ref_iterator, peeled);
+	enum ref_iterator_peel_result result =
+		ref_iterator_peel_raw(ref_iterator, peeled);
+
+	if (repo != the_repository)
+		/* NEEDSWORK: make peel_object() work with all repositories */
+		BUG("ref_iterator_peel() can only be used with the_repository");
+	if (result == REF_ITERATOR_PEEL_INCONCLUSIVE)
+		return peel_object(ref_iterator->oid, peeled) == PEEL_PEELED ?
+			0 : -1;
+	return result == REF_ITERATOR_PEEL_SUCCESS ? 0 : -1;
 }
 
 int ref_iterator_abort(struct ref_iterator *ref_iterator)
@@ -67,8 +84,9 @@ static int empty_ref_iterator_advance(struct ref_iterator *ref_iterator)
 	return ref_iterator_abort(ref_iterator);
 }
 
-static int empty_ref_iterator_peel(struct ref_iterator *ref_iterator,
-				   struct object_id *peeled)
+static enum ref_iterator_peel_result empty_ref_iterator_peel(
+		struct ref_iterator *ref_iterator,
+		struct object_id *peeled)
 {
 	BUG("peel called for empty iterator");
 }
@@ -186,8 +204,9 @@ static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator)
 	return ITER_ERROR;
 }
 
-static int merge_ref_iterator_peel(struct ref_iterator *ref_iterator,
-				   struct object_id *peeled)
+static enum ref_iterator_peel_result merge_ref_iterator_peel(
+		struct ref_iterator *ref_iterator,
+		struct object_id *peeled)
 {
 	struct merge_ref_iterator *iter =
 		(struct merge_ref_iterator *)ref_iterator;
@@ -195,7 +214,7 @@ static int merge_ref_iterator_peel(struct ref_iterator *ref_iterator,
 	if (!iter->current) {
 		BUG("peel called before advance for merge iterator");
 	}
-	return ref_iterator_peel(*iter->current, peeled);
+	return ref_iterator_peel_raw(*iter->current, peeled);
 }
 
 static int merge_ref_iterator_abort(struct ref_iterator *ref_iterator)
@@ -371,13 +390,14 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator)
 	return ok;
 }
 
-static int prefix_ref_iterator_peel(struct ref_iterator *ref_iterator,
-				    struct object_id *peeled)
+static enum ref_iterator_peel_result prefix_ref_iterator_peel(
+		struct ref_iterator *ref_iterator,
+		struct object_id *peeled)
 {
 	struct prefix_ref_iterator *iter =
 		(struct prefix_ref_iterator *)ref_iterator;
 
-	return ref_iterator_peel(iter->iter0, peeled);
+	return ref_iterator_peel_raw(iter->iter0, peeled);
 }
 
 static int prefix_ref_iterator_abort(struct ref_iterator *ref_iterator)
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index f52d5488b8..d258303696 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -872,19 +872,21 @@ static int packed_ref_iterator_advance(struct ref_iterator *ref_iterator)
 	return ok;
 }
 
-static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator,
-				   struct object_id *peeled)
+static enum ref_iterator_peel_result packed_ref_iterator_peel(
+		struct ref_iterator *ref_iterator,
+		struct object_id *peeled)
 {
 	struct packed_ref_iterator *iter =
 		(struct packed_ref_iterator *)ref_iterator;
 
 	if ((iter->base.flags & REF_KNOWS_PEELED)) {
 		oidcpy(peeled, &iter->peeled);
-		return is_null_oid(&iter->peeled) ? -1 : 0;
+		return is_null_oid(&iter->peeled) ?
+			REF_ITERATOR_PEEL_FAILURE : REF_ITERATOR_PEEL_SUCCESS;
 	} else if ((iter->base.flags & (REF_ISBROKEN | REF_ISSYMREF))) {
-		return -1;
+		return REF_ITERATOR_PEEL_FAILURE;
 	} else {
-		return peel_object(&iter->oid, peeled) ? -1 : 0;
+		return REF_ITERATOR_PEEL_INCONCLUSIVE;
 	}
 }
 
@@ -1210,7 +1212,7 @@ static int write_with_updates(struct packed_ref_store *refs,
 			/* Pass the old reference through. */
 
 			struct object_id peeled;
-			int peel_error = ref_iterator_peel(iter, &peeled);
+			int peel_error = ref_iterator_peel(iter, the_repository, &peeled);
 
 			if (write_packed_entry(out, iter->refname,
 					       iter->oid,
diff --git a/refs/ref-cache.c b/refs/ref-cache.c
index 49d732f6db..031b613bb2 100644
--- a/refs/ref-cache.c
+++ b/refs/ref-cache.c
@@ -488,10 +488,11 @@ static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator)
 	}
 }
 
-static int cache_ref_iterator_peel(struct ref_iterator *ref_iterator,
-				   struct object_id *peeled)
+static enum ref_iterator_peel_result cache_ref_iterator_peel(
+		struct ref_iterator *ref_iterator,
+		struct object_id *peeled)
 {
-	return peel_object(ref_iterator->oid, peeled) ? -1 : 0;
+	return REF_ITERATOR_PEEL_INCONCLUSIVE;
 }
 
 static int cache_ref_iterator_abort(struct ref_iterator *ref_iterator)
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index dc0ed65686..4656ef83a3 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -323,11 +323,26 @@ struct ref_iterator {
  */
 int ref_iterator_advance(struct ref_iterator *ref_iterator);
 
+enum ref_iterator_peel_result {
+	REF_ITERATOR_PEEL_SUCCESS,
+	REF_ITERATOR_PEEL_FAILURE,
+	REF_ITERATOR_PEEL_INCONCLUSIVE
+};
+
+/*
+ * Peel the reference currently being viewed by the iterator without
+ * using any information from any object store.
+ */
+enum ref_iterator_peel_result ref_iterator_peel_raw(
+		struct ref_iterator *ref_iterator,
+		struct object_id *peeled);
+
 /*
- * If possible, peel the reference currently being viewed by the
- * iterator. Return 0 on success.
+ * Peel the reference currently being viewed by the iterator, using the object
+ * store if the ref store has insufficient information. Returns 0 upon success.
  */
 int ref_iterator_peel(struct ref_iterator *ref_iterator,
+		      struct repository *repo,
 		      struct object_id *peeled);
 
 /*
@@ -461,10 +476,12 @@ void base_ref_iterator_free(struct ref_iterator *iter);
 typedef int ref_iterator_advance_fn(struct ref_iterator *ref_iterator);
 
 /*
- * Peels the current ref, returning 0 for success or -1 for failure.
+ * Peels the current ref using only information from the ref store. If there is
+ * not enough information, returns REF_ITERATOR_PEEL_INCONCLUSIVE.
  */
-typedef int ref_iterator_peel_fn(struct ref_iterator *ref_iterator,
-				 struct object_id *peeled);
+typedef enum ref_iterator_peel_result ref_iterator_peel_fn(
+		struct ref_iterator *ref_iterator,
+		struct object_id *peeled);
 
 /*
  * Implementations of this function should free any resources specific
-- 
2.33.0.464.g1972c5931b-goog
Previous: Jonathan TanNext: Jonathan Tan
Message 8 of 65 in “No more adding submodule ODB as alternate”
  1. 0/9 No more adding submodule ODB as alternateJonathan Tan, Sep 21, 2021
  2. 1/9 refs: make _advance() check struct repo, not flagJonathan Tan, Sep 21, 2021
  3. Junio C HamanoSep 23, 2021
  4. Jonathan TanSep 24, 2021
  5. Junio C HamanoSep 24, 2021
  6. Jeff KingSep 24, 2021
  7. Jonathan TanSep 24, 2021
  8. 2/9 refs: add repo paramater to _iterator_peel()Jonathan Tan, Sep 21, 2021
  9. 3/9 refs iterator: support non-the_repository advanceJonathan Tan, Sep 21, 2021
  10. 4/9 refs: teach refs_for_each_ref() arbitrary reposJonathan Tan, Sep 21, 2021
  11. 5/9 merge-{ort,recursive}: remove add_submodule_odb()Jonathan Tan, Sep 21, 2021
  12. Elijah NewrenSep 28, 2021
  13. 6/9 object-file: only register submodule ODB if neededJonathan Tan, Sep 21, 2021
  14. 7/9 submodule: pass repo to check_has_commit()Jonathan Tan, Sep 21, 2021
  15. 8/9 refs: change refs_for_each_ref_in() to take repoJonathan Tan, Sep 21, 2021
  16. 9/9 submodule: trace adding submodule ODB as alternateJonathan Tan, Sep 21, 2021
  17. Junio C HamanoSep 23, 2021
  18. 0/9 No more adding submodule ODB as alternateJonathan Tan, Sep 28, 2021
  19. 1/9 refs: plumb repo param in begin-iterator functionsJonathan Tan, Sep 28, 2021
  20. Junio C HamanoSep 28, 2021
  21. 2/9 refs: teach arbitrary repo support to iteratorsJonathan Tan, Sep 28, 2021
  22. Junio C HamanoSep 28, 2021
  23. Jonathan TanSep 29, 2021
  24. 3/9 refs: peeling non-the_repository iterators is BUGJonathan Tan, Sep 28, 2021
  25. 4/9 refs: teach refs_for_each_ref() arbitrary reposJonathan Tan, Sep 28, 2021
  26. Junio C HamanoSep 28, 2021
  27. 5/9 merge-{ort,recursive}: remove add_submodule_odb()Jonathan Tan, Sep 28, 2021
  28. 6/9 object-file: only register submodule ODB if neededJonathan Tan, Sep 28, 2021
  29. 7/9 submodule: pass repo to check_has_commit()Jonathan Tan, Sep 28, 2021
  30. 8/9 refs: change refs_for_each_ref_in() to take repoJonathan Tan, Sep 28, 2021
  31. 9/9 submodule: trace adding submodule ODB as alternateJonathan Tan, Sep 28, 2021
  32. 0/7 No more adding submodule ODB as alternateJonathan Tan, Sep 29, 2021
  33. 1/7 refs: plumb repo into ref storesJonathan Tan, Sep 29, 2021
  34. fixup! refs: plumb repo into ref storesCarlo Marcelo Arenas Belón, Sep 30, 2021
  35. fixup! refs: plumb repo into ref storesGlen Choo, Oct 6, 2021
  36. Jonathan TanOct 8, 2021
  37. Jonathan TanOct 8, 2021
  38. Josh SteadmonOct 7, 2021
  39. Jonathan TanOct 8, 2021
  40. 2/7 refs: teach arbitrary repo support to iteratorsJonathan Tan, Sep 29, 2021
  41. Glen ChooOct 7, 2021
  42. Jonathan TanOct 8, 2021
  43. 3/7 refs: peeling non-the_repository iterators is BUGJonathan Tan, Sep 29, 2021
  44. 5/7 object-file: only register submodule ODB if neededJonathan Tan, Sep 29, 2021
  45. Josh SteadmonOct 7, 2021
  46. Jonathan TanOct 8, 2021
  47. 4/7 merge-{ort,recursive}: remove add_submodule_odb()Jonathan Tan, Sep 29, 2021
  48. Josh SteadmonOct 7, 2021
  49. Jonathan TanOct 8, 2021
  50. 6/7 submodule: pass repo to check_has_commit()Jonathan Tan, Sep 29, 2021
  51. 7/7 submodule: trace adding submodule ODB as alternateJonathan Tan, Sep 29, 2021
  52. Josh SteadmonOct 7, 2021
  53. Jonathan TanOct 8, 2021
  54. Josh SteadmonOct 7, 2021
  55. 0/7 No more adding submodule ODB as alternateJonathan Tan, Oct 8, 2021
  56. 1/7 refs: plumb repo into ref storesJonathan Tan, Oct 8, 2021
  57. 2/7 refs: teach arbitrary repo support to iteratorsJonathan Tan, Oct 8, 2021
  58. 3/7 refs: peeling non-the_repository iterators is BUGJonathan Tan, Oct 8, 2021
  59. 4/7 merge-{ort,recursive}: remove add_submodule_odb()Jonathan Tan, Oct 8, 2021
  60. 5/7 object-file: only register submodule ODB if neededJonathan Tan, Oct 8, 2021
  61. 6/7 submodule: pass repo to check_has_commit()Jonathan Tan, Oct 8, 2021
  62. 7/7 submodule: trace adding submodule ODB as alternateJonathan Tan, Oct 8, 2021
  63. Glen ChooOct 12, 2021
  64. Josh SteadmonOct 12, 2021
  65. Junio C HamanoOct 12, 2021

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.