packfile: move list of packs into the packfile store
Move the list of packs into the packfile store. This follows the same logic as in a previous commit, where we moved the most-recently-used list of packs, as well. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Oct 30, 2025 at 11:38 UTC
589127caa73090040200989ff4d24c3d54f473f2
3 files changed
+43
-60
builtin/fast-import.c
+2
-2
@@ -978,7 +978,7 @@ static int store_object(
978
if (e->idx.offset) {
979
duplicate_count_by_type[type]++;
980
return 1;
981
- } else if (find_oid_pack(&oid, packfile_store_get_packs(packs))) {
981
+ } else if (packfile_list_find_oid(packfile_store_get_packs(packs), &oid)) {
982
e->type = type;
983
e->pack_id = MAX_PACK_ID;
984
e->idx.offset = 1; /* just not zero! */
@@ -1179,7 +1179,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
1179
duplicate_count_by_type[OBJ_BLOB]++;
1180
truncate_pack(&checkpoint);
1181
1182
- } else if (find_oid_pack(&oid, packfile_store_get_packs(packs))) {
1182
+ } else if (packfile_list_find_oid(packfile_store_get_packs(packs), &oid)) {
1183
e->type = OBJ_BLOB;
1184
e->pack_id = MAX_PACK_ID;
1185
e->idx.offset = 1; /* just not zero! */
packfile.c
+37
-46
@@ -356,13 +356,14 @@ static void scan_windows(struct packed_git *p,
356
357
static int unuse_one_window(struct packed_git *current)
358
{
359
- struct packed_git *p, *lru_p = NULL;
359
+ struct packfile_list_entry *e;
360
+ struct packed_git *lru_p = NULL;
361
struct pack_window *lru_w = NULL, *lru_l = NULL;
362
363
if (current)
364
scan_windows(current, &lru_p, &lru_w, &lru_l);
364
- for (p = current->repo->objects->packfiles->packs; p; p = p->next)
365
- scan_windows(p, &lru_p, &lru_w, &lru_l);
365
+ for (e = current->repo->objects->packfiles->packs.head; e; e = e->next)
366
+ scan_windows(e->pack, &lru_p, &lru_w, &lru_l);
367
if (lru_p) {
368
munmap(lru_w->base, lru_w->len);
369
pack_mapped -= lru_w->len;
@@ -542,14 +543,15 @@ static void find_lru_pack(struct packed_git *p, struct packed_git **lru_p, struc
543
544
static int close_one_pack(struct repository *r)
545
{
545
- struct packed_git *p, *lru_p = NULL;
546
+ struct packfile_list_entry *e;
547
+ struct packed_git *lru_p = NULL;
548
struct pack_window *mru_w = NULL;
549
int accept_windows_inuse = 1;
550
549
- for (p = r->objects->packfiles->packs; p; p = p->next) {
550
- if (p->pack_fd == -1)
551
+ for (e = r->objects->packfiles->packs.head; e; e = e->next) {
552
+ if (e->pack->pack_fd == -1)
553
continue;
552
- find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse);
554
+ find_lru_pack(e->pack, &lru_p, &mru_w, &accept_windows_inuse);
555
}
556
557
if (lru_p)
@@ -868,8 +870,7 @@ void packfile_store_add_pack(struct packfile_store *store,
870
if (pack->pack_fd != -1)
871
pack_open_fds++;
872
871
- pack->next = store->packs;
872
- store->packs = pack;
873
+ packfile_list_prepend(&store->packs, pack);
874
875
strmap_put(&store->packs_by_path, pack->pack_name, pack);
876
}
@@ -1046,9 +1047,10 @@ static void prepare_packed_git_one(struct odb_source *source)
1047
string_list_clear(data.garbage, 0);
1048
}
1049
1049
-DEFINE_LIST_SORT(static, sort_packs, struct packed_git, next);
1050
+DEFINE_LIST_SORT(static, sort_packs, struct packfile_list_entry, next);
1051
1051
-static int sort_pack(const struct packed_git *a, const struct packed_git *b)
1052
+static int sort_pack(const struct packfile_list_entry *a,
1053
+ const struct packfile_list_entry *b)
1054
{
1055
int st;
1056
@@ -1058,7 +1060,7 @@ static int sort_pack(const struct packed_git *a, const struct packed_git *b)
1060
* remote ones could be on a network mounted filesystem.
1061
* Favor local ones for these reasons.
1062
*/
1061
- st = a->pack_local - b->pack_local;
1063
+ st = a->pack->pack_local - b->pack->pack_local;
1064
if (st)
1065
return -st;
1066
@@ -1067,21 +1069,19 @@ static int sort_pack(const struct packed_git *a, const struct packed_git *b)
1069
* and more recent objects tend to get accessed more
1070
* often.
1071
*/
1070
- if (a->mtime < b->mtime)
1072
+ if (a->pack->mtime < b->pack->mtime)
1073
return 1;
1072
- else if (a->mtime == b->mtime)
1074
+ else if (a->pack->mtime == b->pack->mtime)
1075
return 0;
1076
return -1;
1077
}
1078
1079
static void packfile_store_prepare_mru(struct packfile_store *store)
1080
{
1079
- struct packed_git *p;
1080
-
1081
packfile_list_clear(&store->mru);
1082
1083
- for (p = store->packs; p; p = p->next)
1084
- packfile_list_append(&store->mru, p);
1083
+ for (struct packfile_list_entry *e = store->packs.head; e; e = e->next)
1084
+ packfile_list_append(&store->mru, e->pack);
1085
}
1086
1087
void packfile_store_prepare(struct packfile_store *store)
@@ -1096,7 +1096,11 @@ void packfile_store_prepare(struct packfile_store *store)
1096
prepare_multi_pack_index_one(source);
1097
prepare_packed_git_one(source);
1098
}
1099
- sort_packs(&store->packs, sort_pack);
1099
+
1100
+ sort_packs(&store->packs.head, sort_pack);
1101
+ for (struct packfile_list_entry *e = store->packs.head; e; e = e->next)
1102
+ if (!e->next)
1103
+ store->packs.tail = e;
1104
1105
packfile_store_prepare_mru(store);
1106
store->initialized = true;
@@ -1108,7 +1112,7 @@ void packfile_store_reprepare(struct packfile_store *store)
1112
packfile_store_prepare(store);
1113
}
1114
1111
-struct packed_git *packfile_store_get_packs(struct packfile_store *store)
1115
+struct packfile_list_entry *packfile_store_get_packs(struct packfile_store *store)
1116
{
1117
packfile_store_prepare(store);
1118
@@ -1120,7 +1124,7 @@ struct packed_git *packfile_store_get_packs(struct packfile_store *store)
1124
prepare_midx_pack(m, i);
1125
}
1126
1123
- return store->packs;
1127
+ return store->packs.head;
1128
}
1129
1130
struct packfile_list_entry *packfile_store_get_packs_mru(struct packfile_store *store)
@@ -1276,11 +1280,11 @@ void mark_bad_packed_object(struct packed_git *p, const struct object_id *oid)
1280
const struct packed_git *has_packed_and_bad(struct repository *r,
1281
const struct object_id *oid)
1282
{
1279
- struct packed_git *p;
1283
+ struct packfile_list_entry *e;
1284
1281
- for (p = r->objects->packfiles->packs; p; p = p->next)
1282
- if (oidset_contains(&p->bad_objects, oid))
1283
- return p;
1285
+ for (e = r->objects->packfiles->packs.head; e; e = e->next)
1286
+ if (oidset_contains(&e->pack->bad_objects, oid))
1287
+ return e->pack;
1288
return NULL;
1289
}
1290
@@ -2088,19 +2092,6 @@ int is_pack_valid(struct packed_git *p)
2092
return !open_packed_git(p);
2093
}
2094
2091
-struct packed_git *find_oid_pack(const struct object_id *oid,
2092
- struct packed_git *packs)
2093
-{
2094
- struct packed_git *p;
2095
-
2096
- for (p = packs; p; p = p->next) {
2097
- if (find_pack_entry_one(oid, p))
2098
- return p;
2099
- }
2100
- return NULL;
2101
-
2102
-}
2103
-
2095
static int fill_pack_entry(const struct object_id *oid,
2096
struct pack_entry *e,
2097
struct packed_git *p)
@@ -2139,7 +2130,7 @@ int find_pack_entry(struct repository *r, const struct object_id *oid, struct pa
2130
if (source->midx && fill_midx_entry(source->midx, oid, e))
2131
return 1;
2132
2142
- if (!r->objects->packfiles->packs)
2133
+ if (!r->objects->packfiles->packs.head)
2134
return 0;
2135
2136
for (l = r->objects->packfiles->mru.head; l; l = l->next) {
@@ -2404,19 +2395,19 @@ struct packfile_store *packfile_store_new(struct object_database *odb)
2395
2396
void packfile_store_free(struct packfile_store *store)
2397
{
2407
- for (struct packed_git *p = store->packs, *next; p; p = next) {
2408
- next = p->next;
2409
- free(p);
2410
- }
2398
+ for (struct packfile_list_entry *e = store->packs.head; e; e = e->next)
2399
+ free(e->pack);
2400
+ packfile_list_clear(&store->packs);
2401
+
2402
strmap_clear(&store->packs_by_path, 0);
2403
free(store);
2404
}
2405
2406
void packfile_store_close(struct packfile_store *store)
2407
{
2417
- for (struct packed_git *p = store->packs; p; p = p->next) {
2418
- if (p->do_not_close)
2408
+ for (struct packfile_list_entry *e = store->packs.head; e; e = e->next) {
2409
+ if (e->pack->do_not_close)
2410
BUG("want to close pack marked 'do-not-close'");
2420
- close_pack(p);
2411
+ close_pack(e->pack);
2412
}
2413
}
packfile.h
+4
-12
@@ -11,7 +11,6 @@
11
struct object_info;
12
13
struct packed_git {
14
- struct packed_git *next;
14
struct pack_window *windows;
15
off_t pack_size;
16
const void *index_data;
@@ -83,7 +82,7 @@ struct packfile_store {
82
* The list of packfiles in the order in which they are being added to
83
* the store.
84
*/
86
- struct packed_git *packs;
85
+ struct packfile_list packs;
86
87
/*
88
* Cache of packfiles which are marked as "kept", either because there
@@ -163,13 +162,14 @@ void packfile_store_add_pack(struct packfile_store *store,
162
* repository.
163
*/
164
#define repo_for_each_pack(repo, p) \
166
- for (p = packfile_store_get_packs(repo->objects->packfiles); p; p = p->next)
165
+ for (struct packfile_list_entry *e = packfile_store_get_packs(repo->objects->packfiles); \
166
+ ((p) = (e ? e->pack : NULL)); e = e->next)
167
168
/*
169
* Get all packs managed by the given store, including packfiles that are
170
* referenced by multi-pack indices.
171
*/
172
-struct packed_git *packfile_store_get_packs(struct packfile_store *store);
172
+struct packfile_list_entry *packfile_store_get_packs(struct packfile_store *store);
173
174
/*
175
* Get all packs in most-recently-used order.
@@ -266,14 +266,6 @@ extern void (*report_garbage)(unsigned seen_bits, const char *path);
266
*/
267
unsigned long repo_approximate_object_count(struct repository *r);
268
269
-/*
270
- * Find the pack within the "packs" list whose index contains the object "oid".
271
- * For general object lookups, you probably don't want this; use
272
- * find_pack_entry() instead.
273
- */
274
-struct packed_git *find_oid_pack(const struct object_id *oid,
275
- struct packed_git *packs);
276
-
269
void pack_report(struct repository *repo);
270
271
/*