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

[PATCH v2 10/24] pack-bitmap-write: reimplement bitmap writing

From
Taylor Blau <me@ttaylorr.com>
Date
Nov 17, 2020, 21:47 UTC
Message-ID
<c9512067293c082ad3082262e50dfd04f1bc1648.1605649533.git.me@ttaylorr.com>
In-Reply-To
<cover.1605649533.git.me@ttaylorr.com>
From: Jeff King <peff@peff.net>

The bitmap generation code works by iterating over the set of commits for which we plan to write bitmaps, and then for each one performing a traditional traversal over the reachable commits and trees, filling in the bitmap. Between two traversals, we can often reuse the previous bitmap result as long as the first commit is an ancestor of the second. However, our worst case is that we may end up doing "n" complete complete traversals to the root in order to create "n" bitmaps.

In a real-world case (the shared-storage repo consisting of all GitHub forks of chromium/chromium), we perform very poorly: generating bitmaps takes ~3 hours, whereas we can walk the whole object graph in ~3 minutes.

This commit completely rewrites the algorithm, with the goal of accessing each object only once. It works roughly like this:

  - generate a list of commits in topo-order using a single traversal
  - invert the edges of the graph (so have parents point at their
    children)
  - make one pass in reverse topo-order, generating a bitmap for each
    commit and passing the result along to child nodes

We generate correct results because each node we visit has already had all of its ancestors added to the bitmap. And we make only two linear passes over the commits.

We also visit each tree usually only once. When filling in a bitmap, we don't bother to recurse into trees whose bit is already set in the bitmap (since we know we've already done so when setting their bit). That means that if commit A references tree T, none of its descendants will need to open T again. I say "usually", though, because it is possible for a given tree to be mentioned in unrelated parts of history (e.g., cherry-picking to a parallel branch).

So we've accomplished our goal, and the resulting algorithm is pretty simple to understand. But there are some downsides, at least with this initial implementation:

  - we no longer reuse the results of any on-disk bitmaps when
    generating. So we'd expect to sometimes be slower than the original
    when bitmaps already exist. However, this is something we'll be able
    to add back in later.
  - we use much more memory. Instead of keeping one bitmap in memory at
    a time, we're passing them up through the graph. So our memory use
    should scale with the graph width (times the size of a bitmap).
So how does it perform?

For a clone of linux.git, generating bitmaps from scratch with the old algorithm took 63s. Using this algorithm it takes 205s. Which is much worse, but _might_ be acceptable if it behaved linearly as the size grew. It also increases peak heap usage by ~1G. That's not impossibly large, but not encouraging.

On the complete fork-network of torvalds/linux, it increases the peak RAM usage by 40GB. Yikes. (I forgot to record the time it took, but the memory usage was too much to consider this reasonable anyway).

On the complete fork-network of chromium/chromium, I ran out of memory before succeeding. Some back-of-the-envelope calculations indicate it would need 80+GB to complete.

So at this stage, we've managed to make things much worse. But because of the way this new algorithm is structured, there are a lot of opportunities for optimization on top. We'll start implementing those in the follow-on patches.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
---
 pack-bitmap-write.c | 303 ++++++++++++++++++++++++--------------------
 1 file changed, 169 insertions(+), 134 deletions(-)
diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c
index 5e998bdaa7..f2f0b6b2c2 100644
--- a/pack-bitmap-write.c
+++ b/pack-bitmap-write.c
@@ -110,8 +110,6 @@ void bitmap_writer_build_type_index(struct packing_data *to_pack,
 /**
  * Compute the actual bitmaps
  */
-static struct object **seen_objects;
-static unsigned int seen_objects_nr, seen_objects_alloc;
 
 static inline void push_bitmapped_commit(struct commit *commit, struct ewah_bitmap *reused)
 {
@@ -127,21 +125,6 @@ static inline void push_bitmapped_commit(struct commit *commit, struct ewah_bitm
 	writer.selected_nr++;
 }
 
-static inline void mark_as_seen(struct object *object)
-{
-	ALLOC_GROW(seen_objects, seen_objects_nr + 1, seen_objects_alloc);
-	seen_objects[seen_objects_nr++] = object;
-}
-
-static inline void reset_all_seen(void)
-{
-	unsigned int i;
-	for (i = 0; i < seen_objects_nr; ++i) {
-		seen_objects[i]->flags &= ~(SEEN | ADDED | SHOWN);
-	}
-	seen_objects_nr = 0;
-}
-
 static uint32_t find_object_pos(const struct object_id *oid)
 {
 	struct object_entry *entry = packlist_find(writer.to_pack, oid);
@@ -154,60 +137,6 @@ static uint32_t find_object_pos(const struct object_id *oid)
 	return oe_in_pack_pos(writer.to_pack, entry);
 }
 
-static void show_object(struct object *object, const char *name, void *data)
-{
-	struct bitmap *base = data;
-	bitmap_set(base, find_object_pos(&object->oid));
-	mark_as_seen(object);
-}
-
-static void show_commit(struct commit *commit, void *data)
-{
-	mark_as_seen((struct object *)commit);
-}
-
-static int
-add_to_include_set(struct bitmap *base, struct commit *commit)
-{
-	khiter_t hash_pos;
-	uint32_t bitmap_pos = find_object_pos(&commit->object.oid);
-
-	if (bitmap_get(base, bitmap_pos))
-		return 0;
-
-	hash_pos = kh_get_oid_map(writer.bitmaps, commit->object.oid);
-	if (hash_pos < kh_end(writer.bitmaps)) {
-		struct bitmapped_commit *bc = kh_value(writer.bitmaps, hash_pos);
-		bitmap_or_ewah(base, bc->bitmap);
-		return 0;
-	}
-
-	bitmap_set(base, bitmap_pos);
-	return 1;
-}
-
-static int
-should_include(struct commit *commit, void *_data)
-{
-	struct bitmap *base = _data;
-
-	if (!add_to_include_set(base, commit)) {
-		struct commit_list *parent = commit->parents;
-
-		mark_as_seen((struct object *)commit);
-
-		while (parent) {
-			parent->item->object.flags |= SEEN;
-			mark_as_seen((struct object *)parent->item);
-			parent = parent->next;
-		}
-
-		return 0;
-	}
-
-	return 1;
-}
-
 static void compute_xor_offsets(void)
 {
 	static const int MAX_XOR_OFFSET_SEARCH = 10;
@@ -248,79 +177,185 @@ static void compute_xor_offsets(void)
 	}
 }
 
-void bitmap_writer_build(struct packing_data *to_pack)
+struct bb_commit {
+	struct commit_list *children;
+	struct bitmap *bitmap;
+	unsigned selected:1;
+	unsigned idx; /* within selected array */
+};
+
+define_commit_slab(bb_data, struct bb_commit);
+
+struct bitmap_builder {
+	struct bb_data data;
+	struct commit **commits;
+	size_t commits_nr, commits_alloc;
+};
+
+static void bitmap_builder_init(struct bitmap_builder *bb,
+				struct bitmap_writer *writer)
 {
-	static const double REUSE_BITMAP_THRESHOLD = 0.2;
-
-	int i, reuse_after, need_reset;
-	struct bitmap *base = bitmap_new();
 	struct rev_info revs;
+	struct commit *commit;
+	unsigned int i;
+
+	memset(bb, 0, sizeof(*bb));
+	init_bb_data(&bb->data);
+
+	reset_revision_walk();
+	repo_init_revisions(writer->to_pack->repo, &revs, NULL);
+	revs.topo_order = 1;
+
+	for (i = 0; i < writer->selected_nr; i++) {
+		struct commit *c = writer->selected[i].commit;
+		struct bb_commit *ent = bb_data_at(&bb->data, c);
+		ent->selected = 1;
+		ent->idx = i;
+		add_pending_object(&revs, &c->object, "");
+	}
+
+	if (prepare_revision_walk(&revs))
+		die("revision walk setup failed");
+
+	while ((commit = get_revision(&revs))) {
+		struct commit_list *p;
+
+		parse_commit_or_die(commit);
+
+		ALLOC_GROW(bb->commits, bb->commits_nr + 1, bb->commits_alloc);
+		bb->commits[bb->commits_nr++] = commit;
+
+		for (p = commit->parents; p; p = p->next) {
+			struct bb_commit *ent = bb_data_at(&bb->data, p->item);
+			commit_list_insert(commit, &ent->children);
+		}
+	}
+}
+
+static void bitmap_builder_clear(struct bitmap_builder *bb)
+{
+	clear_bb_data(&bb->data);
+	free(bb->commits);
+	bb->commits_nr = bb->commits_alloc = 0;
+}
+
+static void fill_bitmap_tree(struct bitmap *bitmap,
+			     struct tree *tree)
+{
+	uint32_t pos;
+	struct tree_desc desc;
+	struct name_entry entry;
+
+	/*
+	 * If our bit is already set, then there is nothing to do. Both this
+	 * tree and all of its children will be set.
+	 */
+	pos = find_object_pos(&tree->object.oid);
+	if (bitmap_get(bitmap, pos))
+		return;
+	bitmap_set(bitmap, pos);
+
+	if (parse_tree(tree) < 0)
+		die("unable to load tree object %s",
+		    oid_to_hex(&tree->object.oid));
+	init_tree_desc(&desc, tree->buffer, tree->size);
+
+	while (tree_entry(&desc, &entry)) {
+		switch (object_type(entry.mode)) {
+		case OBJ_TREE:
+			fill_bitmap_tree(bitmap,
+					 lookup_tree(the_repository, &entry.oid));
+			break;
+		case OBJ_BLOB:
+			bitmap_set(bitmap, find_object_pos(&entry.oid));
+			break;
+		default:
+			/* Gitlink, etc; not reachable */
+			break;
+		}
+	}
+
+	free_tree_buffer(tree);
+}
+
+static void fill_bitmap_commit(struct bb_commit *ent,
+			       struct commit *commit)
+{
+	if (!ent->bitmap)
+		ent->bitmap = bitmap_new();
+
+	/*
+	 * mark ourselves, but do not bother with parents; their values
+	 * will already have been propagated to us
+	 */
+	bitmap_set(ent->bitmap, find_object_pos(&commit->object.oid));
+	fill_bitmap_tree(ent->bitmap, get_commit_tree(commit));
+}
+
+static void store_selected(struct bb_commit *ent, struct commit *commit)
+{
+	struct bitmapped_commit *stored = &writer.selected[ent->idx];
+	khiter_t hash_pos;
+	int hash_ret;
+
+	/*
+	 * the "reuse bitmaps" phase may have stored something here, but
+	 * our new algorithm doesn't use it. Drop it.
+	 */
+	if (stored->bitmap)
+		ewah_free(stored->bitmap);
+
+	stored->bitmap = bitmap_to_ewah(ent->bitmap);
+
+	hash_pos = kh_put_oid_map(writer.bitmaps, commit->object.oid, &hash_ret);
+	if (hash_ret == 0)
+		die("Duplicate entry when writing index: %s",
+		    oid_to_hex(&commit->object.oid));
+	kh_value(writer.bitmaps, hash_pos) = stored;
+}
+
+void bitmap_writer_build(struct packing_data *to_pack)
+{
+	struct bitmap_builder bb;
+	size_t i;
+	int nr_stored = 0; /* for progress */
 
 	writer.bitmaps = kh_init_oid_map();
 	writer.to_pack = to_pack;
 
 	if (writer.show_progress)
 		writer.progress = start_progress("Building bitmaps", writer.selected_nr);
-
-	repo_init_revisions(to_pack->repo, &revs, NULL);
-	revs.tag_objects = 1;
-	revs.tree_objects = 1;
-	revs.blob_objects = 1;
-	revs.no_walk = 0;
-
-	revs.include_check = should_include;
-	reset_revision_walk();
-
-	reuse_after = writer.selected_nr * REUSE_BITMAP_THRESHOLD;
-	need_reset = 0;
-
-	for (i = writer.selected_nr - 1; i >= 0; --i) {
-		struct bitmapped_commit *stored;
-		struct object *object;
-
-		khiter_t hash_pos;
-		int hash_ret;
-
-		stored = &writer.selected[i];
-		object = (struct object *)stored->commit;
-
-		if (stored->bitmap == NULL) {
-			if (i < writer.selected_nr - 1 &&
-			    (need_reset ||
-			     !in_merge_bases(writer.selected[i + 1].commit,
-					     stored->commit))) {
-			    bitmap_reset(base);
-			    reset_all_seen();
-			}
-
-			add_pending_object(&revs, object, "");
-			revs.include_check_data = base;
-
-			if (prepare_revision_walk(&revs))
-				die("revision walk setup failed");
-
-			traverse_commit_list(&revs, show_commit, show_object, base);
-
-			object_array_clear(&revs.pending);
-
-			stored->bitmap = bitmap_to_ewah(base);
-			need_reset = 0;
-		} else
-			need_reset = 1;
-
-		if (i >= reuse_after)
-			stored->flags |= BITMAP_FLAG_REUSE;
-
-		hash_pos = kh_put_oid_map(writer.bitmaps, object->oid, &hash_ret);
-		if (hash_ret == 0)
-			die("Duplicate entry when writing index: %s",
-			    oid_to_hex(&object->oid));
-
-		kh_value(writer.bitmaps, hash_pos) = stored;
-		display_progress(writer.progress, writer.selected_nr - i);
+	trace2_region_enter("pack-bitmap-write", "building_bitmaps_total",
+		the_repository);
+
+	bitmap_builder_init(&bb, &writer);
+	for (i = bb.commits_nr; i > 0; i--) {
+		struct commit *commit = bb.commits[i-1];
+		struct bb_commit *ent = bb_data_at(&bb.data, commit);
+		struct commit *child;
+
+		fill_bitmap_commit(ent, commit);
+
+		if (ent->selected) {
+			store_selected(ent, commit);
+			nr_stored++;
+			display_progress(writer.progress, nr_stored);
+		}
+
+		while ((child = pop_commit(&ent->children))) {
+			struct bb_commit *child_ent =
+				bb_data_at(&bb.data, child);
+
+			if (child_ent->bitmap)
+				bitmap_or(child_ent->bitmap, ent->bitmap);
+			else
+				child_ent->bitmap = bitmap_dup(ent->bitmap);
+		}
+		bitmap_free(ent->bitmap);
+		ent->bitmap = NULL;
 	}
+	bitmap_builder_clear(&bb);
 
-	bitmap_free(base);
 	stop_progress(&writer.progress);
 
 	compute_xor_offsets();
-- 
2.29.2.312.gabc4d358d8
Previous: Taylor BlauNext: Jonathan Tan
Message 60 of 173 in “pack-bitmap: bitmap generation improvements”
  1. 00/23 pack-bitmap: bitmap generation improvementsTaylor Blau, Nov 11, 2020
  2. 01/23 ewah/ewah_bitmap.c: grow buffer past 1Taylor Blau, Nov 11, 2020
  3. Junio C HamanoNov 22, 2020
  4. Taylor BlauNov 23, 2020
  5. Jeff KingNov 24, 2020
  6. Jeff KingNov 24, 2020
  7. Taylor BlauDec 1, 2020
  8. 02/23 pack-bitmap: fix header size checkTaylor Blau, Nov 11, 2020
  9. Martin ÅgrenNov 12, 2020
  10. 03/23 pack-bitmap: bounds-check size of cache extensionTaylor Blau, Nov 11, 2020
  11. Martin ÅgrenNov 12, 2020
  12. Jeff KingNov 13, 2020
  13. Martin ÅgrenNov 13, 2020
  14. Taylor BlauNov 13, 2020
  15. Jeff KingNov 13, 2020
  16. Taylor BlauNov 13, 2020
  17. Jeff KingNov 13, 2020
  18. 04/23 t5310: drop size of truncated ewah bitmapTaylor Blau, Nov 11, 2020
  19. 05/23 rev-list: die when --test-bitmap detects a mismatchTaylor Blau, Nov 11, 2020
  20. 06/23 ewah: factor out bitmap growthTaylor Blau, Nov 11, 2020
  21. 07/23 ewah: make bitmap growth less aggressiveTaylor Blau, Nov 11, 2020
  22. Junio C HamanoNov 22, 2020
  23. Taylor BlauNov 23, 2020
  24. Jeff KingNov 24, 2020
  25. Junio C HamanoNov 24, 2020
  26. 08/23 ewah: implement bitmap_or()Taylor Blau, Nov 11, 2020
  27. Junio C HamanoNov 22, 2020
  28. Taylor BlauNov 23, 2020
  29. 09/23 ewah: add bitmap_dup() functionTaylor Blau, Nov 11, 2020
  30. 10/23 pack-bitmap-write: reimplement bitmap writingTaylor Blau, Nov 11, 2020
  31. 11/23 pack-bitmap-write: pass ownership of intermediate bitmapsTaylor Blau, Nov 11, 2020
  32. 12/23 pack-bitmap-write: fill bitmap with commit historyTaylor Blau, Nov 11, 2020
  33. 13/23 bitmap: add bitmap_diff_nonzero()Taylor Blau, Nov 11, 2020
  34. 14/23 commit: implement commit_list_contains()Taylor Blau, Nov 11, 2020
  35. 15/23 t5310: add branch-based checksTaylor Blau, Nov 11, 2020
  36. Derrick StoleeNov 11, 2020
  37. Junio C HamanoNov 11, 2020
  38. Johannes SchindelinNov 15, 2020
  39. 16/23 pack-bitmap-write: rename children to reverse_edgesTaylor Blau, Nov 11, 2020
  40. 17/23 pack-bitmap-write: build fewer intermediate bitmapsTaylor Blau, Nov 11, 2020
  41. SZEDER GáborNov 13, 2020
  42. Jeff KingNov 13, 2020
  43. Jeff KingNov 14, 2020
  44. 18/23 pack-bitmap-write: ignore BITMAP_FLAG_REUSETaylor Blau, Nov 11, 2020
  45. 19/23 pack-bitmap: factor out 'bitmap_for_commit()'Taylor Blau, Nov 11, 2020
  46. 20/23 pack-bitmap: factor out 'add_commit_to_bitmap()'Taylor Blau, Nov 11, 2020
  47. 21/23 pack-bitmap-write: use existing bitmapsTaylor Blau, Nov 11, 2020
  48. 22/23 pack-bitmap-write: relax unique rewalk conditionTaylor Blau, Nov 11, 2020
  49. 23/23 pack-bitmap-write: better reuse bitmapsTaylor Blau, Nov 11, 2020
  50. 00/24 pack-bitmap: bitmap generation improvementsTaylor Blau, Nov 17, 2020
  51. 01/24 ewah/ewah_bitmap.c: grow buffer past 1Taylor Blau, Nov 17, 2020
  52. 02/24 pack-bitmap: fix header size checkTaylor Blau, Nov 17, 2020
  53. 03/24 pack-bitmap: bounds-check size of cache extensionTaylor Blau, Nov 17, 2020
  54. 04/24 t5310: drop size of truncated ewah bitmapTaylor Blau, Nov 17, 2020
  55. 05/24 rev-list: die when --test-bitmap detects a mismatchTaylor Blau, Nov 17, 2020
  56. 06/24 ewah: factor out bitmap growthTaylor Blau, Nov 17, 2020
  57. 07/24 ewah: make bitmap growth less aggressiveTaylor Blau, Nov 17, 2020
  58. 08/24 ewah: implement bitmap_or()Taylor Blau, Nov 17, 2020
  59. 09/24 ewah: add bitmap_dup() functionTaylor Blau, Nov 17, 2020
  60. 10/24 pack-bitmap-write: reimplement bitmap writingTaylor Blau, Nov 17, 2020
  61. Jonathan TanNov 25, 2020
  62. Taylor BlauNov 28, 2020
  63. 11/24 pack-bitmap-write: pass ownership of intermediate bitmapsTaylor Blau, Nov 17, 2020
  64. Jonathan TanNov 25, 2020
  65. 12/24 pack-bitmap-write: fill bitmap with commit historyTaylor Blau, Nov 17, 2020
  66. Junio C HamanoNov 22, 2020
  67. Derrick StoleeNov 23, 2020
  68. Jonathan TanNov 25, 2020
  69. Taylor BlauNov 28, 2020
  70. Jonathan TanNov 30, 2020
  71. 13/24 bitmap: add bitmap_diff_nonzero()Taylor Blau, Nov 17, 2020
  72. Junio C HamanoNov 22, 2020
  73. Taylor BlauNov 23, 2020
  74. 14/24 commit: implement commit_list_contains()Taylor Blau, Nov 17, 2020
  75. 15/24 t5310: add branch-based checksTaylor Blau, Nov 17, 2020
  76. Jonathan TanNov 25, 2020
  77. Taylor BlauNov 28, 2020
  78. 16/24 pack-bitmap-write: rename children to reverse_edgesTaylor Blau, Nov 17, 2020
  79. 17/24 pack-bitmap.c: check reads more aggressively when loadingTaylor Blau, Nov 17, 2020
  80. 18/24 pack-bitmap-write: build fewer intermediate bitmapsTaylor Blau, Nov 17, 2020
  81. Jonathan TanNov 24, 2020
  82. Jonathan TanNov 25, 2020
  83. Derrick StoleeNov 30, 2020
  84. 19/24 pack-bitmap-write: ignore BITMAP_FLAG_REUSETaylor Blau, Nov 17, 2020
  85. Jonathan TanDec 2, 2020
  86. 20/24 pack-bitmap: factor out 'bitmap_for_commit()'Taylor Blau, Nov 17, 2020
  87. Jonathan TanDec 2, 2020
  88. 21/24 pack-bitmap: factor out 'add_commit_to_bitmap()'Taylor Blau, Nov 17, 2020
  89. Jonathan TanDec 2, 2020
  90. 22/24 pack-bitmap-write: use existing bitmapsTaylor Blau, Nov 17, 2020
  91. Jonathan TanDec 2, 2020
  92. Taylor BlauDec 2, 2020
  93. 23/24 pack-bitmap-write: relax unique rewalk conditionTaylor Blau, Nov 17, 2020
  94. Jonathan TanDec 2, 2020
  95. Taylor BlauDec 2, 2020
  96. Jonathan TanDec 7, 2020
  97. Derrick StoleeDec 7, 2020
  98. Derrick StoleeDec 7, 2020
  99. Jeff KingDec 7, 2020
  100. 24/24 pack-bitmap-write: better reuse bitmapsTaylor Blau, Nov 17, 2020
  101. Jonathan TanDec 2, 2020
  102. Taylor BlauDec 2, 2020
  103. Derrick StoleeDec 2, 2020
  104. Taylor BlauDec 2, 2020
  105. Jonathan TanDec 7, 2020
  106. Jonathan TanDec 7, 2020
  107. Derrick StoleeDec 7, 2020
  108. SZEDER GáborNov 18, 2020
  109. Taylor BlauNov 18, 2020
  110. Taylor BlauNov 22, 2020
  111. Taylor BlauNov 22, 2020
  112. Martin ÅgrenNov 20, 2020
  113. Junio C HamanoNov 21, 2020
  114. Martin ÅgrenNov 21, 2020
  115. Taylor BlauNov 22, 2020
  116. Jeff KingNov 24, 2020
  117. Taylor BlauDec 1, 2020
  118. Jonathan TanDec 1, 2020
  119. Taylor BlauDec 1, 2020
  120. Jonathan TanDec 2, 2020
  121. 00/24 pack-bitmap: bitmap generation improvementsTaylor Blau, Dec 8, 2020
  122. 01/24 ewah/ewah_bitmap.c: avoid open-coding ALLOC_GROW()Taylor Blau, Dec 8, 2020
  123. 02/24 pack-bitmap: fix header size checkTaylor Blau, Dec 8, 2020
  124. 03/24 pack-bitmap: bounds-check size of cache extensionTaylor Blau, Dec 8, 2020
  125. 05/24 rev-list: die when --test-bitmap detects a mismatchTaylor Blau, Dec 8, 2020
  126. 04/24 t5310: drop size of truncated ewah bitmapTaylor Blau, Dec 8, 2020
  127. 08/24 ewah: implement bitmap_or()Taylor Blau, Dec 8, 2020
  128. 07/24 ewah: make bitmap growth less aggressiveTaylor Blau, Dec 8, 2020
  129. 09/24 ewah: add bitmap_dup() functionTaylor Blau, Dec 8, 2020
  130. 11/24 pack-bitmap-write: pass ownership of intermediate bitmapsTaylor Blau, Dec 8, 2020
  131. 06/24 ewah: factor out bitmap growthTaylor Blau, Dec 8, 2020
  132. 12/24 pack-bitmap-write: fill bitmap with commit historyTaylor Blau, Dec 8, 2020
  133. 10/24 pack-bitmap-write: reimplement bitmap writingTaylor Blau, Dec 8, 2020
  134. 13/24 bitmap: implement bitmap_is_subset()Taylor Blau, Dec 8, 2020
  135. 14/24 commit: implement commit_list_contains()Taylor Blau, Dec 8, 2020
  136. 15/24 t5310: add branch-based checksTaylor Blau, Dec 8, 2020
  137. 17/24 pack-bitmap.c: check reads more aggressively when loadingTaylor Blau, Dec 8, 2020
  138. 16/24 pack-bitmap-write: rename children to reverse_edgesTaylor Blau, Dec 8, 2020
  139. 22/24 pack-bitmap-write: use existing bitmapsTaylor Blau, Dec 8, 2020
  140. 18/24 pack-bitmap-write: build fewer intermediate bitmapsTaylor Blau, Dec 8, 2020
  141. 20/24 pack-bitmap: factor out 'bitmap_for_commit()'Taylor Blau, Dec 8, 2020
  142. 19/24 pack-bitmap-write: ignore BITMAP_FLAG_REUSETaylor Blau, Dec 8, 2020
  143. 21/24 pack-bitmap: factor out 'add_commit_to_bitmap()'Taylor Blau, Dec 8, 2020
  144. 23/24 pack-bitmap-write: relax unique rewalk conditionTaylor Blau, Dec 8, 2020
  145. 24/24 pack-bitmap-write: better reuse bitmapsTaylor Blau, Dec 8, 2020
  146. Junio C HamanoDec 8, 2020
  147. Taylor BlauDec 8, 2020
  148. Junio C HamanoDec 8, 2020
  149. 00/24 pack-bitmap: bitmap generation improvementsTaylor Blau, Dec 8, 2020
  150. 02/24 pack-bitmap: fix header size checkTaylor Blau, Dec 8, 2020
  151. 01/24 ewah/ewah_bitmap.c: avoid open-coding ALLOC_GROW()Taylor Blau, Dec 8, 2020
  152. 04/24 t5310: drop size of truncated ewah bitmapTaylor Blau, Dec 8, 2020
  153. 03/24 pack-bitmap: bounds-check size of cache extensionTaylor Blau, Dec 8, 2020
  154. 05/24 rev-list: die when --test-bitmap detects a mismatchTaylor Blau, Dec 8, 2020
  155. 06/24 ewah: factor out bitmap growthTaylor Blau, Dec 8, 2020
  156. 07/24 ewah: make bitmap growth less aggressiveTaylor Blau, Dec 8, 2020
  157. 12/24 pack-bitmap-write: fill bitmap with commit historyTaylor Blau, Dec 8, 2020
  158. 10/24 pack-bitmap-write: reimplement bitmap writingTaylor Blau, Dec 8, 2020
  159. 09/24 ewah: add bitmap_dup() functionTaylor Blau, Dec 8, 2020
  160. 08/24 ewah: implement bitmap_or()Taylor Blau, Dec 8, 2020
  161. 11/24 pack-bitmap-write: pass ownership of intermediate bitmapsTaylor Blau, Dec 8, 2020
  162. 13/24 bitmap: implement bitmap_is_subset()Taylor Blau, Dec 8, 2020
  163. 15/24 t5310: add branch-based checksTaylor Blau, Dec 8, 2020
  164. 16/24 pack-bitmap-write: rename children to reverse_edgesTaylor Blau, Dec 8, 2020
  165. 17/24 pack-bitmap.c: check reads more aggressively when loadingTaylor Blau, Dec 8, 2020
  166. 19/24 pack-bitmap-write: ignore BITMAP_FLAG_REUSETaylor Blau, Dec 8, 2020
  167. 20/24 pack-bitmap: factor out 'bitmap_for_commit()'Taylor Blau, Dec 8, 2020
  168. 22/24 pack-bitmap-write: use existing bitmapsTaylor Blau, Dec 8, 2020
  169. 14/24 commit: implement commit_list_contains()Taylor Blau, Dec 8, 2020
  170. 18/24 pack-bitmap-write: build fewer intermediate bitmapsTaylor Blau, Dec 8, 2020
  171. 23/24 pack-bitmap-write: relax unique revwalk conditionTaylor Blau, Dec 8, 2020
  172. 24/24 pack-bitmap-write: better reuse bitmapsTaylor Blau, Dec 8, 2020
  173. 21/24 pack-bitmap: factor out 'add_commit_to_bitmap()'Taylor Blau, Dec 8, 2020

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.