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>
Olga Telezhnaya committed
Jul 17, 2018 at 08:22 UTC
aa46a0da309cb60c056d712cd19e7fd8cf5b0cab
1 file changed
+87
-33
ref-filter.c
+87
-33
@@ -61,6 +61,17 @@ struct refname_atom {
61
int lstrip, rstrip;
62
};
63
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
+
75
/*
76
* An atom is a valid field atom listed below, possibly prefixed with
77
* a "*" to denote deref_tag().
@@ -202,6 +213,30 @@ static int remote_ref_atom_parser(const struct ref_format *format, struct used_a
213
return 0;
214
}
215
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
+
240
static int body_atom_parser(const struct ref_format *format, struct used_atom *atom,
241
const char *arg, struct strbuf *err)
242
{
@@ -388,8 +423,8 @@ static struct {
423
const char *arg, struct strbuf *err);
424
} valid_atom[] = {
425
{ "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 },
428
{ "objectname", SOURCE_OTHER, FIELD_STR, objectname_atom_parser },
429
{ "tree", SOURCE_OBJ },
430
{ "parent", SOURCE_OBJ },
@@ -502,6 +537,12 @@ static int parse_ref_filter_atom(const struct ref_format *format,
537
used_atom[at].name = xmemdupz(atom, ep - atom);
538
used_atom[at].type = valid_atom[i].cmp_type;
539
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
+ }
546
if (arg) {
547
arg = used_atom[at].name + (arg - atom) + 1;
548
if (!*arg) {
@@ -817,7 +858,7 @@ static int grab_objectname(const char *name, const struct object_id *oid,
858
}
859
860
/* 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)
862
{
863
int i;
864
@@ -829,13 +870,13 @@ static void grab_common_values(struct atom_value *val, int deref, struct object
870
if (deref)
871
name++;
872
if (!strcmp(name, "objecttype"))
832
- v->s = type_name(obj->type);
873
+ v->s = type_name(oi->type);
874
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);
877
}
878
else if (deref)
838
- grab_objectname(name, &obj->oid, v, &used_atom[i]);
879
+ grab_objectname(name, &oi->oid, v, &used_atom[i]);
880
}
881
}
882
@@ -1194,7 +1235,6 @@ static void fill_missing_values(struct atom_value *val)
1235
*/
1236
static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
1237
{
1197
- grab_common_values(val, deref, obj, buf, sz);
1238
switch (obj->type) {
1239
case OBJ_TAG:
1240
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
1458
return show_ref(&atom->u.refname, ref->refname);
1459
}
1460
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)
1463
{
1464
/* parse_object_buffer() will set eaten to 0 if free() will be needed */
1465
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;
1470
}
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);
1488
if (!eaten)
1442
- free(buf);
1443
- return ret;
1489
+ free(oi->content);
1490
+ return 0;
1491
}
1492
1493
/*
@@ -1450,7 +1497,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1497
{
1498
struct object *obj;
1499
int i;
1453
- const struct object_id *tagged;
1500
+ struct object_info empty = OBJECT_INFO_INIT;
1501
1502
ref->value = xcalloc(used_atom_cnt, sizeof(struct atom_value));
1503
@@ -1570,13 +1617,20 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1617
1618
for (i = 0; i < used_atom_cnt; i++) {
1619
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);
1623
}
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)))
1629
return 0;
1630
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))
1634
return -1;
1635
1636
/*
@@ -1590,7 +1644,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1644
* If it is a tag object, see if we use a value that derefs
1645
* the object, and if we do grab the object it refers to.
1646
*/
1593
- tagged = &((struct tag *)obj)->tagged->oid;
1647
+ oi_deref.oid = ((struct tag *)obj)->tagged->oid;
1648
1649
/*
1650
* NEEDSWORK: This derefs tag only once, which
@@ -1598,7 +1652,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1652
* is not consistent with what deref_tag() does
1653
* which peels the onion to the core.
1654
*/
1601
- return get_object(ref, tagged, 1, &obj, err);
1655
+ return get_object(ref, 1, &obj, &oi_deref, err);
1656
}
1657
1658
/*