fsck: use oids rather than objects for object_name API
We don't actually care about having object structs; we only need to look up decorations by oid. Let's accept this more limited form, which will give our callers more flexibility. Note that the decoration API we rely on uses object structs itself (even though it only looks at their oids). We can solve this by switching to a kh_oid_map (we could also use the hashmap oidmap, but it's more awkward for the simple case of just storing a void pointer). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Oct 18, 2019 at 00:57 UTC
733902905d4db54612fef9755bb31fd35a89e76c
3 files changed
+45
-37
builtin/fsck.c
+6
-6
@@ -52,7 +52,7 @@ static int name_objects;
52
53
static const char *describe_object(struct object *obj)
54
{
55
- return fsck_describe_object(&fsck_walk_options, obj);
55
+ return fsck_describe_object(&fsck_walk_options, &obj->oid);
56
}
57
58
static const char *printable_type(struct object *obj)
@@ -483,7 +483,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
483
obj = lookup_object(the_repository, oid);
484
if (obj && (obj->flags & HAS_OBJ)) {
485
if (timestamp)
486
- fsck_put_object_name(&fsck_walk_options, obj,
486
+ fsck_put_object_name(&fsck_walk_options, oid,
487
"%s@{%"PRItime"}",
488
refname, timestamp);
489
obj->flags |= USED;
@@ -550,7 +550,7 @@ static int fsck_handle_ref(const char *refname, const struct object_id *oid,
550
default_refs++;
551
obj->flags |= USED;
552
fsck_put_object_name(&fsck_walk_options,
553
- obj, "%s", refname);
553
+ oid, "%s", refname);
554
mark_object_reachable(obj);
555
556
return 0;
@@ -724,7 +724,7 @@ static int fsck_cache_tree(struct cache_tree *it)
724
return 1;
725
}
726
obj->flags |= USED;
727
- fsck_put_object_name(&fsck_walk_options, obj, ":");
727
+ fsck_put_object_name(&fsck_walk_options, &it->oid, ":");
728
mark_object_reachable(obj);
729
if (obj->type != OBJ_TREE)
730
err |= objerror(obj, _("non-tree in cache-tree"));
@@ -869,7 +869,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
869
}
870
871
obj->flags |= USED;
872
- fsck_put_object_name(&fsck_walk_options, obj,
872
+ fsck_put_object_name(&fsck_walk_options, &oid,
873
"%s", arg);
874
mark_object_reachable(obj);
875
continue;
@@ -906,7 +906,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
906
continue;
907
obj = &blob->object;
908
obj->flags |= USED;
909
- fsck_put_object_name(&fsck_walk_options, obj,
909
+ fsck_put_object_name(&fsck_walk_options, &obj->oid,
910
":%s", active_cache[i]->name);
911
mark_object_reachable(obj);
912
}
fsck.c
+34
-27
@@ -315,48 +315,56 @@ static int report(struct fsck_options *options, struct object *object,
315
void fsck_enable_object_names(struct fsck_options *options)
316
{
317
if (!options->object_names)
318
- options->object_names = xcalloc(1, sizeof(struct decoration));
318
+ options->object_names = kh_init_oid_map();
319
}
320
321
-const char *fsck_get_object_name(struct fsck_options *options, struct object *obj)
321
+const char *fsck_get_object_name(struct fsck_options *options,
322
+ const struct object_id *oid)
323
{
324
+ khiter_t pos;
325
if (!options->object_names)
326
return NULL;
325
- return lookup_decoration(options->object_names, obj);
327
+ pos = kh_get_oid_map(options->object_names, *oid);
328
+ if (pos >= kh_end(options->object_names))
329
+ return NULL;
330
+ return kh_value(options->object_names, pos);
331
}
332
328
-void fsck_put_object_name(struct fsck_options *options, struct object *obj,
333
+void fsck_put_object_name(struct fsck_options *options,
334
+ const struct object_id *oid,
335
const char *fmt, ...)
336
{
337
va_list ap;
338
struct strbuf buf = STRBUF_INIT;
333
- char *existing;
339
+ khiter_t pos;
340
+ int hashret;
341
342
if (!options->object_names)
343
return;
337
- existing = lookup_decoration(options->object_names, obj);
338
- if (existing)
344
+
345
+ pos = kh_put_oid_map(options->object_names, *oid, &hashret);
346
+ if (!hashret)
347
return;
348
va_start(ap, fmt);
349
strbuf_vaddf(&buf, fmt, ap);
342
- add_decoration(options->object_names, obj, strbuf_detach(&buf, NULL));
350
+ kh_value(options->object_names, pos) = strbuf_detach(&buf, NULL);
351
va_end(ap);
352
}
353
354
const char *fsck_describe_object(struct fsck_options *options,
347
- struct object *obj)
355
+ const struct object_id *oid)
356
{
357
static struct strbuf bufs[] = {
358
STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
359
};
360
static int b = 0;
361
struct strbuf *buf;
354
- const char *name = fsck_get_object_name(options, obj);
362
+ const char *name = fsck_get_object_name(options, oid);
363
364
buf = bufs + b;
365
b = (b + 1) % ARRAY_SIZE(bufs);
366
strbuf_reset(buf);
359
- strbuf_addstr(buf, oid_to_hex(&obj->oid));
367
+ strbuf_addstr(buf, oid_to_hex(oid));
368
if (name)
369
strbuf_addf(buf, " (%s)", name);
370
@@ -373,7 +381,7 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
381
if (parse_tree(tree))
382
return -1;
383
376
- name = fsck_get_object_name(options, &tree->object);
384
+ name = fsck_get_object_name(options, &tree->object.oid);
385
if (init_tree_desc_gently(&desc, tree->buffer, tree->size))
386
return -1;
387
while (tree_entry_gently(&desc, &entry)) {
@@ -386,20 +394,20 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
394
if (S_ISDIR(entry.mode)) {
395
obj = (struct object *)lookup_tree(the_repository, &entry.oid);
396
if (name && obj)
389
- fsck_put_object_name(options, obj, "%s%s/",
397
+ fsck_put_object_name(options, &entry.oid, "%s%s/",
398
name, entry.path);
399
result = options->walk(obj, OBJ_TREE, data, options);
400
}
401
else if (S_ISREG(entry.mode) || S_ISLNK(entry.mode)) {
402
obj = (struct object *)lookup_blob(the_repository, &entry.oid);
403
if (name && obj)
396
- fsck_put_object_name(options, obj, "%s%s",
404
+ fsck_put_object_name(options, &entry.oid, "%s%s",
405
name, entry.path);
406
result = options->walk(obj, OBJ_BLOB, data, options);
407
}
408
else {
409
result = error("in tree %s: entry %s has bad mode %.6o",
402
- fsck_describe_object(options, &tree->object),
410
+ fsck_describe_object(options, &tree->object.oid),
411
entry.path, entry.mode);
412
}
413
if (result < 0)
@@ -421,9 +429,9 @@ static int fsck_walk_commit(struct commit *commit, void *data, struct fsck_optio
429
if (parse_commit(commit))
430
return -1;
431
424
- name = fsck_get_object_name(options, &commit->object);
432
+ name = fsck_get_object_name(options, &commit->object.oid);
433
if (name)
426
- fsck_put_object_name(options, &get_commit_tree(commit)->object,
434
+ fsck_put_object_name(options, get_commit_tree_oid(commit),
435
"%s:", name);
436
437
result = options->walk((struct object *)get_commit_tree(commit),
@@ -452,18 +460,17 @@ static int fsck_walk_commit(struct commit *commit, void *data, struct fsck_optio
460
461
while (parents) {
462
if (name) {
455
- struct object *obj = &parents->item->object;
463
+ struct object_id *oid = &parents->item->object.oid;
464
465
if (counter++)
458
- fsck_put_object_name(options, obj, "%s^%d",
466
+ fsck_put_object_name(options, oid, "%s^%d",
467
name, counter);
468
else if (generation > 0)
461
- fsck_put_object_name(options, obj, "%.*s~%d",
469
+ fsck_put_object_name(options, oid, "%.*s~%d",
470
name_prefix_len, name,
471
generation + 1);
472
else
465
- fsck_put_object_name(options, obj, "%s^",
466
- name);
473
+ fsck_put_object_name(options, oid, "%s^", name);
474
}
475
result = options->walk((struct object *)parents->item, OBJ_COMMIT, data, options);
476
if (result < 0)
@@ -477,12 +484,12 @@ static int fsck_walk_commit(struct commit *commit, void *data, struct fsck_optio
484
485
static int fsck_walk_tag(struct tag *tag, void *data, struct fsck_options *options)
486
{
480
- const char *name = fsck_get_object_name(options, &tag->object);
487
+ const char *name = fsck_get_object_name(options, &tag->object.oid);
488
489
if (parse_tag(tag))
490
return -1;
491
if (name)
485
- fsck_put_object_name(options, tag->tagged, "%s", name);
492
+ fsck_put_object_name(options, &tag->tagged->oid, "%s", name);
493
return options->walk(tag->tagged, OBJ_ANY, data, options);
494
}
495
@@ -505,7 +512,7 @@ int fsck_walk(struct object *obj, void *data, struct fsck_options *options)
512
return fsck_walk_tag((struct tag *)obj, data, options);
513
default:
514
error("Unknown object type for %s",
508
- fsck_describe_object(options, obj));
515
+ fsck_describe_object(options, &obj->oid));
516
return -1;
517
}
518
}
@@ -979,10 +986,10 @@ int fsck_error_function(struct fsck_options *o,
986
struct object *obj, int msg_type, const char *message)
987
{
988
if (msg_type == FSCK_WARN) {
982
- warning("object %s: %s", fsck_describe_object(o, obj), message);
989
+ warning("object %s: %s", fsck_describe_object(o, &obj->oid), message);
990
return 0;
991
}
985
- error("object %s: %s", fsck_describe_object(o, obj), message);
992
+ error("object %s: %s", fsck_describe_object(o, &obj->oid), message);
993
return 1;
994
}
995
fsck.h
+5
-4
@@ -38,7 +38,7 @@ struct fsck_options {
38
unsigned strict:1;
39
int *msg_type;
40
struct oidset skiplist;
41
- struct decoration *object_names;
41
+ kh_oid_map_t *object_names;
42
};
43
44
#define FSCK_OPTIONS_DEFAULT { NULL, fsck_error_function, 0, NULL, OIDSET_INIT }
@@ -84,11 +84,12 @@ int fsck_finish(struct fsck_options *options);
84
*/
85
void fsck_enable_object_names(struct fsck_options *options);
86
const char *fsck_get_object_name(struct fsck_options *options,
87
- struct object *obj);
87
+ const struct object_id *oid);
88
__attribute__((format (printf,3,4)))
89
-void fsck_put_object_name(struct fsck_options *options, struct object *obj,
89
+void fsck_put_object_name(struct fsck_options *options,
90
+ const struct object_id *oid,
91
const char *fmt, ...);
92
const char *fsck_describe_object(struct fsck_options *options,
92
- struct object *obj);
93
+ const struct object_id *oid);
94
95
#endif