Skip to content

Commit 7a8582c

Browse files
pks-tgitster
authored andcommitted
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>
1 parent dd097bb commit 7a8582c

1 file changed

Lines changed: 35 additions & 90 deletions

File tree

reachable.c

Lines changed: 35 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -191,30 +191,27 @@ static int obj_is_recent(const struct object_id *oid, timestamp_t mtime,
191191
return oidset_contains(&data->extra_recent_oids, oid);
192192
}
193193

194-
static void add_recent_object(const struct object_id *oid,
195-
struct packed_git *pack,
196-
off_t offset,
197-
timestamp_t mtime,
198-
struct recent_data *data)
194+
static int want_recent_object(struct recent_data *data,
195+
const struct object_id *oid)
199196
{
200-
struct object *obj;
201-
enum object_type type;
197+
if (data->ignore_in_core_kept_packs &&
198+
has_object_kept_pack(data->revs->repo, oid, KEPT_PACK_IN_CORE))
199+
return 0;
200+
return 1;
201+
}
202202

203-
if (!obj_is_recent(oid, mtime, data))
204-
return;
203+
static int add_recent_object(const struct object_id *oid,
204+
struct object_info *oi,
205+
void *cb_data)
206+
{
207+
struct recent_data *data = cb_data;
208+
struct object *obj;
205209

206-
/*
207-
* We do not want to call parse_object here, because
208-
* inflating blobs and trees could be very expensive.
209-
* However, we do need to know the correct type for
210-
* later processing, and the revision machinery expects
211-
* commits and tags to have been parsed.
212-
*/
213-
type = odb_read_object_info(the_repository->objects, oid, NULL);
214-
if (type < 0)
215-
die("unable to get object info for %s", oid_to_hex(oid));
210+
if (!want_recent_object(data, oid) ||
211+
!obj_is_recent(oid, *oi->mtimep, data))
212+
return 0;
216213

217-
switch (type) {
214+
switch (*oi->typep) {
218215
case OBJ_TAG:
219216
case OBJ_COMMIT:
220217
obj = parse_object_or_die(the_repository, oid, NULL);
@@ -227,77 +224,22 @@ static void add_recent_object(const struct object_id *oid,
227224
break;
228225
default:
229226
die("unknown object type for %s: %s",
230-
oid_to_hex(oid), type_name(type));
227+
oid_to_hex(oid), type_name(*oi->typep));
231228
}
232229

233230
if (!obj)
234231
die("unable to lookup %s", oid_to_hex(oid));
235-
236-
add_pending_object(data->revs, obj, "");
237-
if (data->cb)
238-
data->cb(obj, pack, offset, mtime);
239-
}
240-
241-
static int want_recent_object(struct recent_data *data,
242-
const struct object_id *oid)
243-
{
244-
if (data->ignore_in_core_kept_packs &&
245-
has_object_kept_pack(data->revs->repo, oid, KEPT_PACK_IN_CORE))
232+
if (obj->flags & SEEN)
246233
return 0;
247-
return 1;
248-
}
249234

250-
static int add_recent_loose(const struct object_id *oid,
251-
const char *path, void *data)
252-
{
253-
struct stat st;
254-
struct object *obj;
255-
256-
if (!want_recent_object(data, oid))
257-
return 0;
258-
259-
obj = lookup_object(the_repository, oid);
260-
261-
if (obj && obj->flags & SEEN)
262-
return 0;
263-
264-
if (stat(path, &st) < 0) {
265-
/*
266-
* It's OK if an object went away during our iteration; this
267-
* could be due to a simultaneous repack. But anything else
268-
* we should abort, since we might then fail to mark objects
269-
* which should not be pruned.
270-
*/
271-
if (errno == ENOENT)
272-
return 0;
273-
return error_errno("unable to stat %s", oid_to_hex(oid));
235+
add_pending_object(data->revs, obj, "");
236+
if (data->cb) {
237+
if (oi->whence == OI_PACKED)
238+
data->cb(obj, oi->u.packed.pack, oi->u.packed.offset, *oi->mtimep);
239+
else
240+
data->cb(obj, NULL, 0, *oi->mtimep);
274241
}
275242

276-
add_recent_object(oid, NULL, 0, st.st_mtime, data);
277-
return 0;
278-
}
279-
280-
static int add_recent_packed(const struct object_id *oid,
281-
struct packed_git *p,
282-
uint32_t pos,
283-
void *data)
284-
{
285-
struct object *obj;
286-
timestamp_t mtime = p->mtime;
287-
288-
if (!want_recent_object(data, oid))
289-
return 0;
290-
291-
obj = lookup_object(the_repository, oid);
292-
293-
if (obj && obj->flags & SEEN)
294-
return 0;
295-
if (p->is_cruft) {
296-
if (load_pack_mtimes(p) < 0)
297-
die(_("could not load cruft pack .mtimes"));
298-
mtime = nth_packed_mtime(p, pos);
299-
}
300-
add_recent_object(oid, p, nth_packed_object_offset(p, pos), mtime, data);
301243
return 0;
302244
}
303245

@@ -307,7 +249,13 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
307249
int ignore_in_core_kept_packs)
308250
{
309251
struct recent_data data;
310-
enum odb_for_each_object_flags flags;
252+
unsigned flags;
253+
enum object_type type;
254+
time_t mtime;
255+
struct object_info oi = {
256+
.mtimep = &mtime,
257+
.typep = &type,
258+
};
311259
int r;
312260

313261
data.revs = revs;
@@ -318,16 +266,13 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
318266
oidset_init(&data.extra_recent_oids, 0);
319267
data.extra_recent_oids_loaded = 0;
320268

321-
r = for_each_loose_object(the_repository->objects, add_recent_loose, &data,
322-
ODB_FOR_EACH_OBJECT_LOCAL_ONLY);
323-
if (r)
324-
goto done;
325-
326269
flags = ODB_FOR_EACH_OBJECT_LOCAL_ONLY | ODB_FOR_EACH_OBJECT_PACK_ORDER;
327270
if (ignore_in_core_kept_packs)
328271
flags |= ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS;
329272

330-
r = for_each_packed_object(revs->repo, add_recent_packed, &data, flags);
273+
r = odb_for_each_object(revs->repo->objects, &oi, add_recent_object, &data, flags);
274+
if (r)
275+
goto done;
331276

332277
done:
333278
oidset_clear(&data.extra_recent_oids);

0 commit comments

Comments
 (0)