Skip to content

Commit aa46a0d

Browse files
telezhnayagitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e225517 commit aa46a0d

File tree

1 file changed

+87
-33
lines changed

1 file changed

+87
-33
lines changed

ref-filter.c

Lines changed: 87 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ struct refname_atom {
6161
int lstrip, rstrip;
6262
};
6363

64+
static struct expand_data {
65+
struct object_id oid;
66+
enum object_type type;
67+
unsigned long size;
68+
off_t disk_size;
69+
struct object_id delta_base_oid;
70+
void *content;
71+
72+
struct object_info info;
73+
} oi, oi_deref;
74+
6475
/*
6576
* An atom is a valid field atom listed below, possibly prefixed with
6677
* a "*" to denote deref_tag().
@@ -202,6 +213,30 @@ static int remote_ref_atom_parser(const struct ref_format *format, struct used_a
202213
return 0;
203214
}
204215

216+
static int objecttype_atom_parser(const struct ref_format *format, struct used_atom *atom,
217+
const char *arg, struct strbuf *err)
218+
{
219+
if (arg)
220+
return strbuf_addf_ret(err, -1, _("%%(objecttype) does not take arguments"));
221+
if (*atom->name == '*')
222+
oi_deref.info.typep = &oi_deref.type;
223+
else
224+
oi.info.typep = &oi.type;
225+
return 0;
226+
}
227+
228+
static int objectsize_atom_parser(const struct ref_format *format, struct used_atom *atom,
229+
const char *arg, struct strbuf *err)
230+
{
231+
if (arg)
232+
return strbuf_addf_ret(err, -1, _("%%(objectsize) does not take arguments"));
233+
if (*atom->name == '*')
234+
oi_deref.info.sizep = &oi_deref.size;
235+
else
236+
oi.info.sizep = &oi.size;
237+
return 0;
238+
}
239+
205240
static int body_atom_parser(const struct ref_format *format, struct used_atom *atom,
206241
const char *arg, struct strbuf *err)
207242
{
@@ -388,8 +423,8 @@ static struct {
388423
const char *arg, struct strbuf *err);
389424
} valid_atom[] = {
390425
{ "refname", SOURCE_NONE, FIELD_STR, refname_atom_parser },
391-
{ "objecttype", SOURCE_OTHER },
392-
{ "objectsize", SOURCE_OTHER, FIELD_ULONG },
426+
{ "objecttype", SOURCE_OTHER, FIELD_STR, objecttype_atom_parser },
427+
{ "objectsize", SOURCE_OTHER, FIELD_ULONG, objectsize_atom_parser },
393428
{ "objectname", SOURCE_OTHER, FIELD_STR, objectname_atom_parser },
394429
{ "tree", SOURCE_OBJ },
395430
{ "parent", SOURCE_OBJ },
@@ -502,6 +537,12 @@ static int parse_ref_filter_atom(const struct ref_format *format,
502537
used_atom[at].name = xmemdupz(atom, ep - atom);
503538
used_atom[at].type = valid_atom[i].cmp_type;
504539
used_atom[at].source = valid_atom[i].source;
540+
if (used_atom[at].source == SOURCE_OBJ) {
541+
if (*atom == '*')
542+
oi_deref.info.contentp = &oi_deref.content;
543+
else
544+
oi.info.contentp = &oi.content;
545+
}
505546
if (arg) {
506547
arg = used_atom[at].name + (arg - atom) + 1;
507548
if (!*arg) {
@@ -817,7 +858,7 @@ static int grab_objectname(const char *name, const struct object_id *oid,
817858
}
818859

819860
/* See grab_values */
820-
static void grab_common_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
861+
static void grab_common_values(struct atom_value *val, int deref, struct expand_data *oi)
821862
{
822863
int i;
823864

@@ -829,13 +870,13 @@ static void grab_common_values(struct atom_value *val, int deref, struct object
829870
if (deref)
830871
name++;
831872
if (!strcmp(name, "objecttype"))
832-
v->s = type_name(obj->type);
873+
v->s = type_name(oi->type);
833874
else if (!strcmp(name, "objectsize")) {
834-
v->value = sz;
835-
v->s = xstrfmt("%lu", sz);
875+
v->value = oi->size;
876+
v->s = xstrfmt("%lu", oi->size);
836877
}
837878
else if (deref)
838-
grab_objectname(name, &obj->oid, v, &used_atom[i]);
879+
grab_objectname(name, &oi->oid, v, &used_atom[i]);
839880
}
840881
}
841882

