From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH v3 3/6] new representation types in the packstream
Date: Thu, 1 Dec 2011 16:40:46 -0800 [thread overview]
Message-ID: <1322786449-25753-4-git-send-email-gitster@pobox.com> (raw)
In-Reply-To: <1322786449-25753-1-git-send-email-gitster@pobox.com>
In addition to four basic types (commit, tree, blob and tag), the pack
stream can encode a few other "representation" types, such as REF_DELTA
and OFS_DELTA. As we allocate 3 bits in the first byte for this purpose,
we do not have much room to add new representation types in place, but we
do have one value reserved for future expansion.
When encoding a new representation type, the early part of the in-pack
object header is encoded as if its type is OBJ_EXT (= 5) using exactly the
same way as before. That is, the lower 4-bit of the first byte is used for
the lowest 4-bit of the size information, the next 3-bit has the type
information, and the MSB says if the subsequent bytes encodes higher bits
for the size information.
An in-pack object header that records OBJ_EXT as the type is followed by
an integer in the same variable-length encoding as OFS_DELTA offset is
encoded. This value is the real type of the representation minus 8 (as we
do not need to use OBJ_EXT to encode types smaller than 8). Because we do
not foresee very many representation types, in practice we would have a
single byte with its MSB clear, to represent types 8-135.
The code does not type=8 and upwards for anything yet.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
cache.h | 4 +++-
pack-write.c | 23 +++++++++++++++++------
sha1_file.c | 11 +++++++++++
3 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/cache.h b/cache.h
index 4f20861..4a3b421 100644
--- a/cache.h
+++ b/cache.h
@@ -381,12 +381,14 @@ enum object_type {
OBJ_TREE = 2,
OBJ_BLOB = 3,
OBJ_TAG = 4,
- /* 5 for future expansion */
+ OBJ_EXT = 5,
OBJ_OFS_DELTA = 6,
OBJ_REF_DELTA = 7,
OBJ_ANY,
OBJ_MAX
};
+#define OBJ_LAST_BASE_TYPE OBJ_REF_DELTA
+#define OBJ_LAST_VALID_TYPE OBJ_REF_DELTA
static inline enum object_type object_type(unsigned int mode)
{
diff --git a/pack-write.c b/pack-write.c
index 5702cec..9309dd1 100644
--- a/pack-write.c
+++ b/pack-write.c
@@ -338,22 +338,33 @@ int encode_in_pack_varint(uintmax_t value, unsigned char *buf)
*/
int encode_in_pack_object_header(enum object_type type, uintmax_t size, unsigned char *hdr)
{
- int n = 1;
+ unsigned char *hdr_base;
unsigned char c;
+ enum object_type header_type;
- if (type < OBJ_COMMIT || type > OBJ_REF_DELTA)
+ if (type < OBJ_COMMIT || OBJ_LAST_VALID_TYPE < type)
die("bad type %d", type);
+ else if (OBJ_LAST_BASE_TYPE < type)
+ header_type = OBJ_EXT;
+ else
+ header_type = type;
- c = (type << 4) | (size & 15);
+ c = (header_type << 4) | (size & 15);
size >>= 4;
+ hdr_base = hdr;
while (size) {
*hdr++ = c | 0x80;
c = size & 0x7f;
size >>= 7;
- n++;
}
- *hdr = c;
- return n;
+ *hdr++ = c;
+ if (header_type != type) {
+ int sz;
+ type = type - (OBJ_LAST_BASE_TYPE + 1);
+ sz = encode_in_pack_varint(type, hdr);
+ hdr += sz;
+ }
+ return hdr - hdr_base;
}
struct sha1file *create_tmp_packfile(char **pack_tmp_name)
diff --git a/sha1_file.c b/sha1_file.c
index f066c2b..14902cc 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1275,6 +1275,17 @@ unsigned long unpack_object_header_buffer(const unsigned char *buf,
shift += 7;
}
*sizep = size;
+ if (*type == OBJ_EXT) {
+ const unsigned char *p = buf + used;
+ uintmax_t val = decode_in_pack_varint(&p);
+
+ if (p == buf + used && !val) {
+ error("bad extended object type");
+ return 0;
+ }
+ *type = val + (OBJ_LAST_BASE_TYPE + 1);
+ used = p - buf;
+ }
return used;
}
--
1.7.8.rc4.177.g4d64
next prev parent reply other threads:[~2011-12-02 0:41 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-01 0:27 [PATCH v2 0/5] Bulk Check-in Junio C Hamano
2011-12-01 0:27 ` [PATCH v2 1/5] write_pack_header(): a helper function Junio C Hamano
2011-12-01 0:27 ` [PATCH v2 2/5] create_tmp_packfile(): " Junio C Hamano
2011-12-01 0:27 ` [PATCH v2 3/5] finish_tmp_packfile(): " Junio C Hamano
2011-12-01 0:27 ` [PATCH v2 4/5] csum-file: introduce sha1file_checkpoint Junio C Hamano
2011-12-01 0:27 ` [PATCH v2 5/5] bulk-checkin: replace fast-import based implementation Junio C Hamano
2011-12-01 8:05 ` Nguyen Thai Ngoc Duy
2011-12-01 15:46 ` Junio C Hamano
2011-12-02 0:40 ` [PATCH v3 0/6] Bulk check-in Junio C Hamano
2011-12-02 0:40 ` [PATCH v3 1/6] bulk-checkin: replace fast-import based implementation Junio C Hamano
2011-12-02 0:40 ` [PATCH v3 2/6] varint-in-pack: refactor varint encoding/decoding Junio C Hamano
2011-12-02 0:40 ` Junio C Hamano [this message]
2011-12-02 0:40 ` [PATCH v3 4/6] bulk-checkin: allow the same data to be multiply hashed Junio C Hamano
2011-12-02 0:40 ` [PATCH v3 5/6] bulk-checkin: support chunked-object encoding Junio C Hamano
2011-12-02 0:40 ` [PATCH v3 6/6] chunked-object: fallback checkout codepaths Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1322786449-25753-4-git-send-email-gitster@pobox.com \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).