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

[PATCH v4 2/5] reftable/stack: add function to check if optimization is required

From
Karthik Nayak <karthik.188@gmail.com>
Date
Nov 8, 2025, 21:51 UTC
Message-ID
<20251108-562-add-sub-command-to-check-if-maintenance-is-needed-v4-2-a90f229b6023@gmail.com>
In-Reply-To
<20251108-562-add-sub-command-to-check-if-maintenance-is-needed-v4-0-a90f229b6023@gmail.com>

The reftable backend performs auto-compaction as part of its regular flow, which is required to keep the number of tables part of a stack at bay. This allows it to stay optimized.

Compaction can also be triggered voluntarily by the user via the 'git pack-refs' or the 'git refs optimize' command. However, currently there is no way for the user to check if optimization is required without actually performing it.

Extract out the heuristics logic from 'reftable_stack_auto_compact()' into an internal function 'update_segment_if_compaction_required()'. Then use this to add and expose `reftable_stack_compaction_required()` which will allow users to check if the reftable backend can be optimized.

Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 reftable/reftable-stack.h       | 11 +++++++++++
 reftable/stack.c                | 42 ++++++++++++++++++++++++++++++++++++-----
 t/unit-tests/u-reftable-stack.c | 12 ++++++++++--
 3 files changed, 58 insertions(+), 7 deletions(-)
diff --git a/reftable/reftable-stack.h b/reftable/reftable-stack.h
index d70fcb705d..c2415cbc6e 100644
--- a/reftable/reftable-stack.h
+++ b/reftable/reftable-stack.h
@@ -123,6 +123,17 @@ struct reftable_log_expiry_config {
 int reftable_stack_compact_all(struct reftable_stack *st,
 			       struct reftable_log_expiry_config *config);
 
+/*
+ * Check if compaction is required.
+ *
+ * When `use_heuristics` is false, check if all tables can be compacted to a
+ * single table. If true, use heuristics to determine if the tables need to be
+ * compacted to maintain geometric progression.
+ */
+int reftable_stack_compaction_required(struct reftable_stack *st,
+				       bool use_heuristics,
+				       bool *required);
+
 /* heuristically compact unbalanced table stack. */
 int reftable_stack_auto_compact(struct reftable_stack *st);
 
diff --git a/reftable/stack.c b/reftable/stack.c
index 49387f9344..1c9f21dfe1 100644
--- a/reftable/stack.c
+++ b/reftable/stack.c
@@ -1647,19 +1647,51 @@ static int stack_segments_for_compaction(struct reftable_stack *st,
 	return 0;
 }
 
-int reftable_stack_auto_compact(struct reftable_stack *st)
+static int update_segment_if_compaction_required(struct reftable_stack *st,
+						 struct segment *seg,
+						 bool use_geometric,
+						 bool *required)
 {
-	struct segment seg;
 	int err;
 
-	if (st->merged->tables_len < 2)
+	if (st->merged->tables_len < 2) {
+		*required = false;
+		return 0;
+	}
+
+	if (!use_geometric) {
+		*required = true;
 		return 0;
+	}
+
+	err = stack_segments_for_compaction(st, seg);
+	if (err)
+		return err;
+
+	*required = segment_size(seg) > 0;
+	return 0;
+}
+
+int reftable_stack_compaction_required(struct reftable_stack *st,
+				       bool use_heuristics,
+				       bool *required)
+{
+	struct segment seg;
+	return update_segment_if_compaction_required(st, &seg, use_heuristics,
+						     required);
+}
+
+int reftable_stack_auto_compact(struct reftable_stack *st)
+{
+	struct segment seg;
+	bool required;
+	int err;
 
-	err = stack_segments_for_compaction(st, &seg);
+	err = update_segment_if_compaction_required(st, &seg, true, &required);
 	if (err)
 		return err;
 
-	if (segment_size(&seg) > 0)
+	if (required)
 		return stack_compact_range(st, seg.start, seg.end - 1,
 					   NULL, STACK_COMPACT_RANGE_BEST_EFFORT);
 
diff --git a/t/unit-tests/u-reftable-stack.c b/t/unit-tests/u-reftable-stack.c
index a8b91812e8..b8110cdeee 100644
--- a/t/unit-tests/u-reftable-stack.c
+++ b/t/unit-tests/u-reftable-stack.c
@@ -1067,6 +1067,7 @@ void test_reftable_stack__add_performs_auto_compaction(void)
 			.value_type = REFTABLE_REF_SYMREF,
 			.value.symref = (char *) "master",
 		};
+		bool required = false;
 		char buf[128];
 
 		/*
@@ -1087,10 +1088,17 @@ void test_reftable_stack__add_performs_auto_compaction(void)
 		 * auto compaction is disabled. When enabled, we should merge
 		 * all tables in the stack.
 		 */
-		if (i != n)
+		cl_assert_equal_i(reftable_stack_compaction_required(st, true, &required), 0);
+		if (i != n) {
 			cl_assert_equal_i(st->merged->tables_len, i + 1);
-		else
+			if (i < 1)
+				cl_assert_equal_b(required, false);
+			else
+				cl_assert_equal_b(required, true);
+		} else {
 			cl_assert_equal_i(st->merged->tables_len, 1);
+			cl_assert_equal_b(required, false);
+		}
 	}
 
 	reftable_stack_destroy(st);
