mirror of
https://github.com/git/git.git
synced 2026-01-22 23:07:18 +09:00
reachable: convert to use odb_for_each_object()
To figure out which objects expired objects we enumerate all loose and packed objects individually so that we can figure out their respective mtimes. Refactor the code to instead use `odb_for_each_object()` with a request that ask for the object mtime instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
3ebb07b62f
commit
7093a4517f
125
reachable.c
125
reachable.c
@ -191,30 +191,27 @@ static int obj_is_recent(const struct object_id *oid, timestamp_t mtime,
|
||||
return oidset_contains(&data->extra_recent_oids, oid);
|
||||
}
|
||||
|
||||
static void add_recent_object(const struct object_id *oid,
|
||||
struct packed_git *pack,
|
||||
off_t offset,
|
||||
timestamp_t mtime,
|
||||
struct recent_data *data)
|
||||
static int want_recent_object(struct recent_data *data,
|
||||
const struct object_id *oid)
|
||||
{
|
||||
if (data->ignore_in_core_kept_packs &&
|
||||
has_object_kept_pack(data->revs->repo, oid, KEPT_PACK_IN_CORE))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int add_recent_object(const struct object_id *oid,
|
||||
struct object_info *oi,
|
||||
void *cb_data)
|
||||
{
|
||||
struct recent_data *data = cb_data;
|
||||
struct object *obj;
|
||||
enum object_type type;
|
||||
|
||||
if (!obj_is_recent(oid, mtime, data))
|
||||
return;
|
||||
if (!want_recent_object(data, oid) ||
|
||||
!obj_is_recent(oid, *oi->mtimep, data))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We do not want to call parse_object here, because
|
||||
* inflating blobs and trees could be very expensive.
|
||||
* However, we do need to know the correct type for
|
||||
* later processing, and the revision machinery expects
|
||||
* commits and tags to have been parsed.
|
||||
*/
|
||||
type = odb_read_object_info(the_repository->objects, oid, NULL);
|
||||
if (type < 0)
|
||||
die("unable to get object info for %s", oid_to_hex(oid));
|
||||
|
||||
switch (type) {
|
||||
switch (*oi->typep) {
|
||||
case OBJ_TAG:
|
||||
case OBJ_COMMIT:
|
||||
obj = parse_object_or_die(the_repository, oid, NULL);
|
||||
@ -227,77 +224,22 @@ static void add_recent_object(const struct object_id *oid,
|
||||
break;
|
||||
default:
|
||||
die("unknown object type for %s: %s",
|
||||
oid_to_hex(oid), type_name(type));
|
||||
oid_to_hex(oid), type_name(*oi->typep));
|
||||
}
|
||||
|
||||
if (!obj)
|
||||
die("unable to lookup %s", oid_to_hex(oid));
|
||||
if (obj->flags & SEEN)
|
||||
return 0;
|
||||
|
||||
add_pending_object(data->revs, obj, "");
|
||||
if (data->cb)
|
||||
data->cb(obj, pack, offset, mtime);
|
||||
}
|
||||
|
||||
static int want_recent_object(struct recent_data *data,
|
||||
const struct object_id *oid)
|
||||
{
|
||||
if (data->ignore_in_core_kept_packs &&
|
||||
has_object_kept_pack(data->revs->repo, oid, KEPT_PACK_IN_CORE))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int add_recent_loose(const struct object_id *oid,
|
||||
const char *path, void *data)
|
||||
{
|
||||
struct stat st;
|
||||
struct object *obj;
|
||||
|
||||
if (!want_recent_object(data, oid))
|
||||
return 0;
|
||||
|
||||
obj = lookup_object(the_repository, oid);
|
||||
|
||||
if (obj && obj->flags & SEEN)
|
||||
return 0;
|
||||
|
||||
if (stat(path, &st) < 0) {
|
||||
/*
|
||||
* It's OK if an object went away during our iteration; this
|
||||
* could be due to a simultaneous repack. But anything else
|
||||
* we should abort, since we might then fail to mark objects
|
||||
* which should not be pruned.
|
||||
*/
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
return error_errno("unable to stat %s", oid_to_hex(oid));
|
||||
if (data->cb) {
|
||||
if (oi->whence == OI_PACKED)
|
||||
data->cb(obj, oi->u.packed.pack, oi->u.packed.offset, *oi->mtimep);
|
||||
else
|
||||
data->cb(obj, NULL, 0, *oi->mtimep);
|
||||
}
|
||||
|
||||
add_recent_object(oid, NULL, 0, st.st_mtime, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_recent_packed(const struct object_id *oid,
|
||||
struct packed_git *p,
|
||||
uint32_t pos,
|
||||
void *data)
|
||||
{
|
||||
struct object *obj;
|
||||
timestamp_t mtime = p->mtime;
|
||||
|
||||
if (!want_recent_object(data, oid))
|
||||
return 0;
|
||||
|
||||
obj = lookup_object(the_repository, oid);
|
||||
|
||||
if (obj && obj->flags & SEEN)
|
||||
return 0;
|
||||
if (p->is_cruft) {
|
||||
if (load_pack_mtimes(p) < 0)
|
||||
die(_("could not load cruft pack .mtimes"));
|
||||
mtime = nth_packed_mtime(p, pos);
|
||||
}
|
||||
add_recent_object(oid, p, nth_packed_object_offset(p, pos), mtime, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -307,7 +249,13 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
|
||||
int ignore_in_core_kept_packs)
|
||||
{
|
||||
struct recent_data data;
|
||||
enum odb_for_each_object_flags flags;
|
||||
unsigned flags;
|
||||
enum object_type type;
|
||||
time_t mtime;
|
||||
struct object_info oi = {
|
||||
.mtimep = &mtime,
|
||||
.typep = &type,
|
||||
};
|
||||
int r;
|
||||
|
||||
data.revs = revs;
|
||||
@ -318,16 +266,13 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
|
||||
oidset_init(&data.extra_recent_oids, 0);
|
||||
data.extra_recent_oids_loaded = 0;
|
||||
|
||||
r = for_each_loose_object(the_repository->objects, add_recent_loose, &data,
|
||||
ODB_FOR_EACH_OBJECT_LOCAL_ONLY);
|
||||
if (r)
|
||||
goto done;
|
||||
|
||||
flags = ODB_FOR_EACH_OBJECT_LOCAL_ONLY | ODB_FOR_EACH_OBJECT_PACK_ORDER;
|
||||
if (ignore_in_core_kept_packs)
|
||||
flags |= ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS;
|
||||
|
||||
r = for_each_packed_object(revs->repo, add_recent_packed, &data, flags);
|
||||
r = odb_for_each_object(revs->repo->objects, &oi, add_recent_object, &data, flags);
|
||||
if (r)
|
||||
goto done;
|
||||
|
||||
done:
|
||||
oidset_clear(&data.extra_recent_oids);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user