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

[PATCH v7 11/13] pack-objects: shrink size field in struct object_entry

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Mar 24, 2018, 06:33 UTC
Message-ID
<20180324063353.24722-12-pclouds@gmail.com>
In-Reply-To
<20180324063353.24722-1-pclouds@gmail.com>

It's very very rare that an uncompressed object is larger than 4GB (partly because Git does not handle those large files very well to begin with). Let's optimize it for the common case where object size is smaller than this limit.

Shrink size field down to 32 bits [1] and one overflow bit. If the size is too large, we read it back from disk. As noted in the previous patch, we need to return the delta size instead of canonical size when the to-be-reused object entry type is a delta instead of a canonical one.

Add two compare helpers that can take advantage of the overflow bit (e.g. if the file is 4GB+, chances are it's already larger than core.bigFileThreshold and there's no point in comparing the actual value).

Another note about oe_get_size_slow(). This function MUST be thread safe because SIZE() macro is used inside try_delta() which may run in parallel. Outside parallel code, no-contention locking should be dirt cheap (or insignificant compared to i/o access anyway). To exercise this code, it's best to run the test suite with something like

    make test GIT_TEST_OE_SIZE_BITS=2
which forces this code on all objects larger than 3 bytes.
[1] it's actually already 32 bits on Windows
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/pack-objects.c | 100 +++++++++++++++++++++++++++++++----------
 pack-objects.c         |   9 +++-
 pack-objects.h         |  53 +++++++++++++++++++++-
 t/README               |   6 +++
 4 files changed, 142 insertions(+), 26 deletions(-)
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index f054ba9dfa..caeef086d3 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -30,6 +30,8 @@
 #include "packfile.h"
 
 #define IN_PACK(obj) oe_in_pack(&to_pack, obj)
+#define SIZE(obj) oe_size(&to_pack, obj)
+#define SET_SIZE(obj,size) oe_set_size(&to_pack, obj, size)
 #define DELTA(obj) oe_delta(&to_pack, obj)
 #define DELTA_CHILD(obj) oe_delta_child(&to_pack, obj)
 #define DELTA_SIBLING(obj) oe_delta_sibling(&to_pack, obj)
