Skip to content

Commit c84a1f3

Browse files
jonathantanmygitster
authored andcommitted
sha1_file: refactor read_object
read_object() and sha1_object_info_extended() both implement mechanisms such as object replacement, retrying the packed store after failing to find the object in the packed store then the loose store, and being able to mark a packed object as bad and then retrying the whole process. Consolidating these mechanisms would be a great help to maintainability. Therefore, consolidate them by extending sha1_object_info_extended() to support the functionality needed, and then modifying read_object() to use sha1_object_info_extended(). Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 845b102 commit c84a1f3

File tree

2 files changed

+43
-42
lines changed

2 files changed

+43
-42
lines changed

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,7 @@ struct object_info {
18271827
off_t *disk_sizep;
18281828
unsigned char *delta_base_sha1;
18291829
struct strbuf *typename;
1830+
void **contentp;
18301831

18311832
/* Response */
18321833
enum {

sha1_file.c

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,19 +2005,6 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)
20052005
return parse_sha1_header_extended(hdr, &oi, 0);
20062006
}
20072007

2008-
static void *unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size, const unsigned char *sha1)
2009-
{
2010-
int ret;
2011-
git_zstream stream;
2012-
char hdr[8192];
2013-
2014-
ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
2015-
if (ret < Z_OK || (*type = parse_sha1_header(hdr, size)) < 0)
2016-
return NULL;
2017-
2018-
return unpack_sha1_rest(&stream, hdr, *size, sha1);
2019-
}
2020-
20212008
unsigned long get_size_from_delta(struct packed_git *p,
20222009
struct pack_window **w_curs,
20232010
off_t curpos)
@@ -2326,8 +2313,10 @@ static void *cache_or_unpack_entry(struct packed_git *p, off_t base_offset,
23262313
if (!ent)
23272314
return unpack_entry(p, base_offset, type, base_size);
23282315

2329-
*type = ent->type;
2330-
*base_size = ent->size;
2316+
if (type)
2317+
*type = ent->type;
2318+
if (base_size)
2319+
*base_size = ent->size;
23312320
return xmemdupz(ent->data, ent->size);
23322321
}
23332322

@@ -2388,9 +2377,16 @@ int packed_object_info(struct packed_git *p, off_t obj_offset,
23882377
* We always get the representation type, but only convert it to
23892378
* a "real" type later if the caller is interested.
23902379
*/
2391-
type = unpack_object_header(p, &w_curs, &curpos, &size);
2380+
if (oi->contentp) {
2381+
*oi->contentp = cache_or_unpack_entry(p, obj_offset, oi->sizep,
2382+
&type);
2383+
if (!*oi->contentp)
2384+
type = OBJ_BAD;
2385+
} else {
2386+
type = unpack_object_header(p, &w_curs, &curpos, &size);
2387+
}
23922388

2393-
if (oi->sizep) {
2389+
if (!oi->contentp && oi->sizep) {
23942390
if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
23952391
off_t tmp_pos = curpos;
23962392
off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
@@ -2679,8 +2675,10 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
26792675
free(external_base);
26802676
}
26812677

2682-
*final_type = type;
2683-
*final_size = size;
2678+
if (final_type)
2679+
*final_type = type;
2680+
if (final_size)
2681+
*final_size = size;
26842682

26852683
unuse_pack(&w_curs);
26862684

@@ -2914,6 +2912,7 @@ static int sha1_loose_object_info(const unsigned char *sha1,
29142912
git_zstream stream;
29152913
char hdr[32];
29162914
struct strbuf hdrbuf = STRBUF_INIT;
2915+
unsigned long size_scratch;
29172916

29182917
if (oi->delta_base_sha1)
29192918
hashclr(oi->delta_base_sha1);
@@ -2926,7 +2925,7 @@ static int sha1_loose_object_info(const unsigned char *sha1,
29262925
* return value implicitly indicates whether the
29272926
* object even exists.
29282927
*/
2929-
if (!oi->typep && !oi->typename && !oi->sizep) {
2928+
if (!oi->typep && !oi->typename && !oi->sizep && !oi->contentp) {
29302929
const char *path;
29312930
struct stat st;
29322931
if (stat_sha1_file(sha1, &st, &path) < 0)
@@ -2939,6 +2938,10 @@ static int sha1_loose_object_info(const unsigned char *sha1,
29392938
map = map_sha1_file(sha1, &mapsize);
29402939
if (!map)
29412940
return -1;
2941+
2942+
if (!oi->sizep)
2943+
oi->sizep = &size_scratch;
2944+
29422945
if (oi->disk_sizep)
29432946
*oi->disk_sizep = mapsize;
29442947
if ((flags & OBJECT_INFO_ALLOW_UNKNOWN_TYPE)) {
@@ -2956,10 +2959,18 @@ static int sha1_loose_object_info(const unsigned char *sha1,
29562959
sha1_to_hex(sha1));
29572960
} else if ((status = parse_sha1_header_extended(hdr, oi, flags)) < 0)
29582961
status = error("unable to parse %s header", sha1_to_hex(sha1));
2959-
git_inflate_end(&stream);
2962+
2963+
if (status >= 0 && oi->contentp)
2964+
*oi->contentp = unpack_sha1_rest(&stream, hdr,
2965+
*oi->sizep, sha1);
2966+
else
2967+
git_inflate_end(&stream);
2968+
29602969
munmap(map, mapsize);
29612970
if (status && oi->typep)
29622971
*oi->typep = status;
2972+
if (oi->sizep == &size_scratch)
2973+
oi->sizep = NULL;
29632974
strbuf_release(&hdrbuf);
29642975
return (status < 0) ? status : 0;
29652976
}
@@ -2985,6 +2996,8 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
29852996
hashclr(oi->delta_base_sha1);
29862997
if (oi->typename)
29872998
strbuf_addstr(oi->typename, typename(co->type));
2999+
if (oi->contentp)
3000+
*oi->contentp = xmemdupz(co->buf, co->size);
29883001
oi->whence = OI_CACHED;
29893002
return 0;
29903003
}
@@ -3078,28 +3091,15 @@ int pretend_sha1_file(void *buf, unsigned long len, enum object_type type,
30783091
static void *read_object(const unsigned char *sha1, enum object_type *type,
30793092
unsigned long *size)
30803093
{
3081-
unsigned long mapsize;
3082-
void *map, *buf;
3083-
struct cached_object *co;
3084-
3085-
co = find_cached_object(sha1);
3086-
if (co) {
3087-
*type = co->type;
3088-
*size = co->size;
3089-
return xmemdupz(co->buf, co->size);
3090-
}
3094+
struct object_info oi = OBJECT_INFO_INIT;
3095+
void *content;
3096+
oi.typep = type;
3097+
oi.sizep = size;
3098+
oi.contentp = &content;
30913099

3092-
buf = read_packed_sha1(sha1, type, size);
3093-
if (buf)
3094-
return buf;
3095-
map = map_sha1_file(sha1, &mapsize);
3096-
if (map) {
3097-
buf = unpack_sha1_file(map, mapsize, type, size, sha1);
3098-
munmap(map, mapsize);
3099-
return buf;
3100-
}
3101-
reprepare_packed_git();
3102-
return read_packed_sha1(sha1, type, size);
3100+
if (sha1_object_info_extended(sha1, &oi, 0) < 0)
3101+
return NULL;
3102+
return content;
31033103
}
31043104

31053105
/*

0 commit comments

Comments
 (0)