summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2011-12-01 16:07:57 -0800
committerJunio C Hamano <gitster@pobox.com>2011-12-01 16:07:57 -0800
commit5ef0079864f59c87ad67a580cbb868f02f16ffc5 (patch)
treebff44943dcc8646b8ce581c91d9c1cc8531c3988
parent5724b041a69cd25a2f8febe92ad6c31fbfaff953 (diff)
downloadgit-jc/split-blob.tar.gz
WIP (streaming chunked)jc/split-blob
-rw-r--r--cache.h3
-rw-r--r--sha1_file.c3
-rw-r--r--streaming.c50
3 files changed, 54 insertions, 2 deletions
diff --git a/cache.h b/cache.h
index 374f712584..6db9f5f1f9 100644
--- a/cache.h
+++ b/cache.h
@@ -1097,7 +1097,8 @@ struct object_info {
struct {
struct packed_git *pack;
off_t offset;
- unsigned int is_delta;
+ unsigned int is_delta:1;
+ unsigned int is_chunked:1;
} packed;
} u;
};
diff --git a/sha1_file.c b/sha1_file.c
index 7355716ec6..07e743804f 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2196,6 +2196,9 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi)
oi->u.packed.pack = e.p;
oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA ||
rtype == OBJ_OFS_DELTA);
+ oi->u.packed.is_chunked =
+ (OBJ_CHUNKED_BLOB <= rtype &&
+ rtype <= OBJ_CHUNKED_BLOB);
}
return status;
diff --git a/streaming.c b/streaming.c
index 71072e1b1d..d258e70f74 100644
--- a/streaming.c
+++ b/streaming.c
@@ -8,7 +8,8 @@ enum input_source {
stream_error = -1,
incore = 0,
loose = 1,
- pack_non_delta = 2
+ pack_non_delta = 2,
+ pack_chunked = 3,
};
typedef int (*open_istream_fn)(struct git_istream *,
@@ -41,6 +42,7 @@ struct stream_vtbl {
static open_method_decl(incore);
static open_method_decl(loose);
static open_method_decl(pack_non_delta);
+static open_method_decl(pack_chunked);
static struct git_istream *attach_stream_filter(struct git_istream *st,
struct stream_filter *filter);
@@ -49,6 +51,7 @@ static open_istream_fn open_istream_tbl[] = {
open_istream_incore,
open_istream_loose,
open_istream_pack_non_delta,
+ open_istream_pack_chunked,
};
#define FILTER_BUFFER (1024*16)
@@ -88,6 +91,9 @@ struct git_istream {
off_t pos;
} in_pack;
+ struct {
+ } chunked;
+
struct filtered_istream filtered;
} u;
};
@@ -121,6 +127,8 @@ static enum input_source istream_source(const unsigned char *sha1,
case OI_LOOSE:
return loose;
case OI_PACKED:
+ if (oi->u.packed.is_chunked)
+ return pack_chunked;
if (!oi->u.packed.is_delta && big_file_threshold <= size)
return pack_non_delta;
/* fallthru */
@@ -452,6 +460,46 @@ static open_method_decl(pack_non_delta)
/*****************************************************************
*
+ * Chunked packed object stream
+ *
+ *****************************************************************/
+
+static read_method_decl(pack_chunked)
+{
+}
+
+static close_method_decl(pack_chunked)
+{
+}
+
+static struct stream_vtbl pack_chunked_vtbl = {
+ close_istream_pack_chunked,
+ read_istream_pack_chunked,
+};
+
+static open_method_decl(pack_chunked)
+{
+ struct pack_window *window;
+ enum object_type in_pack_type;
+
+ st->u.in_pack.pack = oi->u.packed.pack;
+ st->u.in_pack.pos = oi->u.packed.offset;
+ window = NULL;
+
+ in_pack_type = unpack_object_header(st->u.in_pack.pack,
+ &window,
+ &st->u.in_pack.pos,
+ &st->size);
+ unuse_pack(&window);
+
+ st->z_state = z_unused;
+ st->vtbl = &pack_chunked_vtbl;
+ return 0;
+}
+
+
+/*****************************************************************
+ *
* In-core stream
*
*****************************************************************/