@@ -274,7 +276,7 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent
 
 	if (!usable_delta) {
 		if (oe_type(entry) == OBJ_BLOB &&
-		    entry->size > big_file_threshold &&
+		    oe_size_greater_than(&to_pack, entry, big_file_threshold) &&
 		    (st = open_istream(entry->idx.oid.hash, &type, &size, NULL)) != NULL)
 			buf = NULL;
 		else {
@@ -384,12 +386,13 @@ static off_t write_reuse_object(struct hashfile *f, struct object_entry *entry,
 	unsigned char header[MAX_PACK_OBJECT_HEADER],
 		      dheader[MAX_PACK_OBJECT_HEADER];
 	unsigned hdrlen;
+	unsigned long entry_size = SIZE(entry);
 
 	if (DELTA(entry))
 		type = (allow_ofs_delta && DELTA(entry)->idx.offset) ?
 			OBJ_OFS_DELTA : OBJ_REF_DELTA;
 	hdrlen = encode_in_pack_object_header(header, sizeof(header),
-					      type, entry->size);
+					      type, entry_size);
 
 	offset = entry->in_pack_offset;
 	revidx = find_pack_revindex(p, offset);
@@ -406,7 +409,7 @@ static off_t write_reuse_object(struct hashfile *f, struct object_entry *entry,
 	datalen -= entry->in_pack_header_size;
 
 	if (!pack_to_stdout && p->index_version == 1 &&
-	    check_pack_inflate(p, &w_curs, offset, datalen, entry->size)) {
+	    check_pack_inflate(p, &w_curs, offset, datalen, entry_size)) {
 		error("corrupt packed object for %s",
 		      oid_to_hex(&entry->idx.oid));
 		unuse_pack(&w_curs);
@@ -1407,6 +1410,8 @@ static void cleanup_preferred_base(void)
 
 static void check_object(struct object_entry *entry)
 {
+	unsigned long canonical_size;
+
 	if (IN_PACK(entry)) {
 		struct packed_git *p = IN_PACK(entry);
 		struct pack_window *w_curs = NULL;
@@ -1444,7 +1449,7 @@ static void check_object(struct object_entry *entry)
 		default:
 			/* Not a delta hence we've already got all we need. */
 			oe_set_type(entry, entry->in_pack_type);
-			entry->size = in_pack_size;
+			SET_SIZE(entry, in_pack_size);
 			entry->in_pack_header_size = used;
 			if (oe_type(entry) < OBJ_COMMIT || oe_type(entry) > OBJ_BLOB)
 				goto give_up;
@@ -1501,9 +1506,9 @@ static void check_object(struct object_entry *entry)
 			 * circular deltas.
 			 */
 			oe_set_type(entry, entry->in_pack_type);
-			entry->size = in_pack_size; /* delta size */
+			SET_SIZE(entry, in_pack_size); /* delta size */
 			SET_DELTA(entry, base_entry);
-			entry->delta_size = entry->size;
+			entry->delta_size = in_pack_size;
 			entry->delta_sibling_idx = base_entry->delta_child_idx;
 			SET_DELTA_CHILD(base_entry, entry);
 			unuse_pack(&w_curs);
@@ -1519,9 +1524,10 @@ static void check_object(struct object_entry *entry)
 			 * object size from the delta header.
 			 */
 			delta_pos = entry->in_pack_offset + entry->in_pack_header_size;
-			entry->size = get_size_from_delta(p, &w_curs, delta_pos);
-			if (entry->size == 0)
+			canonical_size = get_size_from_delta(p, &w_curs, delta_pos);
+			if (canonical_size == 0)
 				goto give_up;
+			SET_SIZE(entry, canonical_size);
 			unuse_pack(&w_curs);
 			return;
 		}
@@ -1535,13 +1541,18 @@ static void check_object(struct object_entry *entry)
 		unuse_pack(&w_curs);
 	}
 
-	oe_set_type(entry, sha1_object_info(entry->idx.oid.hash, &entry->size));
-	/*
-	 * The error condition is checked in prepare_pack().  This is
-	 * to permit a missing preferred base object to be ignored
-	 * as a preferred base.  Doing so can result in a larger
-	 * pack file, but the transfer will still take place.
-	 */
+	oe_set_type(entry, sha1_object_info(entry->idx.oid.hash,
+					    &canonical_size));
+	if (entry->type_valid) {
+		SET_SIZE(entry, canonical_size);
+	} else {
+		/*
+		 * Bad object type is checked in prepare_pack().  This is
+		 * to permit a missing preferred base object to be ignored
+		 * as a preferred base.  Doing so can result in a larger
+		 * pack file, but the transfer will still take place.
+		 */
+	}
 }
 
 static int pack_offset_sort(const void *_a, const void *_b)
@@ -1581,6 +1592,7 @@ static void drop_reused_delta(struct object_entry *entry)
 	unsigned *idx = &to_pack.objects[entry->delta_idx - 1].delta_child_idx;
 	struct object_info oi = OBJECT_INFO_INIT;
 	enum object_type type;
+	unsigned long size;
 
 	while (*idx) {
 		struct object_entry *oe = &to_pack.objects[*idx - 1];
@@ -1593,7 +1605,7 @@ static void drop_reused_delta(struct object_entry *entry)
 	SET_DELTA(entry, NULL);
 	entry->depth = 0;
 
-	oi.sizep = &entry->size;
+	oi.sizep = &size;
 	oi.typep = &type;
 	if (packed_object_info(IN_PACK(entry), entry->in_pack_offset, &oi) < 0) {
 		/*
@@ -1603,10 +1615,11 @@ static void drop_reused_delta(struct object_entry *entry)
 		 * and dealt with in prepare_pack().
 		 */
 		oe_set_type(entry, sha1_object_info(entry->idx.oid.hash,
-						    &entry->size));
+						    &size));
 	} else {
 		oe_set_type(entry, type);
 	}
+	SET_SIZE(entry, size);
 }
 
 /*
@@ -1746,7 +1759,8 @@ static void get_object_details(void)
 	for (i = 0; i < to_pack.nr_objects; i++) {
 		struct object_entry *entry = sorted_by_offset[i];
 		check_object(entry);
-		if (entry->type_valid && big_file_threshold < entry->size)
+		if (entry->type_valid &&
+		    oe_size_greater_than(&to_pack, entry, big_file_threshold))
 			entry->no_try_delta = 1;
 	}
 
@@ -1775,6 +1789,8 @@ static int type_size_sort(const void *_a, const void *_b)
 	const struct object_entry *b = *(struct object_entry **)_b;
 	enum object_type a_type = oe_type(a);
 	enum object_type b_type = oe_type(b);
+	unsigned long a_size = SIZE(a);
+	unsigned long b_size = SIZE(b);
 
 	if (a_type > b_type)
 		return -1;
@@ -1788,9 +1804,9 @@ static int type_size_sort(const void *_a, const void *_b)
 		return -1;
 	if (a->preferred_base < b->preferred_base)
 		return 1;
-	if (a->size > b->size)
+	if (a_size > b_size)
 		return -1;
-	if (a->size < b->size)
+	if (a_size < b_size)
 		return 1;
 	return a < b ? -1 : (a > b);  /* newest first */
 }
@@ -1843,6 +1859,41 @@ static pthread_mutex_t progress_mutex;
 
 #endif
 
