зеркало из https://github.com/microsoft/git.git
Merge branch 'ng/pack-objects-cleanup'
By Nguyễn Thái Ngọc Duy * ng/pack-objects-cleanup: pack-objects: refactor write_object() into helper functions pack-objects, streaming: turn "xx >= big_file_threshold" to ".. > .."
This commit is contained in:
Коммит
32bd3a514b
|
@ -200,64 +200,15 @@ static void copy_pack_data(struct sha1file *f,
|
|||
}
|
||||
|
||||
/* Return 0 if we will bust the pack-size limit */
|
||||
static unsigned long write_object(struct sha1file *f,
|
||||
struct object_entry *entry,
|
||||
off_t write_offset)
|
||||
static unsigned long write_no_reuse_object(struct sha1file *f, struct object_entry *entry,
|
||||
unsigned long limit, int usable_delta)
|
||||
{
|
||||
unsigned long size, limit, datalen;
|
||||
void *buf;
|
||||
unsigned long size, datalen;
|
||||
unsigned char header[10], dheader[10];
|
||||
unsigned hdrlen;
|
||||
enum object_type type;
|
||||
int usable_delta, to_reuse;
|
||||
void *buf;
|
||||
|
||||
if (!pack_to_stdout)
|
||||
crc32_begin(f);
|
||||
|
||||
type = entry->type;
|
||||
|
||||
/* apply size limit if limited packsize and not first object */
|
||||
if (!pack_size_limit || !nr_written)
|
||||
limit = 0;
|
||||
else if (pack_size_limit <= write_offset)
|
||||
/*
|
||||
* the earlier object did not fit the limit; avoid
|
||||
* mistaking this with unlimited (i.e. limit = 0).
|
||||
*/
|
||||
limit = 1;
|
||||
else
|
||||
limit = pack_size_limit - write_offset;
|
||||
|
||||
if (!entry->delta)
|
||||
usable_delta = 0; /* no delta */
|
||||
else if (!pack_size_limit)
|
||||
usable_delta = 1; /* unlimited packfile */
|
||||
else if (entry->delta->idx.offset == (off_t)-1)
|
||||
usable_delta = 0; /* base was written to another pack */
|
||||
else if (entry->delta->idx.offset)
|
||||
usable_delta = 1; /* base already exists in this pack */
|
||||
else
|
||||
usable_delta = 0; /* base could end up in another pack */
|
||||
|
||||
if (!reuse_object)
|
||||
to_reuse = 0; /* explicit */
|
||||
else if (!entry->in_pack)
|
||||
to_reuse = 0; /* can't reuse what we don't have */
|
||||
else if (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA)
|
||||
/* check_object() decided it for us ... */
|
||||
to_reuse = usable_delta;
|
||||
/* ... but pack split may override that */
|
||||
else if (type != entry->in_pack_type)
|
||||
to_reuse = 0; /* pack has delta which is unusable */
|
||||
else if (entry->delta)
|
||||
to_reuse = 0; /* we want to pack afresh */
|
||||
else
|
||||
to_reuse = 1; /* we have it in-pack undeltified,
|
||||
* and we do not need to deltify it.
|
||||
*/
|
||||
|
||||
if (!to_reuse) {
|
||||
no_reuse:
|
||||
if (!usable_delta) {
|
||||
buf = read_sha1_file(entry->idx.sha1, &type, &size);
|
||||
if (!buf)
|
||||
|
@ -332,12 +283,22 @@ static unsigned long write_object(struct sha1file *f,
|
|||
}
|
||||
sha1write(f, buf, datalen);
|
||||
free(buf);
|
||||
}
|
||||
else {
|
||||
|
||||
return hdrlen + datalen;
|
||||
}
|
||||
|
||||
/* Return 0 if we will bust the pack-size limit */
|
||||
static unsigned long write_reuse_object(struct sha1file *f, struct object_entry *entry,
|
||||
unsigned long limit, int usable_delta)
|
||||
{
|
||||
struct packed_git *p = entry->in_pack;
|
||||
struct pack_window *w_curs = NULL;
|
||||
struct revindex_entry *revidx;
|
||||
off_t offset;
|
||||
enum object_type type = entry->type;
|
||||
unsigned long datalen;
|
||||
unsigned char header[10], dheader[10];
|
||||
unsigned hdrlen;
|
||||
|
||||
if (entry->delta)
|
||||
type = (allow_ofs_delta && entry->delta->idx.offset) ?
|
||||
|
@ -351,16 +312,17 @@ static unsigned long write_object(struct sha1file *f,
|
|||
check_pack_crc(p, &w_curs, offset, datalen, revidx->nr)) {
|
||||
error("bad packed object CRC for %s", sha1_to_hex(entry->idx.sha1));
|
||||
unuse_pack(&w_curs);
|
||||
goto no_reuse;
|
||||
return write_no_reuse_object(f, entry, limit, usable_delta);
|
||||
}
|
||||
|
||||
offset += entry->in_pack_header_size;
|
||||
datalen -= entry->in_pack_header_size;
|
||||
|
||||
if (!pack_to_stdout && p->index_version == 1 &&
|
||||
check_pack_inflate(p, &w_curs, offset, datalen, entry->size)) {
|
||||
error("corrupt packed object for %s", sha1_to_hex(entry->idx.sha1));
|
||||
unuse_pack(&w_curs);
|
||||
goto no_reuse;
|
||||
return write_no_reuse_object(f, entry, limit, usable_delta);
|
||||
}
|
||||
|
||||
if (type == OBJ_OFS_DELTA) {
|
||||
|
@ -396,13 +358,73 @@ static unsigned long write_object(struct sha1file *f,
|
|||
copy_pack_data(f, p, &w_curs, offset, datalen);
|
||||
unuse_pack(&w_curs);
|
||||
reused++;
|
||||
}
|
||||
return hdrlen + datalen;
|
||||
}
|
||||
|
||||
/* Return 0 if we will bust the pack-size limit */
|
||||
static unsigned long write_object(struct sha1file *f,
|
||||
struct object_entry *entry,
|
||||
off_t write_offset)
|
||||
{
|
||||
unsigned long limit, len;
|
||||
int usable_delta, to_reuse;
|
||||
|
||||
if (!pack_to_stdout)
|
||||
crc32_begin(f);
|
||||
|
||||
/* apply size limit if limited packsize and not first object */
|
||||
if (!pack_size_limit || !nr_written)
|
||||
limit = 0;
|
||||
else if (pack_size_limit <= write_offset)
|
||||
/*
|
||||
* the earlier object did not fit the limit; avoid
|
||||
* mistaking this with unlimited (i.e. limit = 0).
|
||||
*/
|
||||
limit = 1;
|
||||
else
|
||||
limit = pack_size_limit - write_offset;
|
||||
|
||||
if (!entry->delta)
|
||||
usable_delta = 0; /* no delta */
|
||||
else if (!pack_size_limit)
|
||||
usable_delta = 1; /* unlimited packfile */
|
||||
else if (entry->delta->idx.offset == (off_t)-1)
|
||||
usable_delta = 0; /* base was written to another pack */
|
||||
else if (entry->delta->idx.offset)
|
||||
usable_delta = 1; /* base already exists in this pack */
|
||||
else
|
||||
usable_delta = 0; /* base could end up in another pack */
|
||||
|
||||
if (!reuse_object)
|
||||
to_reuse = 0; /* explicit */
|
||||
else if (!entry->in_pack)
|
||||
to_reuse = 0; /* can't reuse what we don't have */
|
||||
else if (entry->type == OBJ_REF_DELTA || entry->type == OBJ_OFS_DELTA)
|
||||
/* check_object() decided it for us ... */
|
||||
to_reuse = usable_delta;
|
||||
/* ... but pack split may override that */
|
||||
else if (entry->type != entry->in_pack_type)
|
||||
to_reuse = 0; /* pack has delta which is unusable */
|
||||
else if (entry->delta)
|
||||
to_reuse = 0; /* we want to pack afresh */
|
||||
else
|
||||
to_reuse = 1; /* we have it in-pack undeltified,
|
||||
* and we do not need to deltify it.
|
||||
*/
|
||||
|
||||
if (!to_reuse)
|
||||
len = write_no_reuse_object(f, entry, limit, usable_delta);
|
||||
else
|
||||
len = write_reuse_object(f, entry, limit, usable_delta);
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if (usable_delta)
|
||||
written_delta++;
|
||||
written++;
|
||||
if (!pack_to_stdout)
|
||||
entry->idx.crc32 = crc32_end(f);
|
||||
return hdrlen + datalen;
|
||||
return len;
|
||||
}
|
||||
|
||||
enum write_one_status {
|
||||
|
@ -1327,7 +1349,7 @@ static void get_object_details(void)
|
|||
for (i = 0; i < nr_objects; i++) {
|
||||
struct object_entry *entry = sorted_by_offset[i];
|
||||
check_object(entry);
|
||||
if (big_file_threshold <= entry->size)
|
||||
if (big_file_threshold < entry->size)
|
||||
entry->no_try_delta = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ static enum input_source istream_source(const unsigned char *sha1,
|
|||
case OI_LOOSE:
|
||||
return loose;
|
||||
case OI_PACKED:
|
||||
if (!oi->u.packed.is_delta && big_file_threshold <= size)
|
||||
if (!oi->u.packed.is_delta && big_file_threshold < size)
|
||||
return pack_non_delta;
|
||||
/* fallthru */
|
||||
default:
|
||||
|
|
Загрузка…
Ссылка в новой задаче