@@ -1194,7 +1235,6 @@ static void fill_missing_values(struct atom_value *val)
11941235
*/
11951236
static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
11961237
{
1197-
grab_common_values(val, deref, obj, buf, sz);
11981238
switch (obj->type) {
11991239
case OBJ_TAG:
12001240
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
14181458
return show_ref(&atom->u.refname, ref->refname);
14191459
}
14201460

1421-
static int get_object(struct ref_array_item *ref, const struct object_id *oid,
1422-
int deref, struct object **obj, struct strbuf *err)
1461+
static int get_object(struct ref_array_item *ref, int deref, struct object **obj,
1462+
struct expand_data *oi, struct strbuf *err)
14231463
{
14241464
/* parse_object_buffer() will set eaten to 0 if free() will be needed */
14251465
int eaten = 1;
1426-
int ret = 0;
1427-
unsigned long size;
1428-
enum object_type type;
1429-
void *buf = read_object_file(oid, &type, &size);
1430-
if (!buf)
1431-
ret = strbuf_addf_ret(err, -1, _("missing object %s for %s"),
1432-
oid_to_hex(oid), ref->refname);
1433-
else {
1434-
*obj = parse_object_buffer(oid, type, size, buf, &eaten);
1435-
if (!*obj)
1436-
ret = strbuf_addf_ret(err, -1, _("parse_object_buffer failed on %s for %s"),
1437-
oid_to_hex(oid), ref->refname);
1438-
else
1439-
grab_values(ref->value, deref, *obj, buf, size);
1466+
if (oi->info.contentp) {
1467+
/* We need to know that to use parse_object_buffer properly */
1468+
oi->info.sizep = &oi->size;
1469+
oi->info.typep = &oi->type;
14401470
}
1471+
if (oid_object_info_extended(the_repository, &oi->oid, &oi->info,
1472+
OBJECT_INFO_LOOKUP_REPLACE))
1473+
return strbuf_addf_ret(err, -1, _("missing object %s for %s"),
1474+
oid_to_hex(&oi->oid), ref->refname);
1475+
1476+
if (oi->info.contentp) {
1477+
*obj = parse_object_buffer(&oi->oid, oi->type, oi->size, oi->content, &eaten);
1478+
if (!obj) {
1479+
if (!eaten)
1480+
free(oi->content);
1481+
return strbuf_addf_ret(err, -1, _("parse_object_buffer failed on %s for %s"),
1482+
oid_to_hex(&oi->oid), ref->refname);
1483+
}
1484+
grab_values(ref->value, deref, *obj, oi->content, oi->size);
1485+
}
1486+
1487+
grab_common_values(ref->value, deref, oi);
14411488
if (!eaten)
1442-
free(buf);
1443-
return ret;
1489+
free(oi->content);
1490+
return 0;
14441491
}
14451492

14461493
/*
@@ -1450,7 +1497,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
14501497
{
14511498
struct object *obj;
14521499
int i;
1453-
const struct object_id *tagged;
1500+
struct object_info empty = OBJECT_INFO_INIT;
14541501

14551502
ref->value = xcalloc(used_atom_cnt, sizeof(struct atom_value));
14561503

@@ -1570,13 +1617,20 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
15701617

15711618
for (i = 0; i < used_atom_cnt; i++) {
15721619
struct atom_value *v = &ref->value[i];
1573-
if (v->s == NULL)
1574-
break;
1620+
if (v->s == NULL && used_atom[i].source == SOURCE_NONE)
1621+
return strbuf_addf_ret(err, -1, _("missing object %s for %s"),
1622+
oid_to_hex(&ref->objectname), ref->refname);
15751623
}
1576-
if (used_atom_cnt <= i)
1624+
1625+
if (need_tagged)
1626+
oi.info.contentp = &oi.content;
1627+
if (!memcmp(&oi.info, &empty, sizeof(empty)) &&
1628+
!memcmp(&oi_deref.info, &empty, sizeof(empty)))
15771629
return 0;
15781630

1579-
if (get_object(ref, &ref->objectname, 0, &obj, err))
1631+
1632+
oi.oid = ref->objectname;
1633+
if (get_object(ref, 0, &obj, &oi, err))
15801634
return -1;
15811635

15821636
/*
@@ -1590,15 +1644,15 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
15901644
* If it is a tag object, see if we use a value that derefs
15911645
* the object, and if we do grab the object it refers to.
15921646
*/
1593-
tagged = &((struct tag *)obj)->tagged->oid;
1647+
oi_deref.oid = ((struct tag *)obj)->tagged->oid;
15941648

15951649
/*
15961650
* NEEDSWORK: This derefs tag only once, which
15971651
* is good to deal with chains of trust, but
15981652
* is not consistent with what deref_tag() does
15991653
* which peels the onion to the core.
16001654
*/
1601-
return get_object(ref, tagged, 1, &obj, err);
1655+
return get_object(ref, 1, &obj, &oi_deref, err);
16021656
}
16031657

16041658
/*

0 commit comments

Comments
 (0)