+unsigned long oe_get_size_slow(struct packing_data *pack,
+			       const struct object_entry *e)
+{
+	struct packed_git *p;
+	struct pack_window *w_curs;
+	unsigned char *buf;
+	enum object_type type;
+	unsigned long used, avail, size;
+
+	if (e->type_ != OBJ_OFS_DELTA && e->type_ != OBJ_REF_DELTA) {
+		read_lock();
+		if (sha1_object_info(e->idx.oid.hash, &size) < 0)
+			die(_("unable to get size of %s"),
+			    oid_to_hex(&e->idx.oid));
+		read_unlock();
+		return size;
+	}
+
+	p = oe_in_pack(pack, e);
+	if (!p)
+		die("BUG: when e->type is a delta, it must belong to a pack");
+
+	read_lock();
+	w_curs = NULL;
+	buf = use_pack(p, &w_curs, e->in_pack_offset, &avail);
+	used = unpack_object_header_buffer(buf, avail, &type, &size);
+	if (used == 0)
+		die(_("unable to parse object header of %s"),
+		    oid_to_hex(&e->idx.oid));
+
+	unuse_pack(&w_curs);
+	read_unlock();
+	return size;
+}
+
 static int try_delta(struct unpacked *trg, struct unpacked *src,
 		     unsigned max_depth, unsigned long *mem_usage)
 {
@@ -1877,7 +1928,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
 		return 0;
 
 	/* Now some size filtering heuristics. */
-	trg_size = trg_entry->size;
+	trg_size = SIZE(trg_entry);
 	if (!DELTA(trg_entry)) {
 		max_size = trg_size/2 - 20;
 		ref_depth = 1;
@@ -1889,7 +1940,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
 						(max_depth - ref_depth + 1);
 	if (max_size == 0)
 		return 0;
-	src_size = src_entry->size;
+	src_size = SIZE(src_entry);
 	sizediff = src_size < trg_size ? trg_size - src_size : 0;
 	if (sizediff >= max_size)
 		return 0;
@@ -2009,7 +2060,7 @@ static unsigned long free_unpacked(struct unpacked *n)
 	free_delta_index(n->index);
 	n->index = NULL;
 	if (n->data) {
-		freed_mem += n->entry->size;
+		freed_mem += SIZE(n->entry);
 		FREE_AND_NULL(n->data);
 	}
 	n->entry = NULL;
@@ -2459,7 +2510,8 @@ static void prepare_pack(int window, int depth)
 			 */
 			continue;
 
-		if (!entry->type_valid || entry->size < 50)
+		if (!entry->type_valid ||
+		    oe_size_less_than(&to_pack, entry, 50))
 			continue;
 
 		if (entry->no_try_delta)
diff --git a/pack-objects.c b/pack-objects.c
index 13f2b2bff2..59c6e40a02 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -120,8 +120,15 @@ struct object_entry *packlist_alloc(struct packing_data *pdata,
 {
 	struct object_entry *new_entry;
 
-	if (!pdata->nr_objects)
+	if (!pdata->nr_objects) {
 		prepare_in_pack_by_idx(pdata);
+		if (getenv("GIT_TEST_OE_SIZE_BITS")) {
+			int bits = atoi(getenv("GIT_TEST_OE_SIZE_BITS"));;
+			pdata->oe_size_limit = 1 << bits;
+		}
+		if (!pdata->oe_size_limit)
+			pdata->oe_size_limit = 1 << OE_SIZE_BITS;
+	}
 	if (pdata->nr_objects >= pdata->nr_alloc) {
 		pdata->nr_alloc = (pdata->nr_alloc  + 1024) * 3 / 2;
 		REALLOC_ARRAY(pdata->objects, pdata->nr_alloc);
diff --git a/pack-objects.h b/pack-objects.h
index d23e17050c..8bb082f22f 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -5,6 +5,7 @@
 #define OE_DEPTH_BITS		12
 #define OE_IN_PACK_BITS		10
 #define OE_Z_DELTA_BITS		16
+#define OE_SIZE_BITS		31
 
 /*
  * State flags for depth-first search used for analyzing delta cycles.
@@ -72,7 +73,8 @@ enum dfs_state {
  */
 struct object_entry {
 	struct pack_idx_entry idx;
-	unsigned long size;	/* uncompressed size */
+	uint32_t size_:OE_SIZE_BITS;
+	uint32_t size_valid:1;
 	unsigned in_pack_idx:OE_IN_PACK_BITS;	/* already in pack */
 	off_t in_pack_offset;
 	uint32_t delta_idx;	/* delta base object */
@@ -117,6 +119,8 @@ struct packing_data {
 	 */
 	struct packed_git **in_pack_by_idx;
 	struct packed_git **in_pack;
+
+	uintmax_t oe_size_limit;
 };
 
 struct object_entry *packlist_alloc(struct packing_data *pdata,
@@ -256,4 +260,51 @@ static inline void oe_set_delta_sibling(struct packing_data *pack,
 		e->delta_sibling_idx = 0;
 }
 
+unsigned long oe_get_size_slow(struct packing_data *pack,
+			       const struct object_entry *e);
+static inline unsigned long oe_size(struct packing_data *pack,
+				    const struct object_entry *e)
+{
+	if (e->size_valid)
+		return e->size_;
+
+	return oe_get_size_slow(pack, e);
+}
+
+static inline int oe_size_less_than(struct packing_data *pack,
+				    const struct object_entry *lhs,
+				    unsigned long rhs)
+{
+	if (lhs->size_valid)
+		return lhs->size_ < rhs;
+	if (rhs < pack->oe_size_limit) /* rhs < 2^x <= lhs ? */
+		return 0;
+	return oe_get_size_slow(pack, lhs) < rhs;
+}
+
+static inline int oe_size_greater_than(struct packing_data *pack,
+				       const struct object_entry *lhs,
+				       unsigned long rhs)
+{
+	if (lhs->size_valid)
+		return lhs->size_ > rhs;
+	if (rhs < pack->oe_size_limit) /* rhs < 2^x <= lhs ? */
+		return 1;
+	return oe_get_size_slow(pack, lhs) > rhs;
+}
+
+static inline void oe_set_size(struct packing_data *pack,
+			       struct object_entry *e,
+			       unsigned long size)
+{
+	if (size < pack->oe_size_limit) {
+		e->size_ = size;
+		e->size_valid = 1;
+	} else {
+		e->size_valid = 0;
+		if (oe_get_size_slow(pack, e) != size)
+			die("BUG: 'size' is supposed to be the object size!");
+	}
+}
+
 #endif
diff --git a/t/README b/t/README
index c6130ff16d..da117ca734 100644
--- a/t/README
+++ b/t/README
@@ -306,6 +306,12 @@ GIT_TEST_FULL_IN_PACK_ARRAY exercises the uncommon pack-objects code
 path where there are more than 1024 packs even if the actual number of
 packs in repository is below this limit.
 
+GIT_TEST_OE_SIZE_BITS=<bits> exercises the uncommon pack-objects
+code path where we do not cache objecct size in memory and read it
+from existing packs on demand. This normally only happens when the
+object size is over 2GB. This variable forces the code path on any
+object larger than 2^<bits> bytes.
+
 Naming Tests
 ------------
 
-- 
2.17.0.rc0.348.gd5a49e0b6f
Previous: Duy NguyenNext: Jeff King
Message 160 of 273 in “Reduce pack-objects memory footprint?”
  1. Duy NguyenFeb 28, 2018
  2. Jeff KingFeb 28, 2018
  3. Duy NguyenFeb 28, 2018
  4. Jeff KingFeb 28, 2018
  5. Duy NguyenFeb 28, 2018
  6. Eric WongFeb 28, 2018
  7. Duy NguyenMar 1, 2018
  8. 00/11 Reduce pack-objects memory footprintNguyễn Thái Ngọc Duy, Mar 1, 2018
  9. 01/11 pack-objects: document holes in struct object_entry.hNguyễn Thái Ngọc Duy, Mar 1, 2018
  10. 02/11 pack-objects: turn type and in_pack_type to bitfieldsNguyễn Thái Ngọc Duy, Mar 1, 2018
  11. 03/11 pack-objects: use bitfield for object_entry::dfs_stateNguyễn Thái Ngọc Duy, Mar 1, 2018
  12. 04/11 pack-objects: use bitfield for object_entry::depthNguyễn Thái Ngọc Duy, Mar 1, 2018
  13. Junio C HamanoMar 1, 2018
  14. 06/11 pack-objects: move in_pack_pos out of struct object_entryNguyễn Thái Ngọc Duy, Mar 1, 2018
  15. 08/11 pack-objects: faster reverse packed_git lookupNguyễn Thái Ngọc Duy, Mar 1, 2018
  16. 05/11 pack-objects: note about in_pack_header_sizeNguyễn Thái Ngọc Duy, Mar 1, 2018
  17. 07/11 pack-objects: move in_pack out of struct object_entryNguyễn Thái Ngọc Duy, Mar 1, 2018
  18. Ævar Arnfjörð BjarmasonMar 1, 2018
  19. Jeff KingMar 1, 2018
  20. Duy NguyenMar 2, 2018
  21. Junio C HamanoMar 1, 2018
  22. 09/11 pack-objects: refer to delta objects by index instead of pointerNguyễn Thái Ngọc Duy, Mar 1, 2018
  23. Junio C HamanoMar 1, 2018
  24. 10/11 pack-objects: reorder 'hash' to pack struct object_entryNguyễn Thái Ngọc Duy, Mar 1, 2018
  25. 11/11 pack-objects: increase pack file limit to 4096Nguyễn Thái Ngọc Duy, Mar 1, 2018
  26. Ævar Arnfjörð BjarmasonMar 1, 2018
  27. Duy NguyenMar 2, 2018
  28. Jeff KingMar 2, 2018
  29. 0/9 Reduce pack-objects memory footprintNguyễn Thái Ngọc Duy, Mar 3, 2018
  30. 1/9 pack-objects: document holes in struct object_entry.hNguyễn Thái Ngọc Duy, Mar 3, 2018
  31. 2/9 pack-objects: turn type and in_pack_type to bitfieldsNguyễn Thái Ngọc Duy, Mar 3, 2018
  32. 3/9 pack-objects: use bitfield for object_entry::dfs_stateNguyễn Thái Ngọc Duy, Mar 3, 2018
  33. 4/9 pack-objects: use bitfield for object_entry::depthNguyễn Thái Ngọc Duy, Mar 3, 2018
  34. 5/9 pack-objects: note about in_pack_header_sizeNguyễn Thái Ngọc Duy, Mar 3, 2018
  35. 6/9 pack-objects: move in_pack_pos out of struct object_entryNguyễn Thái Ngọc Duy, Mar 3, 2018
  36. 7/9 pack-objects: move in_pack out of struct object_entryNguyễn Thái Ngọc Duy, Mar 3, 2018
  37. 8/9 pack-objects: refer to delta objects by index instead of pointerNguyễn Thái Ngọc Duy, Mar 3, 2018
  38. 9/9 pack-objects: reorder 'hash' to pack struct object_entryNguyễn Thái Ngọc Duy, Mar 3, 2018
  39. Duy NguyenMar 5, 2018
  40. 00/12 Reduce pack-objects memory footprintNguyễn Thái Ngọc Duy, Mar 8, 2018
  41. 01/12 pack-objects: a bit of document about struct object_entryNguyễn Thái Ngọc Duy, Mar 8, 2018
  42. Junio C HamanoMar 9, 2018
  43. 02/12 pack-objects: turn type and in_pack_type to bitfieldsNguyễn Thái Ngọc Duy, Mar 8, 2018
  44. Junio C HamanoMar 9, 2018
  45. Duy NguyenMar 12, 2018
  46. 03/12 pack-objects: use bitfield for object_entry::dfs_stateNguyễn Thái Ngọc Duy, Mar 8, 2018
  47. 04/12 pack-objects: use bitfield for object_entry::depthNguyễn Thái Ngọc Duy, Mar 8, 2018
  48. Junio C HamanoMar 9, 2018
  49. 05/12 pack-objects: note about in_pack_header_sizeNguyễn Thái Ngọc Duy, Mar 8, 2018
  50. 06/12 pack-objects: move in_pack_pos out of struct object_entryNguyễn Thái Ngọc Duy, Mar 8, 2018
  51. 07/12 pack-objects: move in_pack out of struct object_entryNguyễn Thái Ngọc Duy, Mar 8, 2018
  52. Junio C HamanoMar 9, 2018
  53. 08/12 pack-objects: refer to delta objects by index instead of pointerNguyễn Thái Ngọc Duy, Mar 8, 2018
  54. Junio C HamanoMar 14, 2018
  55. 09/12 pack-objects: reorder 'hash' to pack struct object_entryNguyễn Thái Ngọc Duy, Mar 8, 2018
  56. 10/12 pack-objects: shrink z_delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 8, 2018
  57. 11/12 pack-objects: shrink size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 8, 2018
  58. 12/12 pack-objects: shrink delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 8, 2018
  59. 00/11 nd/pack-objects-pack-struct updatesNguyễn Thái Ngọc Duy, Mar 16, 2018
  60. 01/11 pack-objects: a bit of document about struct object_entryNguyễn Thái Ngọc Duy, Mar 16, 2018
  61. Junio C HamanoMar 16, 2018
  62. Duy NguyenMar 17, 2018
  63. 02/11 pack-objects: turn type and in_pack_type to bitfieldsNguyễn Thái Ngọc Duy, Mar 16, 2018
  64. Junio C HamanoMar 16, 2018
  65. 04/11 pack-objects: use bitfield for object_entry::depthNguyễn Thái Ngọc Duy, Mar 16, 2018
  66. 05/11 pack-objects: move in_pack_pos out of struct object_entryNguyễn Thái Ngọc Duy, Mar 16, 2018
  67. 03/11 pack-objects: use bitfield for object_entry::dfs_stateNguyễn Thái Ngọc Duy, Mar 16, 2018
  68. 08/11 pack-objects: shrink z_delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 16, 2018
  69. Junio C HamanoMar 16, 2018
  70. 11/11 pack-objects.h: reorder members to shrink struct object_entryNguyễn Thái Ngọc Duy, Mar 16, 2018
  71. Junio C HamanoMar 16, 2018
  72. Duy NguyenMar 17, 2018
  73. 07/11 pack-objects: refer to delta objects by index instead of pointerNguyễn Thái Ngọc Duy, Mar 16, 2018
  74. Junio C HamanoMar 16, 2018
  75. 10/11 pack-objects: shrink delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 16, 2018
  76. 06/11 pack-objects: move in_pack out of struct object_entryNguyễn Thái Ngọc Duy, Mar 16, 2018
  77. Stefan BellerMar 26, 2018
  78. 09/11 pack-objects: shrink size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 16, 2018
  79. Junio C HamanoMar 16, 2018
  80. Junio C HamanoMar 16, 2018
  81. 00/11 nd/pack-objects-pack-struct updatesNguyễn Thái Ngọc Duy, Mar 17, 2018
  82. 01/11 pack-objects: a bit of document about struct object_entryNguyễn Thái Ngọc Duy, Mar 17, 2018
  83. 03/11 pack-objects: use bitfield for object_entry::dfs_stateNguyễn Thái Ngọc Duy, Mar 17, 2018
  84. 04/11 pack-objects: use bitfield for object_entry::depthNguyễn Thái Ngọc Duy, Mar 17, 2018
  85. Ævar Arnfjörð BjarmasonMar 17, 2018
  86. 07/11 pack-objects: refer to delta objects by index instead of pointerNguyễn Thái Ngọc Duy, Mar 17, 2018
  87. 08/11 pack-objects: shrink z_delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 17, 2018
  88. 09/11 pack-objects: shrink size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 17, 2018
  89. Ævar Arnfjörð BjarmasonMar 17, 2018
  90. Junio C HamanoMar 18, 2018
  91. Duy NguyenMar 18, 2018
  92. 11/11 pack-objects.h: reorder members to shrink struct object_entryNguyễn Thái Ngọc Duy, Mar 17, 2018
  93. Ævar Arnfjörð BjarmasonMar 17, 2018
  94. Duy NguyenMar 18, 2018
  95. 10/11 pack-objects: shrink delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 17, 2018
  96. 02/11 pack-objects: turn type and in_pack_type to bitfieldsNguyễn Thái Ngọc Duy, Mar 17, 2018
  97. 05/11 pack-objects: move in_pack_pos out of struct object_entryNguyễn Thái Ngọc Duy, Mar 17, 2018
  98. 06/11 pack-objects: move in_pack out of struct object_entryNguyễn Thái Ngọc Duy, Mar 17, 2018
  99. Ævar Arnfjörð BjarmasonMar 17, 2018
  100. Ævar Arnfjörð BjarmasonMar 17, 2018
  101. 00/11 nd/pack-objects-pack-struct updatesNguyễn Thái Ngọc Duy, Mar 18, 2018
  102. 01/11 pack-objects: a bit of document about struct object_entryNguyễn Thái Ngọc Duy, Mar 18, 2018
  103. 02/11 pack-objects: turn type and in_pack_type to bitfieldsNguyễn Thái Ngọc Duy, Mar 18, 2018
  104. 03/11 pack-objects: use bitfield for object_entry::dfs_stateNguyễn Thái Ngọc Duy, Mar 18, 2018
  105. 04/11 pack-objects: use bitfield for object_entry::depthNguyễn Thái Ngọc Duy, Mar 18, 2018
  106. 05/11 pack-objects: move in_pack_pos out of struct object_entryNguyễn Thái Ngọc Duy, Mar 18, 2018
  107. 08/11 pack-objects: shrink z_delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 18, 2018
  108. 06/11 pack-objects: move in_pack out of struct object_entryNguyễn Thái Ngọc Duy, Mar 18, 2018
  109. 07/11 pack-objects: refer to delta objects by index instead of pointerNguyễn Thái Ngọc Duy, Mar 18, 2018
  110. 11/11 pack-objects: reorder members to shrink struct object_entryNguyễn Thái Ngọc Duy, Mar 18, 2018
  111. 09/11 pack-objects: shrink size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 18, 2018
  112. Ævar Arnfjörð BjarmasonMar 18, 2018
  113. Junio C HamanoMar 19, 2018
  114. Duy NguyenMar 19, 2018
  115. Junio C HamanoMar 19, 2018
  116. Duy NguyenMar 19, 2018
  117. Junio C HamanoMar 19, 2018
  118. Duy NguyenMar 19, 2018
  119. Junio C HamanoMar 19, 2018
  120. Duy NguyenMar 20, 2018
  121. Junio C HamanoMar 20, 2018
  122. Jeff KingMar 21, 2018
  123. Duy NguyenMar 21, 2018
  124. Duy NguyenMar 20, 2018
  125. 10/11 pack-objects: shrink delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 18, 2018
  126. Ævar Arnfjörð BjarmasonMar 18, 2018
  127. Jeff KingMar 21, 2018
  128. Duy NguyenMar 21, 2018
  129. Ævar Arnfjörð BjarmasonMar 21, 2018
  130. Duy NguyenMar 21, 2018
  131. Duy NguyenMar 21, 2018
  132. Junio C HamanoMar 21, 2018
  133. Jeff KingMar 22, 2018
  134. Jeff KingMar 22, 2018
  135. Duy NguyenMar 22, 2018
  136. Jeff KingMar 22, 2018
  137. Duy NguyenMar 22, 2018
  138. Ramsay JonesMar 23, 2018
  139. Jeff KingMar 23, 2018
  140. Jeff KingMar 23, 2018
  141. Ramsay JonesMar 23, 2018
  142. Jeff KingMar 24, 2018
  143. Duy NguyenMar 23, 2018
  144. Ramsay JonesMar 23, 2018
  145. Ævar Arnfjörð BjarmasonMar 21, 2018
  146. Junio C HamanoMar 21, 2018
  147. Duy NguyenMar 21, 2018
  148. Jeff KingMar 22, 2018
  149. Duy NguyenMar 22, 2018
  150. Jeff KingMar 22, 2018
  151. 00/13 nd/pack-objects-pack-struct updatesNguyễn Thái Ngọc Duy, Mar 24, 2018
  152. 01/13 pack-objects: a bit of document about struct object_entryNguyễn Thái Ngọc Duy, Mar 24, 2018
  153. 03/13 pack-objects: use bitfield for object_entry::dfs_stateNguyễn Thái Ngọc Duy, Mar 24, 2018
  154. Jeff KingMar 30, 2018
  155. 04/13 pack-objects: use bitfield for object_entry::depthNguyễn Thái Ngọc Duy, Mar 24, 2018
  156. Jeff KingMar 30, 2018
  157. 13/13 pack-objects: reorder members to shrink struct object_entryNguyễn Thái Ngọc Duy, Mar 24, 2018
  158. Jeff KingMar 30, 2018
  159. Duy NguyenMar 31, 2018
  160. 11/13 pack-objects: shrink size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 24, 2018
  161. Jeff KingMar 30, 2018
  162. 02/13 pack-objects: turn type and in_pack_type to bitfieldsNguyễn Thái Ngọc Duy, Mar 24, 2018
  163. Jeff KingMar 30, 2018
  164. 12/13 pack-objects: shrink delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 24, 2018
  165. Jeff KingMar 30, 2018
  166. Duy NguyenMar 31, 2018
  167. Duy NguyenMar 31, 2018
  168. 06/13 pack-objects: move in_pack out of struct object_entryNguyễn Thái Ngọc Duy, Mar 24, 2018
  169. Ævar Arnfjörð BjarmasonMar 24, 2018
  170. Duy NguyenMar 24, 2018
  171. Ævar Arnfjörð BjarmasonMar 24, 2018
  172. Jeff KingMar 30, 2018
  173. Duy NguyenMar 31, 2018
  174. Jeff KingMar 31, 2018
  175. Duy NguyenMar 31, 2018
  176. 05/13 pack-objects: move in_pack_pos out of struct object_entryNguyễn Thái Ngọc Duy, Mar 24, 2018
  177. Jeff KingMar 30, 2018
  178. 10/13 pack-objects: clarify the use of object_entry::sizeNguyễn Thái Ngọc Duy, Mar 24, 2018
  179. Jeff KingMar 30, 2018
  180. Duy NguyenMar 31, 2018
  181. Jeff KingMar 31, 2018
  182. 09/13 pack-objects: don't check size when the object is badNguyễn Thái Ngọc Duy, Mar 24, 2018
  183. 07/13 pack-objects: refer to delta objects by index instead of pointerNguyễn Thái Ngọc Duy, Mar 24, 2018
  184. Jeff KingMar 30, 2018
  185. 08/13 pack-objects: shrink z_delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 24, 2018
  186. Jeff KingMar 30, 2018
  187. Duy NguyenMar 31, 2018
  188. Jeff KingMar 31, 2018
  189. Jeff KingMar 26, 2018
  190. Duy NguyenMar 26, 2018
  191. Jeff KingMar 27, 2018
  192. 00/15 nd/pack-objects-pack-struct updatesNguyễn Thái Ngọc Duy, Mar 31, 2018
  193. 01/15 t/README: mention about running the test suite in special modesNguyễn Thái Ngọc Duy, Mar 31, 2018
  194. 02/15 pack-objects: a bit of document about struct object_entryNguyễn Thái Ngọc Duy, Mar 31, 2018
  195. 07/15 pack-objects: move in_pack out of struct object_entryNguyễn Thái Ngọc Duy, Mar 31, 2018
  196. 06/15 pack-objects: move in_pack_pos out of struct object_entryNguyễn Thái Ngọc Duy, Mar 31, 2018
  197. 05/15 pack-objects: use bitfield for object_entry::depthNguyễn Thái Ngọc Duy, Mar 31, 2018
  198. 04/15 pack-objects: use bitfield for object_entry::dfs_stateNguyễn Thái Ngọc Duy, Mar 31, 2018
  199. 08/15 pack-objects: refer to delta objects by index instead of pointerNguyễn Thái Ngọc Duy, Mar 31, 2018
  200. 14/15 pack-objects: reorder members to shrink struct object_entryNguyễn Thái Ngọc Duy, Mar 31, 2018
  201. 15/15 ci: exercise the whole test suite with uncommon code in pack-objectsNguyễn Thái Ngọc Duy, Mar 31, 2018
  202. 10/15 pack-objects: don't check size when the object is badNguyễn Thái Ngọc Duy, Mar 31, 2018
  203. 13/15 pack-objects: shrink delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 31, 2018
  204. 09/15 pack-objects: shrink z_delta_size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 31, 2018
  205. 12/15 pack-objects: shrink size field in struct object_entryNguyễn Thái Ngọc Duy, Mar 31, 2018
  206. 11/15 pack-objects: clarify the use of object_entry::sizeNguyễn Thái Ngọc Duy, Mar 31, 2018
  207. 03/15 pack-objects: turn type and in_pack_type to bitfieldsNguyễn Thái Ngọc Duy, Mar 31, 2018
  208. Ævar Arnfjörð BjarmasonMar 31, 2018
  209. Duy NguyenMar 31, 2018
  210. Ævar Arnfjörð BjarmasonMar 31, 2018
  211. Jeff KingApr 6, 2018
  212. 0/1 Avoid expensive 'repack -ad' in gc --autoNguyễn Thái Ngọc Duy, Mar 1, 2018
  213. 1/1 gc --auto: exclude the largest giant pack in low-memory configNguyễn Thái Ngọc Duy, Mar 1, 2018
  214. Junio C HamanoMar 1, 2018
  215. Duy NguyenMar 2, 2018
  216. Ævar Arnfjörð BjarmasonMar 5, 2018
  217. 0/5 Avoid expensive 'repack -ad' in gc --autoNguyễn Thái Ngọc Duy, Mar 6, 2018
  218. 1/5 fixup! Add a test showing that 'git repack' throws away grafted-away parentsNguyễn Thái Ngọc Duy, Mar 6, 2018
  219. Junio C HamanoMar 6, 2018
  220. 2/5 repack: add --keep-pack optionNguyễn Thái Ngọc Duy, Mar 6, 2018
  221. Junio C HamanoMar 6, 2018
  222. Duy NguyenMar 7, 2018
  223. 3/5 gc --auto: exclude base pack if not enough mem to "repack -ad"Nguyễn Thái Ngọc Duy, Mar 6, 2018
  224. Junio C HamanoMar 6, 2018
  225. Duy NguyenMar 7, 2018
  226. Junio C HamanoMar 7, 2018
  227. Ævar Arnfjörð BjarmasonMar 12, 2018
  228. Junio C HamanoMar 12, 2018
  229. Ævar Arnfjörð BjarmasonMar 12, 2018
  230. Duy NguyenMar 15, 2018
  231. Johannes SchindelinMar 7, 2018
  232. Junio C HamanoMar 7, 2018
  233. Ævar Arnfjörð BjarmasonMar 12, 2018
  234. Duy NguyenMar 15, 2018
  235. Ævar Arnfjörð BjarmasonMar 15, 2018
  236. Duy NguyenMar 16, 2018
  237. 4/5 pack-objects: show some progress when counting kept objectsNguyễn Thái Ngọc Duy, Mar 6, 2018
  238. Ævar Arnfjörð BjarmasonMar 12, 2018
  239. Duy NguyenMar 16, 2018
  240. Duy NguyenMar 16, 2018
  241. 5/5 pack-objects: display progress in get_object_details()Nguyễn Thái Ngọc Duy, Mar 6, 2018
  242. Junio C HamanoMar 6, 2018
  243. 0/7 nd/repack-keep-pack updatesNguyễn Thái Ngọc Duy, Mar 16, 2018
  244. 1/7 repack: add --keep-pack optionNguyễn Thái Ngọc Duy, Mar 16, 2018
  245. 4/7 gc --auto: exclude base pack if not enough mem to "repack -ad"Nguyễn Thái Ngọc Duy, Mar 16, 2018
  246. Ævar Arnfjörð BjarmasonMar 16, 2018
  247. 6/7 pack-objects: show some progress when counting kept objectsNguyễn Thái Ngọc Duy, Mar 16, 2018
  248. 7/7 pack-objects: display progress in get_object_details()Nguyễn Thái Ngọc Duy, Mar 16, 2018
  249. 5/7 gc: handle a corner case in gc.bigPackThresholdNguyễn Thái Ngọc Duy, Mar 16, 2018
  250. Ævar Arnfjörð BjarmasonMar 16, 2018
  251. 2/7 gc: add --keep-base-packNguyễn Thái Ngọc Duy, Mar 16, 2018
  252. Ævar Arnfjörð BjarmasonMar 16, 2018
  253. Duy NguyenMar 19, 2018
  254. Ævar Arnfjörð BjarmasonMar 19, 2018
  255. Ævar Arnfjörð BjarmasonMar 16, 2018
  256. 3/7 gc: detect base packs based on gc.bigPackThreshold configNguyễn Thái Ngọc Duy, Mar 16, 2018
  257. Ævar Arnfjörð BjarmasonMar 16, 2018
  258. 0/7 nd/repack-keep-pack updatesNguyễn Thái Ngọc Duy, Mar 24, 2018
  259. 1/7 t7700: have closing quote of a test at the beginning of lineNguyễn Thái Ngọc Duy, Mar 24, 2018
  260. 4/7 gc: add gc.bigPackThreshold configNguyễn Thái Ngọc Duy, Mar 24, 2018
  261. 3/7 gc: add --keep-largest-pack optionNguyễn Thái Ngọc Duy, Mar 24, 2018
  262. 6/7 gc --auto: exclude base pack if not enough mem to "repack -ad"Nguyễn Thái Ngọc Duy, Mar 24, 2018
  263. 7/7 pack-objects: show some progress when counting kept objectsNguyễn Thái Ngọc Duy, Mar 24, 2018
  264. 5/7 gc: handle a corner case in gc.bigPackThresholdNguyễn Thái Ngọc Duy, Mar 24, 2018
  265. 2/7 repack: add --keep-pack optionNguyễn Thái Ngọc Duy, Mar 24, 2018
  266. Duy NguyenMar 2, 2018
  267. Eric WongMar 2, 2018
  268. Jeff KingMar 2, 2018
  269. Duy NguyenMar 2, 2018
  270. Duy NguyenMar 2, 2018
  271. Why does pack-objects use so much memory on incremental packing?Ævar Arnfjörð Bjarmason, Mar 17, 2018
  272. Duy NguyenMar 18, 2018
  273. Jeff KingMar 20, 2018

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.