[PATCH 37/38] pack v4: introduce "escape hatches" in the name and path indexes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If the path or name index is zero, this means the entry data is to be
found inline rather than being located in the dictionary table. This is
there to allow easy completion of thin packs without having to add new
table entries which would have required a full rewrite of the pack data.

Signed-off-by: Nicolas Pitre <nico@xxxxxxxxxxx>
---
 packv4-create.c |  6 +++---
 packv4-parse.c  | 28 ++++++++++++++++++++++------
 2 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/packv4-create.c b/packv4-create.c
index fd16222..9d6ffc0 100644
--- a/packv4-create.c
+++ b/packv4-create.c
@@ -343,7 +343,7 @@ void *pv4_encode_commit(void *buffer, unsigned long *sizep)
 	index = dict_add_entry(commit_name_table, tz_val, in, end - in);
 	if (index < 0)
 		goto bad_dict;
-	out += encode_varint(index, out);
+	out += encode_varint(index + 1, out);
 	time = strtoul(end, &end, 10);
 	if (!end || end[0] != ' ' || end[6] != '\n')
 		goto bad_data;
@@ -361,7 +361,7 @@ void *pv4_encode_commit(void *buffer, unsigned long *sizep)
 	index = dict_add_entry(commit_name_table, tz_val, in, end - in);
 	if (index < 0)
 		goto bad_dict;
-	out += encode_varint(index, out);
+	out += encode_varint(index + 1, out);
 	time = strtoul(end, &end, 10);
 	if (!end || end[0] != ' ' || end[6] != '\n')
 		goto bad_data;
@@ -561,7 +561,7 @@ void *pv4_encode_tree(void *_buffer, unsigned long *sizep,
 			free(buffer);
 			return NULL;
 		}
-		out += encode_varint(index << 1, out);
+		out += encode_varint((index + 1) << 1, out);
 		out += encode_sha1ref(name_entry.sha1, out);
 	}
 
diff --git a/packv4-parse.c b/packv4-parse.c
index 4c218d2..6db4ed3 100644
--- a/packv4-parse.c
+++ b/packv4-parse.c
@@ -125,11 +125,19 @@ const unsigned char *get_nameref(struct packed_git *p, const unsigned char **src
 		load_name_dict(p);
 
 	index = decode_varint(srcp);
-	if (index >= p->name_dict->nb_entries) {
+
+	if (!index) {
+		/* the entry data is inline */
+		const unsigned char *data = *srcp;
+		*srcp += 2 + strlen((const char *)*srcp + 2) + 1;
+		return data;
+	}
+
+	if (index - 1 >= p->name_dict->nb_entries) {
 		error("%s: index overflow", __func__);
 		return NULL;
 	}
-	return p->name_dict->data + p->name_dict->offsets[index];
+	return p->name_dict->data + p->name_dict->offsets[index - 1];
 }
 
 static void load_path_dict(struct packed_git *p)
@@ -151,16 +159,24 @@ static void load_path_dict(struct packed_git *p)
 	p->path_dict = paths;
 }
 
-const unsigned char *get_pathref(struct packed_git *p, unsigned int index)
+const unsigned char *get_pathref(struct packed_git *p, unsigned int index,
+				 const unsigned char **srcp)
 {
 	if (!p->path_dict)
 		load_path_dict(p);
 
-	if (index >= p->path_dict->nb_entries) {
+	if (!index) {
+		/* the entry data is inline */
+		const unsigned char *data = *srcp;
+		*srcp += 2 + strlen((const char *)*srcp + 2) + 1;
+		return data;
+	}
+
+	if (index - 1 >= p->path_dict->nb_entries) {
 		error("%s: index overflow", __func__);
 		return NULL;
 	}
-	return p->path_dict->data + p->path_dict->offsets[index];
+	return p->path_dict->data + p->path_dict->offsets[index - 1];
 }
 
 void *pv4_get_commit(struct packed_git *p, struct pack_window **w_curs,
@@ -296,7 +312,7 @@ static int decode_entries(struct packed_git *p, struct pack_window **w_curs,
 			unsigned mode;
 			int len;
 
-			path = get_pathref(p, what >> 1);
+			path = get_pathref(p, what >> 1, &scp);
 			sha1 = get_sha1ref(p, &scp);
 			if (!path || !sha1)
 				return -1;
-- 
1.8.4.38.g317e65b

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]