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

[PATCH 07/10] index-pack: learn about pack index version 2

From
Nicolas Pitre <nico@cam.org>
Date
Apr 9, 2007, 05:06 UTC
Message-ID
<117609520190-git-send-email-nico@cam.org>
In-Reply-To
<11760952002410-git-send-email-nico@cam.org>
Like previous patch but for index-pack.
[ There is quite some code duplication between pack-objects and index-pack
  for generating a pack index (and fast-import as well I suppose).  This
  should be reworked into a common function eventually. But not now. ]
Signed-off-by: Nicolas Pitre <nico@cam.org>
---
 index-pack.c |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 57 insertions(+), 9 deletions(-)
diff --git a/index-pack.c b/index-pack.c
index d33f723..a833f64 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -686,9 +686,10 @@ static const char *write_index_file(const char *index_name, unsigned char *sha1)
 {
 	struct sha1file *f;
 	struct object_entry **sorted_by_sha, **list, **last;
-	unsigned int array[256];
+	uint32_t array[256];
 	int i, fd;
 	SHA_CTX ctx;
+	uint32_t index_version;
 
 	if (nr_objects) {
 		sorted_by_sha =
@@ -699,7 +700,6 @@ static const char *write_index_file(const char *index_name, unsigned char *sha1)
 			sorted_by_sha[i] = &objects[i];
 		qsort(sorted_by_sha, nr_objects, sizeof(sorted_by_sha[0]),
 		      sha1_compare);
-
 	}
 	else
 		sorted_by_sha = list = last = NULL;
@@ -718,6 +718,17 @@ static const char *write_index_file(const char *index_name, unsigned char *sha1)
 		die("unable to create %s: %s", index_name, strerror(errno));
 	f = sha1fd(fd, index_name);
 
+	/* if last object's offset is >= 2^31 we should use index V2 */
+	index_version = (objects[nr_objects-1].offset >> 31) ? 2 : 1;
+
+	/* index versions 2 and above need a header */
+	if (index_version >= 2) {
+		struct pack_idx_header hdr;
+		hdr.idx_signature = htonl(PACK_IDX_SIGNATURE);
+		hdr.idx_version = htonl(index_version);
+		sha1write(f, &hdr, sizeof(hdr));
+	}
+
 	/*
 	 * Write the first-level table (the list is sorted,
 	 * but we use a 256-entry lookup to be able to avoid
@@ -734,24 +745,61 @@ static const char *write_index_file(const char *index_name, unsigned char *sha1)
 		array[i] = htonl(next - sorted_by_sha);
 		list = next;
 	}
-	sha1write(f, array, 256 * sizeof(int));
+	sha1write(f, array, 256 * 4);
 
-	/* recompute the SHA1 hash of sorted object names.
-	 * currently pack-objects does not do this, but that
-	 * can be fixed.
-	 */
+	/* compute the SHA1 hash of sorted object names. */
 	SHA1_Init(&ctx);
+
 	/*
 	 * Write the actual SHA1 entries..
 	 */
 	list = sorted_by_sha;
 	for (i = 0; i < nr_objects; i++) {
 		struct object_entry *obj = *list++;
-		unsigned int offset = htonl(obj->offset);
-		sha1write(f, &offset, 4);
+		if (index_version < 2) {
+			uint32_t offset = htonl(obj->offset);
+			sha1write(f, &offset, 4);
+		}
 		sha1write(f, obj->sha1, 20);
 		SHA1_Update(&ctx, obj->sha1, 20);
 	}
+
+	if (index_version >= 2) {
+		unsigned int nr_large_offset = 0;
+
+		/* write the crc32 table */
+		list = sorted_by_sha;
+		for (i = 0; i < nr_objects; i++) {
+			struct object_entry *obj = *list++;
+			uint32_t crc32_val = htonl(obj->crc32);
+			sha1write(f, &crc32_val, 4);
+		}
+
+		/* write the 32-bit offset table */
+		list = sorted_by_sha;
+		for (i = 0; i < nr_objects; i++) {
+			struct object_entry *obj = *list++;
+			uint32_t offset = (obj->offset <= 0x7fffffff) ?
+				obj->offset : (0x80000000 | nr_large_offset++);
+			offset = htonl(offset);
+			sha1write(f, &offset, 4);
+		}
+
+		/* write the large offset table */
+		list = sorted_by_sha;
+		while (nr_large_offset) {
+			struct object_entry *obj = *list++;
+			uint64_t offset = obj->offset;
+			if (offset > 0x7fffffff) {
+				uint32_t split[2];
+				split[0]	= htonl(offset >> 32);
+				split[1] = htonl(offset & 0xffffffff);
+				sha1write(f, split, 8);
+				nr_large_offset--;
+			}
+		}
+	}
+
 	sha1write(f, sha1, 20);
 	sha1close(f, NULL, 1);
 	free(sorted_by_sha);
-- 
1.5.1.696.g6d352-dirty
Previous: Nicolas PitreNext: Nicolas Pitre
Message 8 of 24 in “support for large packs and 64-bit offsets”
  1. Nicolas PitreApr 9, 2007
  2. 01/10 get rid of num_packed_objects()Nicolas Pitre, Apr 9, 2007
  3. 02/10 make overflow test on delta base offset work regardless of variable sizeNicolas Pitre, Apr 9, 2007
  4. 03/10 add overflow tests on pack offset variablesNicolas Pitre, Apr 9, 2007
  5. 04/10 compute a CRC32 for each object as stored in a packNicolas Pitre, Apr 9, 2007
  6. 05/10 compute object CRC32 with index-packNicolas Pitre, Apr 9, 2007
  7. 06/10 pack-objects: learn about pack index version 2Nicolas Pitre, Apr 9, 2007
  8. 07/10 index-pack: learn about pack index version 2Nicolas Pitre, Apr 9, 2007
  9. 08/10 sha1_file.c: learn about index version 2Nicolas Pitre, Apr 9, 2007
  10. 09/10 show-index.c: learn about index v2Nicolas Pitre, Apr 9, 2007
  11. 10/10 pack-redundant.c: learn about index v2Nicolas Pitre, Apr 9, 2007
  12. Junio C HamanoApr 9, 2007
  13. Nicolas PitreApr 9, 2007
  14. Shawn O. PearceApr 9, 2007
  15. Nicolas PitreApr 9, 2007
  16. Shawn O. PearceApr 9, 2007
  17. Junio C HamanoApr 9, 2007
  18. Shawn O. PearceApr 9, 2007
  19. Nicolas PitreApr 9, 2007
  20. Junio C HamanoApr 9, 2007
  21. Linus TorvaldsApr 9, 2007
  22. Nicolas PitreApr 9, 2007
  23. Shawn O. PearceApr 9, 2007
  24. Nicolas PitreApr 9, 2007

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.