mirror of
https://github.com/git/git.git
synced 2024-11-24 18:33:43 +08:00
sha1_file: move delta base cache code up
In a subsequent patch, packed_object_info() will be modified to use the delta base cache, so move the relevant code to before packed_object_info(). Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
1f0c0d36c1
commit
845b102b99
220
sha1_file.c
220
sha1_file.c
@ -2239,116 +2239,6 @@ unwind:
|
||||
goto out;
|
||||
}
|
||||
|
||||
int packed_object_info(struct packed_git *p, off_t obj_offset,
|
||||
struct object_info *oi)
|
||||
{
|
||||
struct pack_window *w_curs = NULL;
|
||||
unsigned long size;
|
||||
off_t curpos = obj_offset;
|
||||
enum object_type type;
|
||||
|
||||
/*
|
||||
* We always get the representation type, but only convert it to
|
||||
* a "real" type later if the caller is interested.
|
||||
*/
|
||||
type = unpack_object_header(p, &w_curs, &curpos, &size);
|
||||
|
||||
if (oi->sizep) {
|
||||
if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
|
||||
off_t tmp_pos = curpos;
|
||||
off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
|
||||
type, obj_offset);
|
||||
if (!base_offset) {
|
||||
type = OBJ_BAD;
|
||||
goto out;
|
||||
}
|
||||
*oi->sizep = get_size_from_delta(p, &w_curs, tmp_pos);
|
||||
if (*oi->sizep == 0) {
|
||||
type = OBJ_BAD;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
*oi->sizep = size;
|
||||
}
|
||||
}
|
||||
|
||||
if (oi->disk_sizep) {
|
||||
struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
|
||||
*oi->disk_sizep = revidx[1].offset - obj_offset;
|
||||
}
|
||||
|
||||
if (oi->typep || oi->typename) {
|
||||
enum object_type ptot;
|
||||
ptot = packed_to_object_type(p, obj_offset, type, &w_curs,
|
||||
curpos);
|
||||
if (oi->typep)
|
||||
*oi->typep = ptot;
|
||||
if (oi->typename) {
|
||||
const char *tn = typename(ptot);
|
||||
if (tn)
|
||||
strbuf_addstr(oi->typename, tn);
|
||||
}
|
||||
if (ptot < 0) {
|
||||
type = OBJ_BAD;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (oi->delta_base_sha1) {
|
||||
if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
|
||||
const unsigned char *base;
|
||||
|
||||
base = get_delta_base_sha1(p, &w_curs, curpos,
|
||||
type, obj_offset);
|
||||
if (!base) {
|
||||
type = OBJ_BAD;
|
||||
goto out;
|
||||
}
|
||||
|
||||
hashcpy(oi->delta_base_sha1, base);
|
||||
} else
|
||||
hashclr(oi->delta_base_sha1);
|
||||
}
|
||||
|
||||
out:
|
||||
unuse_pack(&w_curs);
|
||||
return type;
|
||||
}
|
||||
|
||||
static void *unpack_compressed_entry(struct packed_git *p,
|
||||
struct pack_window **w_curs,
|
||||
off_t curpos,
|
||||
unsigned long size)
|
||||
{
|
||||
int st;
|
||||
git_zstream stream;
|
||||
unsigned char *buffer, *in;
|
||||
|
||||
buffer = xmallocz_gently(size);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
stream.next_out = buffer;
|
||||
stream.avail_out = size + 1;
|
||||
|
||||
git_inflate_init(&stream);
|
||||
do {
|
||||
in = use_pack(p, w_curs, curpos, &stream.avail_in);
|
||||
stream.next_in = in;
|
||||
st = git_inflate(&stream, Z_FINISH);
|
||||
if (!stream.avail_out)
|
||||
break; /* the payload is larger than it should be */
|
||||
curpos += stream.next_in - in;
|
||||
} while (st == Z_OK || st == Z_BUF_ERROR);
|
||||
git_inflate_end(&stream);
|
||||
if ((st != Z_STREAM_END) || stream.total_out != size) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static struct hashmap delta_base_cache;
|
||||
static size_t delta_base_cached;
|
||||
|
||||
@ -2486,6 +2376,116 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
|
||||
hashmap_add(&delta_base_cache, ent);
|
||||
}
|
||||
|
||||
int packed_object_info(struct packed_git *p, off_t obj_offset,
|
||||
struct object_info *oi)
|
||||
{
|
||||
struct pack_window *w_curs = NULL;
|
||||
unsigned long size;
|
||||
off_t curpos = obj_offset;
|
||||
enum object_type type;
|
||||
|
||||
/*
|
||||
* We always get the representation type, but only convert it to
|
||||
* a "real" type later if the caller is interested.
|
||||
*/
|
||||
type = unpack_object_header(p, &w_curs, &curpos, &size);
|
||||
|
||||
if (oi->sizep) {
|
||||
if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
|
||||
off_t tmp_pos = curpos;
|
||||
off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
|
||||
type, obj_offset);
|
||||
if (!base_offset) {
|
||||
type = OBJ_BAD;
|
||||
goto out;
|
||||
}
|
||||
*oi->sizep = get_size_from_delta(p, &w_curs, tmp_pos);
|
||||
if (*oi->sizep == 0) {
|
||||
type = OBJ_BAD;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
*oi->sizep = size;
|
||||
}
|
||||
}
|
||||
|
||||
if (oi->disk_sizep) {
|
||||
struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
|
||||
*oi->disk_sizep = revidx[1].offset - obj_offset;
|
||||
}
|
||||
|
||||
if (oi->typep || oi->typename) {
|
||||
enum object_type ptot;
|
||||
ptot = packed_to_object_type(p, obj_offset, type, &w_curs,
|
||||
curpos);
|
||||
if (oi->typep)
|
||||
*oi->typep = ptot;
|
||||
if (oi->typename) {
|
||||
const char *tn = typename(ptot);
|
||||
if (tn)
|
||||
strbuf_addstr(oi->typename, tn);
|
||||
}
|
||||
if (ptot < 0) {
|
||||
type = OBJ_BAD;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (oi->delta_base_sha1) {
|
||||
if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
|
||||
const unsigned char *base;
|
||||
|
||||
base = get_delta_base_sha1(p, &w_curs, curpos,
|
||||
type, obj_offset);
|
||||
if (!base) {
|
||||
type = OBJ_BAD;
|
||||
goto out;
|
||||
}
|
||||
|
||||
hashcpy(oi->delta_base_sha1, base);
|
||||
} else
|
||||
hashclr(oi->delta_base_sha1);
|
||||
}
|
||||
|
||||
out:
|
||||
unuse_pack(&w_curs);
|
||||
return type;
|
||||
}
|
||||
|
||||
static void *unpack_compressed_entry(struct packed_git *p,
|
||||
struct pack_window **w_curs,
|
||||
off_t curpos,
|
||||
unsigned long size)
|
||||
{
|
||||
int st;
|
||||
git_zstream stream;
|
||||
unsigned char *buffer, *in;
|
||||
|
||||
buffer = xmallocz_gently(size);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
stream.next_out = buffer;
|
||||
stream.avail_out = size + 1;
|
||||
|
||||
git_inflate_init(&stream);
|
||||
do {
|
||||
in = use_pack(p, w_curs, curpos, &stream.avail_in);
|
||||
stream.next_in = in;
|
||||
st = git_inflate(&stream, Z_FINISH);
|
||||
if (!stream.avail_out)
|
||||
break; /* the payload is larger than it should be */
|
||||
curpos += stream.next_in - in;
|
||||
} while (st == Z_OK || st == Z_BUF_ERROR);
|
||||
git_inflate_end(&stream);
|
||||
if ((st != Z_STREAM_END) || stream.total_out != size) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void *read_object(const unsigned char *sha1, enum object_type *type,
|
||||
unsigned long *size);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user