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

[PATCH v4 1/8] packfile: introduce 'find_kept_pack_entry()'

From
Taylor Blau <me@ttaylorr.com>
Date
Feb 23, 2021, 02:25 UTC
Message-ID
<bb674e511914b7070a8f985a30dd09f9a3ed58db.1614047097.git.me@ttaylorr.com>
In-Reply-To
<cover.1614047097.git.me@ttaylorr.com>

Future callers will want a function to fill a 'struct pack_entry' for a given object id but _only_ from its position in any kept pack(s).

In particular, an new 'git repack' mode which ensures the resulting packs form a geometric progress by object count will mark packs that it does not want to repack as "kept in-core", and it will want to halt a reachability traversal as soon as it visits an object in any of the kept packs. But, it does not want to halt the traversal at non-kept, or .keep packs.

The obvious alternative is 'find_pack_entry()', but this doesn't quite suffice since it only returns the first pack it finds, which may or may not be kept (and the mru cache makes it unpredictable which one you'll get if there are options).

Short of that, you could walk over all packs looking for the object in each one, but it scales with the number of packs, which may be prohibitive.

Introduce 'find_kept_pack_entry()', a function which is like 'find_pack_entry()', but only fills in objects in the kept packs.

Handle packs which have .keep files, as well as in-core kept packs separately, since certain callers will want to distinguish one from the other. (Though on-disk and in-core kept packs share the adjective "kept", it is best to think of the two sets as independent.)

There is a gotcha when looking up objects that are duplicated in kept and non-kept packs, particularly when the MIDX stores the non-kept version and the caller asked for kept objects only. This could be resolved by teaching the MIDX to resolve duplicates by always favoring the kept pack (if one exists), but this breaks an assumption in existing MIDXs, and so it would require a format change.

The benefit to changing the MIDX in this way is marginal, so we instead have a more thorough check here which is explained with a comment.

Callers will be added in subsequent patches.
Co-authored-by: Jeff King <peff@peff.net>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
---
 packfile.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 packfile.h |  5 +++++
 2 files changed, 64 insertions(+), 5 deletions(-)
diff --git a/packfile.c b/packfile.c
index 1fec12ac5f..7f84f221ce 100644
--- a/packfile.c
+++ b/packfile.c
@@ -2042,7 +2042,10 @@ static int fill_pack_entry(const struct object_id *oid,
 	return 1;
 }
 