-- 
2.51.0
Previous: Karthik NayakNext: Karthik Nayak
Message 53 of 57 in “maintenance: add an 'is-needed' subcommand”
  1. 0/5 maintenance: add an 'is-needed' subcommandKarthik Nayak, Oct 31, 2025
  2. 1/5 reftable/stack: return stack segments directlyKarthik Nayak, Oct 31, 2025
  3. Justin ToblerOct 31, 2025
  4. Karthik NayakNov 3, 2025
  5. Justin ToblerNov 3, 2025
  6. 2/5 reftable/stack: add function to check if optimization is requiredKarthik Nayak, Oct 31, 2025
  7. Justin ToblerOct 31, 2025
  8. Junio C HamanoOct 31, 2025
  9. Karthik NayakNov 3, 2025
  10. Karthik NayakNov 3, 2025
  11. Justin ToblerNov 3, 2025
  12. Patrick SteinhardtNov 3, 2025
  13. Karthik NayakNov 3, 2025
  14. 3/5 refs: add a `optimize_required` field to `struct ref_storage_be`Karthik Nayak, Oct 31, 2025
  15. 4/5 maintenance: add checking logic in `pack_refs_condition()`Karthik Nayak, Oct 31, 2025
  16. Patrick SteinhardtNov 3, 2025
  17. Karthik NayakNov 3, 2025
  18. 5/5 maintenance: add 'is-needed' subcommandKarthik Nayak, Oct 31, 2025
  19. Patrick SteinhardtNov 3, 2025
  20. Karthik NayakNov 3, 2025
  21. Patrick SteinhardtNov 4, 2025
  22. Karthik NayakNov 4, 2025
  23. 0/5 maintenance: add an 'is-needed' subcommandKarthik Nayak, Nov 4, 2025
  24. 1/5 reftable/stack: return stack segments directlyKarthik Nayak, Nov 4, 2025
  25. 3/5 refs: add a `optimize_required` field to `struct ref_storage_be`Karthik Nayak, Nov 4, 2025
  26. 2/5 reftable/stack: add function to check if optimization is requiredKarthik Nayak, Nov 4, 2025
  27. Junio C HamanoNov 4, 2025
  28. Karthik NayakNov 5, 2025
  29. Junio C HamanoNov 5, 2025
  30. Karthik NayakNov 6, 2025
  31. 4/5 maintenance: add checking logic in `pack_refs_condition()`Karthik Nayak, Nov 4, 2025
  32. 5/5 maintenance: add 'is-needed' subcommandKarthik Nayak, Nov 4, 2025
  33. Junio C HamanoNov 4, 2025
  34. Karthik NayakNov 5, 2025
  35. 0/5 maintenance: add an 'is-needed' subcommandKarthik Nayak, Nov 6, 2025
  36. 1/5 reftable/stack: return stack segments directlyKarthik Nayak, Nov 6, 2025
  37. 2/5 reftable/stack: add function to check if optimization is requiredKarthik Nayak, Nov 6, 2025
  38. Junio C HamanoNov 6, 2025
  39. Patrick SteinhardtNov 7, 2025
  40. 3/5 refs: add a `optimize_required` field to `struct ref_storage_be`Karthik Nayak, Nov 6, 2025
  41. 4/5 maintenance: add checking logic in `pack_refs_condition()`Karthik Nayak, Nov 6, 2025
  42. Patrick SteinhardtNov 6, 2025
  43. Karthik NayakNov 6, 2025
  44. Junio C HamanoNov 6, 2025
  45. Karthik NayakNov 7, 2025
  46. Junio C HamanoNov 7, 2025
  47. Karthik NayakNov 7, 2025
  48. 5/5 maintenance: add 'is-needed' subcommandKarthik Nayak, Nov 6, 2025
  49. Patrick SteinhardtNov 6, 2025
  50. Karthik NayakNov 6, 2025
  51. 0/5 maintenance: add an 'is-needed' subcommandKarthik Nayak, Nov 8, 2025
  52. 1/5 reftable/stack: return stack segments directlyKarthik Nayak, Nov 8, 2025
  53. 2/5 reftable/stack: add function to check if optimization is requiredKarthik Nayak, Nov 8, 2025
  54. 3/5 refs: add a `optimize_required` field to `struct ref_storage_be`Karthik Nayak, Nov 8, 2025
  55. 4/5 maintenance: add checking logic in `pack_refs_condition()`Karthik Nayak, Nov 8, 2025
  56. 5/5 maintenance: add 'is-needed' subcommandKarthik Nayak, Nov 8, 2025
  57. Patrick SteinhardtNov 10, 2025

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.