ref-filter: use oid_object_info() to get object
Use oid_object_info_extended() to get object info instead of read_object_file(). It will help to handle some requests faster (e.g., we do not need to parse whole object if we need to know %(objectsize)). It could also help us to add new atoms such as %(objectsize:disk) and %(deltabase). Signed-off-by: Olga Telezhnaia <olyatelezhnaya@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
e2255179f6
commit
aa46a0da30
120
ref-filter.c
120
ref-filter.c
@ -61,6 +61,17 @@ struct refname_atom {
|
||||
int lstrip, rstrip;
|
||||
};
|
||||
|
||||
static struct expand_data {
|
||||
struct object_id oid;
|
||||
enum object_type type;
|
||||
unsigned long size;
|
||||
off_t disk_size;
|
||||
struct object_id delta_base_oid;
|
||||
void *content;
|
||||
|
||||
struct object_info info;
|
||||
} oi, oi_deref;
|
||||
|
||||
/*
|
||||
* An atom is a valid field atom listed below, possibly prefixed with
|
||||
* a "*" to denote deref_tag().
|
||||
@ -202,6 +213,30 @@ static int remote_ref_atom_parser(const struct ref_format *format, struct used_a
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int objecttype_atom_parser(const struct ref_format *format, struct used_atom *atom,
|
||||
const char *arg, struct strbuf *err)
|
||||
{
|
||||
if (arg)
|
||||
return strbuf_addf_ret(err, -1, _("%%(objecttype) does not take arguments"));
|
||||
if (*atom->name == '*')
|
||||
oi_deref.info.typep = &oi_deref.type;
|
||||
else
|
||||
oi.info.typep = &oi.type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int objectsize_atom_parser(const struct ref_format *format, struct used_atom *atom,
|
||||
const char *arg, struct strbuf *err)
|
||||
{
|
||||
if (arg)
|
||||
return strbuf_addf_ret(err, -1, _("%%(objectsize) does not take arguments"));
|
||||
if (*atom->name == '*')
|
||||
oi_deref.info.sizep = &oi_deref.size;
|
||||
else
|
||||
oi.info.sizep = &oi.size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int body_atom_parser(const struct ref_format *format, struct used_atom *atom,
|
||||
const char *arg, struct strbuf *err)
|
||||
{
|
||||
@ -388,8 +423,8 @@ static struct {
|
||||
const char *arg, struct strbuf *err);
|
||||
} valid_atom[] = {
|
||||
{ "refname", SOURCE_NONE, FIELD_STR, refname_atom_parser },
|
||||
{ "objecttype", SOURCE_OTHER },
|
||||
{ "objectsize", SOURCE_OTHER, FIELD_ULONG },
|
||||
{ "objecttype", SOURCE_OTHER, FIELD_STR, objecttype_atom_parser },
|
||||
{ "objectsize", SOURCE_OTHER, FIELD_ULONG, objectsize_atom_parser },
|
||||
{ "objectname", SOURCE_OTHER, FIELD_STR, objectname_atom_parser },
|
||||
{ "tree", SOURCE_OBJ },
|
||||
{ "parent", SOURCE_OBJ },
|
||||
@ -502,6 +537,12 @@ static int parse_ref_filter_atom(const struct ref_format *format,
|
||||
used_atom[at].name = xmemdupz(atom, ep - atom);
|
||||
used_atom[at].type = valid_atom[i].cmp_type;
|
||||
used_atom[at].source = valid_atom[i].source;
|
||||
if (used_atom[at].source == SOURCE_OBJ) {
|
||||
if (*atom == '*')
|
||||
oi_deref.info.contentp = &oi_deref.content;
|
||||
else
|
||||
oi.info.contentp = &oi.content;
|
||||
}
|
||||
if (arg) {
|
||||
arg = used_atom[at].name + (arg - atom) + 1;
|
||||
if (!*arg) {
|
||||
@ -817,7 +858,7 @@ static int grab_objectname(const char *name, const struct object_id *oid,
|
||||
}
|
||||
|
||||
/* See grab_values */
|
||||
static void grab_common_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
|
||||
static void grab_common_values(struct atom_value *val, int deref, struct expand_data *oi)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -829,13 +870,13 @@ static void grab_common_values(struct atom_value *val, int deref, struct object
|
||||
if (deref)
|
||||
name++;
|
||||
if (!strcmp(name, "objecttype"))
|
||||
v->s = type_name(obj->type);
|
||||
v->s = type_name(oi->type);
|
||||
else if (!strcmp(name, "objectsize")) {
|
||||
v->value = sz;
|
||||
v->s = xstrfmt("%lu", sz);
|
||||
v->value = oi->size;
|
||||
v->s = xstrfmt("%lu", oi->size);
|
||||
}
|
||||
else if (deref)
|
||||
grab_objectname(name, &obj->oid, v, &used_atom[i]);
|
||||
grab_objectname(name, &oi->oid, v, &used_atom[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1194,7 +1235,6 @@ static void fill_missing_values(struct atom_value *val)
|
||||
*/
|
||||
static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
|
||||
{
|
||||
grab_common_values(val, deref, obj, buf, sz);
|
||||
switch (obj->type) {
|
||||
case OBJ_TAG:
|
||||
grab_tag_values(val, deref, obj, buf, sz);
|
||||
@ -1418,29 +1458,36 @@ static const char *get_refname(struct used_atom *atom, struct ref_array_item *re
|
||||
return show_ref(&atom->u.refname, ref->refname);
|
||||
}
|
||||
|
||||
static int get_object(struct ref_array_item *ref, const struct object_id *oid,
|
||||
int deref, struct object **obj, struct strbuf *err)
|
||||
static int get_object(struct ref_array_item *ref, int deref, struct object **obj,
|
||||
struct expand_data *oi, struct strbuf *err)
|
||||
{
|
||||
/* parse_object_buffer() will set eaten to 0 if free() will be needed */
|
||||
int eaten = 1;
|
||||
int ret = 0;
|
||||
unsigned long size;
|
||||
enum object_type type;
|
||||
void *buf = read_object_file(oid, &type, &size);
|
||||
if (!buf)
|
||||
ret = strbuf_addf_ret(err, -1, _("missing object %s for %s"),
|
||||
oid_to_hex(oid), ref->refname);
|
||||
else {
|
||||
*obj = parse_object_buffer(oid, type, size, buf, &eaten);
|
||||
if (!*obj)
|
||||
ret = strbuf_addf_ret(err, -1, _("parse_object_buffer failed on %s for %s"),
|
||||
oid_to_hex(oid), ref->refname);
|
||||
else
|
||||
grab_values(ref->value, deref, *obj, buf, size);
|
||||
if (oi->info.contentp) {
|
||||
/* We need to know that to use parse_object_buffer properly */
|
||||
oi->info.sizep = &oi->size;
|
||||
oi->info.typep = &oi->type;
|
||||
}
|
||||
if (oid_object_info_extended(the_repository, &oi->oid, &oi->info,
|
||||
OBJECT_INFO_LOOKUP_REPLACE))
|
||||
return strbuf_addf_ret(err, -1, _("missing object %s for %s"),
|
||||
oid_to_hex(&oi->oid), ref->refname);
|
||||
|
||||
if (oi->info.contentp) {
|
||||
*obj = parse_object_buffer(&oi->oid, oi->type, oi->size, oi->content, &eaten);
|
||||
if (!obj) {
|
||||
if (!eaten)
|
||||
free(oi->content);
|
||||
return strbuf_addf_ret(err, -1, _("parse_object_buffer failed on %s for %s"),
|
||||
oid_to_hex(&oi->oid), ref->refname);
|
||||
}
|
||||
grab_values(ref->value, deref, *obj, oi->content, oi->size);
|
||||
}
|
||||
|
||||
grab_common_values(ref->value, deref, oi);
|
||||
if (!eaten)
|
||||
free(buf);
|
||||
return ret;
|
||||
free(oi->content);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1450,7 +1497,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
|
||||
{
|
||||
struct object *obj;
|
||||
int i;
|
||||
const struct object_id *tagged;
|
||||
struct object_info empty = OBJECT_INFO_INIT;
|
||||
|
||||
ref->value = xcalloc(used_atom_cnt, sizeof(struct atom_value));
|
||||
|
||||
@ -1570,13 +1617,20 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
|
||||
|
||||
for (i = 0; i < used_atom_cnt; i++) {
|
||||
struct atom_value *v = &ref->value[i];
|
||||
if (v->s == NULL)
|
||||
break;
|
||||
if (v->s == NULL && used_atom[i].source == SOURCE_NONE)
|
||||
return strbuf_addf_ret(err, -1, _("missing object %s for %s"),
|
||||
oid_to_hex(&ref->objectname), ref->refname);
|
||||
}
|
||||
if (used_atom_cnt <= i)
|
||||
|
||||
if (need_tagged)
|
||||
oi.info.contentp = &oi.content;
|
||||
if (!memcmp(&oi.info, &empty, sizeof(empty)) &&
|
||||
!memcmp(&oi_deref.info, &empty, sizeof(empty)))
|
||||
return 0;
|
||||
|
||||
if (get_object(ref, &ref->objectname, 0, &obj, err))
|
||||
|
||||
oi.oid = ref->objectname;
|
||||
if (get_object(ref, 0, &obj, &oi, err))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
@ -1590,7 +1644,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
|
||||
* If it is a tag object, see if we use a value that derefs
|
||||
* the object, and if we do grab the object it refers to.
|
||||
*/
|
||||
tagged = &((struct tag *)obj)->tagged->oid;
|
||||
oi_deref.oid = ((struct tag *)obj)->tagged->oid;
|
||||
|
||||
/*
|
||||
* NEEDSWORK: This derefs tag only once, which
|
||||
@ -1598,7 +1652,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
|
||||
* is not consistent with what deref_tag() does
|
||||
* which peels the onion to the core.
|
||||
*/
|
||||
return get_object(ref, tagged, 1, &obj, err);
|
||||
return get_object(ref, 1, &obj, &oi_deref, err);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user