-int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e)
+static int find_one_pack_entry(struct repository *r,
+			       const struct object_id *oid,
+			       struct pack_entry *e,
+			       int kept_only)
 {
 	struct list_head *pos;
 	struct multi_pack_index *m;
@@ -2052,26 +2055,77 @@ int find_pack_entry(struct repository *r, const struct object_id *oid, struct pa
 		return 0;
 
 	for (m = r->objects->multi_pack_index; m; m = m->next) {
-		if (fill_midx_entry(r, oid, e, m))
+		if (!fill_midx_entry(r, oid, e, m))
+			continue;
+
+		if (!kept_only)
+			return 1;
+
+		if (((kept_only & ON_DISK_KEEP_PACKS) && e->p->pack_keep) ||
+		    ((kept_only & IN_CORE_KEEP_PACKS) && e->p->pack_keep_in_core))
 			return 1;
 	}
 
 	list_for_each(pos, &r->objects->packed_git_mru) {
 		struct packed_git *p = list_entry(pos, struct packed_git, mru);
-		if (!p->multi_pack_index && fill_pack_entry(oid, e, p)) {
-			list_move(&p->mru, &r->objects->packed_git_mru);
-			return 1;
+		if (p->multi_pack_index && !kept_only) {
+			/*
+			 * If this pack is covered by the MIDX, we'd have found
+			 * the object already in the loop above if it was here,
+			 * so don't bother looking.
+			 *
+			 * The exception is if we are looking only at kept
+			 * packs. An object can be present in two packs covered
+			 * by the MIDX, one kept and one not-kept. And as the
+			 * MIDX points to only one copy of each object, it might
+			 * have returned only the non-kept version above. We
+			 * have to check again to be thorough.
+			 */
+			continue;
+		}
+		if (!kept_only ||
+		    (((kept_only & ON_DISK_KEEP_PACKS) && p->pack_keep) ||
+		     ((kept_only & IN_CORE_KEEP_PACKS) && p->pack_keep_in_core))) {
+			if (fill_pack_entry(oid, e, p)) {
+				list_move(&p->mru, &r->objects->packed_git_mru);
+				return 1;
+			}
 		}
 	}
 	return 0;
 }
 
+int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e)
+{
+	return find_one_pack_entry(r, oid, e, 0);
+}
+
+int find_kept_pack_entry(struct repository *r,
+			 const struct object_id *oid,
+			 unsigned flags,
+			 struct pack_entry *e)
+{
+	/*
+	 * Load all packs, including midx packs, since our "kept" strategy
+	 * relies on that. We're relying on the side effect of it setting up
+	 * r->objects->packed_git, which is a little ugly.
+	 */
+	get_all_packs(r);
+	return find_one_pack_entry(r, oid, e, flags);
+}
+
 int has_object_pack(const struct object_id *oid)
 {
 	struct pack_entry e;
 	return find_pack_entry(the_repository, oid, &e);
 }
 
+int has_object_kept_pack(const struct object_id *oid, unsigned flags)
+{
+	struct pack_entry e;
+	return find_kept_pack_entry(the_repository, oid, flags, &e);
+}
+
 int has_pack_index(const unsigned char *sha1)
 {
 	struct stat st;
diff --git a/packfile.h b/packfile.h
index 4cfec9e8d3..3ae117a8ae 100644
--- a/packfile.h
+++ b/packfile.h
@@ -162,13 +162,18 @@ int packed_object_info(struct repository *r,
 void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1);
 const struct packed_git *has_packed_and_bad(struct repository *r, const unsigned char *sha1);
 
+#define ON_DISK_KEEP_PACKS 1
+#define IN_CORE_KEEP_PACKS 2
+
 /*
  * Iff a pack file in the given repository contains the object named by sha1,
  * return true and store its location to e.
  */
 int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e);
+int find_kept_pack_entry(struct repository *r, const struct object_id *oid, unsigned flags, struct pack_entry *e);
 
 int has_object_pack(const struct object_id *oid);
+int has_object_kept_pack(const struct object_id *oid, unsigned flags);
 
 int has_pack_index(const unsigned char *sha1);
 
-- 
2.30.0.667.g81c0cbc6fd
Previous: Taylor BlauNext: Taylor Blau
Message 96 of 120 in “repack: support repacking into a geometric sequence”
  1. 00/10 repack: support repacking into a geometric sequenceTaylor Blau, Jan 19, 2021
  2. 02/10 revision: learn '--no-kept-objects'Taylor Blau, Jan 19, 2021
  3. Junio C HamanoJan 29, 2021
  4. Taylor BlauJan 29, 2021
  5. 01/10 packfile: introduce 'find_kept_pack_entry()'Taylor Blau, Jan 19, 2021
  6. Derrick StoleeJan 20, 2021
  7. Taylor BlauJan 20, 2021
  8. Junio C HamanoJan 29, 2021
  9. Taylor BlauJan 29, 2021
  10. Jeff KingJan 29, 2021
  11. Junio C HamanoJan 29, 2021
  12. 07/10 packfile: add kept-pack cache for find_kept_pack_entry()Taylor Blau, Jan 19, 2021
  13. 06/10 pack-objects: rewrite honor-pack-keep logicTaylor Blau, Jan 19, 2021
  14. 05/10 p5303: measure time to repack with keepTaylor Blau, Jan 19, 2021
  15. Junio C HamanoJan 29, 2021
  16. Jeff KingJan 29, 2021
  17. p5303: avoid sed GNU-ismJeff King, Jan 29, 2021
  18. Eric SunshineJan 29, 2021
  19. Jeff KingJan 29, 2021
  20. Eric SunshineJan 29, 2021
  21. Taylor BlauJan 29, 2021
  22. Junio C HamanoJan 29, 2021
  23. Jeff KingJan 29, 2021
  24. Junio C HamanoJan 29, 2021
  25. 08/10 builtin/pack-objects.c: teach '--keep-pack-stdin'Taylor Blau, Jan 19, 2021
  26. 10/10 builtin/repack.c: add '--geometric' optionTaylor Blau, Jan 19, 2021
  27. 03/10 builtin/pack-objects.c: learn '--assume-kept-packs-closed'Taylor Blau, Jan 19, 2021
  28. Junio C HamanoJan 29, 2021
  29. Jeff KingJan 29, 2021
  30. Taylor BlauJan 29, 2021
  31. Jeff KingJan 29, 2021
  32. Taylor BlauJan 29, 2021
  33. Jeff KingJan 29, 2021
  34. Junio C HamanoJan 29, 2021
  35. Taylor BlauJan 29, 2021
  36. Taylor BlauFeb 2, 2021
  37. Jeff KingJan 29, 2021
  38. Junio C HamanoJan 29, 2021
  39. Junio C HamanoJan 29, 2021
  40. Jeff KingJan 29, 2021
  41. Taylor BlauJan 29, 2021
  42. Jeff KingJan 29, 2021
  43. Junio C HamanoJan 29, 2021
  44. 09/10 builtin/repack.c: extract loose object handlingTaylor Blau, Jan 19, 2021
  45. Derrick StoleeJan 20, 2021
  46. Taylor BlauJan 20, 2021
  47. Derrick StoleeJan 20, 2021
  48. Junio C HamanoJan 21, 2021
  49. 04/10 p5303: add missing &&-chainsTaylor Blau, Jan 19, 2021
  50. Derrick StoleeJan 20, 2021
  51. 0/8 repack: support repacking into a geometric sequenceTaylor Blau, Feb 4, 2021
  52. 4/8 p5303: add missing &&-chainsTaylor Blau, Feb 4, 2021
  53. 3/8 builtin/pack-objects.c: add '--stdin-packs' optionTaylor Blau, Feb 4, 2021
  54. Jeff KingFeb 16, 2021
  55. Taylor BlauFeb 17, 2021
  56. Jeff KingFeb 17, 2021
  57. 2/8 revision: learn '--no-kept-objects'Taylor Blau, Feb 4, 2021
  58. Jeff KingFeb 16, 2021
  59. Taylor BlauFeb 17, 2021
  60. 1/8 packfile: introduce 'find_kept_pack_entry()'Taylor Blau, Feb 4, 2021
  61. Jeff KingFeb 16, 2021
  62. Taylor BlauFeb 16, 2021
  63. 5/8 p5303: measure time to repack with keepTaylor Blau, Feb 4, 2021
  64. Jeff KingFeb 16, 2021
  65. Jeff KingFeb 17, 2021
  66. Taylor BlauFeb 17, 2021
  67. Jeff KingFeb 17, 2021
  68. 7/8 packfile: add kept-pack cache for find_kept_pack_entry()Taylor Blau, Feb 4, 2021
  69. Jeff KingFeb 17, 2021
  70. Taylor BlauFeb 17, 2021
  71. Jeff KingFeb 17, 2021
  72. Taylor BlauFeb 17, 2021
  73. Jeff KingFeb 17, 2021
  74. 8/8 builtin/repack.c: add '--geometric' optionTaylor Blau, Feb 4, 2021
  75. Jeff KingFeb 17, 2021
  76. Taylor BlauFeb 17, 2021
  77. 6/8 builtin/pack-objects.c: rewrite honor-pack-keep logicTaylor Blau, Feb 4, 2021
  78. Jeff KingFeb 17, 2021
  79. Taylor BlauFeb 17, 2021
  80. Jeff KingFeb 17, 2021
  81. Jeff KingFeb 17, 2021
  82. Jeff KingFeb 17, 2021
  83. 0/8 repack: support repacking into a geometric sequenceTaylor Blau, Feb 18, 2021
  84. 1/8 packfile: introduce 'find_kept_pack_entry()'Taylor Blau, Feb 18, 2021
  85. 2/8 revision: learn '--no-kept-objects'Taylor Blau, Feb 18, 2021
  86. 4/8 p5303: add missing &&-chainsTaylor Blau, Feb 18, 2021
  87. 3/8 builtin/pack-objects.c: add '--stdin-packs' optionTaylor Blau, Feb 18, 2021
  88. 6/8 builtin/pack-objects.c: rewrite honor-pack-keep logicTaylor Blau, Feb 18, 2021
  89. 5/8 p5303: measure time to repack with keepTaylor Blau, Feb 18, 2021
  90. 7/8 packfile: add kept-pack cache for find_kept_pack_entry()Taylor Blau, Feb 18, 2021
  91. 8/8 builtin/repack.c: add '--geometric' optionTaylor Blau, Feb 18, 2021
  92. Jeff KingFeb 23, 2021
  93. Taylor BlauFeb 23, 2021
  94. Jeff KingFeb 23, 2021
  95. 0/8 repack: support repacking into a geometric sequenceTaylor Blau, Feb 23, 2021
  96. 1/8 packfile: introduce 'find_kept_pack_entry()'Taylor Blau, Feb 23, 2021
  97. 2/8 revision: learn '--no-kept-objects'Taylor Blau, Feb 23, 2021
  98. 3/8 builtin/pack-objects.c: add '--stdin-packs' optionTaylor Blau, Feb 23, 2021
  99. Junio C HamanoFeb 23, 2021
  100. Jeff KingFeb 23, 2021
  101. 4/8 p5303: add missing &&-chainsTaylor Blau, Feb 23, 2021
  102. 6/8 builtin/pack-objects.c: rewrite honor-pack-keep logicTaylor Blau, Feb 23, 2021
  103. 5/8 p5303: measure time to repack with keepTaylor Blau, Feb 23, 2021
  104. 8/8 builtin/repack.c: add '--geometric' optionTaylor Blau, Feb 23, 2021
  105. Junio C HamanoFeb 24, 2021
  106. Junio C HamanoFeb 24, 2021
  107. Taylor BlauMar 4, 2021
  108. Taylor BlauMar 4, 2021
  109. 7/8 packfile: add kept-pack cache for find_kept_pack_entry()Taylor Blau, Feb 23, 2021
  110. Jeff KingFeb 23, 2021
  111. Junio C HamanoFeb 23, 2021
  112. Jeff KingFeb 23, 2021
  113. Martin FickFeb 23, 2021
  114. Taylor BlauFeb 23, 2021
  115. Martin FickFeb 23, 2021
  116. Jeff KingFeb 23, 2021
  117. Martin FickFeb 23, 2021
  118. Jeff KingFeb 23, 2021
  119. Martin FickFeb 24, 2021
  120. Jeff KingFeb 26, 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.