Skip to content

Commit 1d05db2

Browse files
pks-tgitster
authored andcommitted
packfile: move packfile store into object source
The packfile store is a member of `struct object_database`, which means that we have a single store per database. This doesn't really make much sense though: each source connected to the database has its own set of packfiles, so there is a conceptual mismatch here. This hasn't really caused much of a problem in the past, but with the advent of pluggable object databases this is becoming more of a problem because some of the sources may not even use packfiles in the first place. Move the packfile store down by one level from the object database into the object database source. This ensures that each source now has its own packfile store, and we can eventually start to abstract it away entirely so that the caller doesn't even know what kind of store it uses. Note that we only need to adjust a relatively small number of callers, way less than one might expect. This is because most callers are using `repo_for_each_pack()`, which handles enumeration of all packfiles that exist in the repository. So for now, none of these callers need to be adapted. The remaining callers that iterate through the packfiles directly and that need adjustment are those that are a bit more tangled with packfiles. These will be adjusted over time. Note that this patch only moves the packfile store, and there is still a bunch of functions that seemingly operate on a packfile store but that end up iterating over all sources. These will be adjusted in subsequent commits. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c9107d2 commit 1d05db2

File tree

11 files changed

+243
-145
lines changed

11 files changed

+243
-145
lines changed

builtin/fast-import.c

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ static void end_packfile(void)
900900
idx_name = keep_pack(create_index());
901901

902902
/* Register the packfile with core git's machinery. */
903-
new_p = packfile_store_load_pack(pack_data->repo->objects->packfiles,
903+
new_p = packfile_store_load_pack(pack_data->repo->objects->sources->packfiles,
904904
idx_name, 1);
905905
if (!new_p)
906906
die(_("core Git rejected index %s"), idx_name);
@@ -955,7 +955,7 @@ static int store_object(
955955
struct object_id *oidout,
956956
uintmax_t mark)
957957
{
958-
struct packfile_store *packs = the_repository->objects->packfiles;
958+
struct odb_source *source;
959959
void *out, *delta;
960960
struct object_entry *e;
961961
unsigned char hdr[96];
@@ -979,7 +979,11 @@ static int store_object(
979979
if (e->idx.offset) {
980980
duplicate_count_by_type[type]++;
981981
return 1;
982-
} else if (packfile_list_find_oid(packfile_store_get_packs(packs), &oid)) {
982+
}
983+
984+
for (source = the_repository->objects->sources; source; source = source->next) {
985+
if (!packfile_list_find_oid(packfile_store_get_packs(source->packfiles), &oid))
986+
continue;
983987
e->type = type;
984988
e->pack_id = MAX_PACK_ID;
985989
e->idx.offset = 1; /* just not zero! */
@@ -1096,10 +1100,10 @@ static void truncate_pack(struct hashfile_checkpoint *checkpoint)
10961100

10971101
static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
10981102
{
1099-
struct packfile_store *packs = the_repository->objects->packfiles;
11001103
size_t in_sz = 64 * 1024, out_sz = 64 * 1024;
11011104
unsigned char *in_buf = xmalloc(in_sz);
11021105
unsigned char *out_buf = xmalloc(out_sz);
1106+
struct odb_source *source;
11031107
struct object_entry *e;
11041108
struct object_id oid;
11051109
unsigned long hdrlen;
@@ -1179,24 +1183,29 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
11791183
if (e->idx.offset) {
11801184
duplicate_count_by_type[OBJ_BLOB]++;
11811185
truncate_pack(&checkpoint);
1186+
goto out;
1187+
}
11821188

1183-
} else if (packfile_list_find_oid(packfile_store_get_packs(packs), &oid)) {
1189+
for (source = the_repository->objects->sources; source; source = source->next) {
1190+
if (!packfile_list_find_oid(packfile_store_get_packs(source->packfiles), &oid))
1191+
continue;
11841192
e->type = OBJ_BLOB;
11851193
e->pack_id = MAX_PACK_ID;
11861194
e->idx.offset = 1; /* just not zero! */
11871195
duplicate_count_by_type[OBJ_BLOB]++;
11881196
truncate_pack(&checkpoint);
1189-
1190-
} else {
1191-
e->depth = 0;
1192-
e->type = OBJ_BLOB;
1193-
e->pack_id = pack_id;
1194-
e->idx.offset = offset;
1195-
e->idx.crc32 = crc32_end(pack_file);
1196-
object_count++;
1197-
object_count_by_type[OBJ_BLOB]++;
1197+
goto out;
11981198
}
11991199

1200+
e->depth = 0;
1201+
e->type = OBJ_BLOB;
1202+
e->pack_id = pack_id;
1203+
e->idx.offset = offset;
1204+
e->idx.crc32 = crc32_end(pack_file);
1205+
object_count++;
1206+
object_count_by_type[OBJ_BLOB]++;
1207+
1208+
out:
12001209
free(in_buf);
12011210
free(out_buf);
12021211
}

builtin/grep.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1213,8 +1213,12 @@ int cmd_grep(int argc,
12131213
*/
12141214
if (recurse_submodules)
12151215
repo_read_gitmodules(the_repository, 1);
1216+
/*
1217+
* Note: `packfile_store_prepare()` prepares stores from all
1218+
* sources. This will be fixed in a subsequent commit.
1219+
*/
12161220
if (startup_info->have_repository)
1217-
packfile_store_prepare(the_repository->objects->packfiles);
1221+
packfile_store_prepare(the_repository->objects->sources->packfiles);
12181222

12191223
start_threads(&opt);
12201224
} else {

builtin/index-pack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1638,7 +1638,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
16381638
hash, "idx", 1);
16391639

16401640
if (do_fsck_object && startup_info->have_repository)
1641-
packfile_store_load_pack(the_repository->objects->packfiles,
1641+
packfile_store_load_pack(the_repository->objects->sources->packfiles,
16421642
final_index_name, 0);
16431643

16441644
if (!from_stdin) {

builtin/pack-objects.c

Lines changed: 51 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,49 +1529,53 @@ static int want_cruft_object_mtime(struct repository *r,
15291529
const struct object_id *oid,
15301530
unsigned flags, uint32_t mtime)
15311531
{
1532-
struct packed_git **cache = packfile_store_get_kept_pack_cache(r->objects->packfiles, flags);
1532+
struct odb_source *source;
15331533

1534-
for (; *cache; cache++) {
1535-
struct packed_git *p = *cache;
1536-
off_t ofs;
1537-
uint32_t candidate_mtime;
1534+
for (source = r->objects->sources; source; source = source->next) {
1535+
struct packed_git **cache = packfile_store_get_kept_pack_cache(source->packfiles, flags);
15381536

1539-
ofs = find_pack_entry_one(oid, p);
1540-
if (!ofs)
1541-
continue;
1537+
for (; *cache; cache++) {
1538+
struct packed_git *p = *cache;
1539+
off_t ofs;
1540+
uint32_t candidate_mtime;
15421541

1543-
/*
1544-
* We have a copy of the object 'oid' in a non-cruft
1545-
* pack. We can avoid packing an additional copy
1546-
* regardless of what the existing copy's mtime is since
1547-
* it is outside of a cruft pack.
1548-
*/
1549-
if (!p->is_cruft)
1550-
return 0;
1551-
1552-
/*
1553-
* If we have a copy of the object 'oid' in a cruft
1554-
* pack, then either read the cruft pack's mtime for
1555-
* that object, or, if that can't be loaded, assume the
1556-
* pack's mtime itself.
1557-
*/
1558-
if (!load_pack_mtimes(p)) {
1559-
uint32_t pos;
1560-
if (offset_to_pack_pos(p, ofs, &pos) < 0)
1542+
ofs = find_pack_entry_one(oid, p);
1543+
if (!ofs)
15611544
continue;
1562-
candidate_mtime = nth_packed_mtime(p, pos);
1563-
} else {
1564-
candidate_mtime = p->mtime;
1565-
}
15661545

1567-
/*
1568-
* We have a surviving copy of the object in a cruft
1569-
* pack whose mtime is greater than or equal to the one
1570-
* we are considering. We can thus avoid packing an
1571-
* additional copy of that object.
1572-
*/
1573-
if (mtime <= candidate_mtime)
1574-
return 0;
1546+
/*
1547+
* We have a copy of the object 'oid' in a non-cruft
1548+
* pack. We can avoid packing an additional copy
1549+
* regardless of what the existing copy's mtime is since
1550+
* it is outside of a cruft pack.
1551+
*/
1552+
if (!p->is_cruft)
1553+
return 0;
1554+
1555+
/*
1556+
* If we have a copy of the object 'oid' in a cruft
1557+
* pack, then either read the cruft pack's mtime for
1558+
* that object, or, if that can't be loaded, assume the
1559+
* pack's mtime itself.
1560+
*/
1561+
if (!load_pack_mtimes(p)) {
1562+
uint32_t pos;
1563+
if (offset_to_pack_pos(p, ofs, &pos) < 0)
1564+
continue;
1565+
candidate_mtime = nth_packed_mtime(p, pos);
1566+
} else {
1567+
candidate_mtime = p->mtime;
1568+
}
1569+
1570+
/*
1571+
* We have a surviving copy of the object in a cruft
1572+
* pack whose mtime is greater than or equal to the one
1573+
* we are considering. We can thus avoid packing an
1574+
* additional copy of that object.
1575+
*/
1576+
if (mtime <= candidate_mtime)
1577+
return 0;
1578+
}
15751579
}
15761580

15771581
return -1;
@@ -1749,13 +1753,15 @@ static int want_object_in_pack_mtime(const struct object_id *oid,
17491753
}
17501754
}
17511755

1752-
for (e = the_repository->objects->packfiles->packs.head; e; e = e->next) {
1753-
struct packed_git *p = e->pack;
1754-
want = want_object_in_pack_one(p, oid, exclude, found_pack, found_offset, found_mtime);
1755-
if (!exclude && want > 0)
1756-
packfile_list_prepend(&the_repository->objects->packfiles->packs, p);
1757-
if (want != -1)
1758-
return want;
1756+
for (source = the_repository->objects->sources; source; source = source->next) {
1757+
for (e = source->packfiles->packs.head; e; e = e->next) {
1758+
struct packed_git *p = e->pack;
1759+
want = want_object_in_pack_one(p, oid, exclude, found_pack, found_offset, found_mtime);
1760+
if (!exclude && want > 0)
1761+
packfile_list_prepend(&source->packfiles->packs, p);
1762+
if (want != -1)
1763+
return want;
1764+
}
17591765
}
17601766

17611767
if (uri_protocols.nr) {

http.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2544,7 +2544,7 @@ void http_install_packfile(struct packed_git *p,
25442544
struct packfile_list *list_to_remove_from)
25452545
{
25462546
packfile_list_remove(list_to_remove_from, p);
2547-
packfile_store_add_pack(the_repository->objects->packfiles, p);
2547+
packfile_store_add_pack(the_repository->objects->sources->packfiles, p);
25482548
}
25492549

25502550
struct http_pack_request *new_http_pack_request(

midx.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static int midx_read_object_offsets(const unsigned char *chunk_start,
9595

9696
struct multi_pack_index *get_multi_pack_index(struct odb_source *source)
9797
{
98-
packfile_store_prepare(source->odb->packfiles);
98+
packfile_store_prepare(source->packfiles);
9999
return source->midx;
100100
}
101101

@@ -447,7 +447,6 @@ static uint32_t midx_for_pack(struct multi_pack_index **_m,
447447
int prepare_midx_pack(struct multi_pack_index *m,
448448
uint32_t pack_int_id)
449449
{
450-
struct repository *r = m->source->odb->repo;
451450
struct strbuf pack_name = STRBUF_INIT;
452451
struct packed_git *p;
453452

@@ -460,7 +459,7 @@ int prepare_midx_pack(struct multi_pack_index *m,
460459

461460
strbuf_addf(&pack_name, "%s/pack/%s", m->source->path,
462461
m->pack_names[pack_int_id]);
463-
p = packfile_store_load_pack(r->objects->packfiles,
462+
p = packfile_store_load_pack(m->source->packfiles,
464463
pack_name.buf, m->source->local);
465464
strbuf_release(&pack_name);
466465

odb.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ static struct odb_source *odb_source_new(struct object_database *odb,
155155
source->local = local;
156156
source->path = xstrdup(path);
157157
source->loose = odb_source_loose_new(source);
158+
source->packfiles = packfile_store_new(source);
158159

159160
return source;
160161
}
@@ -373,6 +374,7 @@ static void odb_source_free(struct odb_source *source)
373374
{
374375
free(source->path);
375376
odb_source_loose_free(source->loose);
377+
packfile_store_free(source->packfiles);
376378
free(source);
377379
}
378380

@@ -704,19 +706,19 @@ static int do_oid_object_info_extended(struct object_database *odb,
704706
while (1) {
705707
struct odb_source *source;
706708

707-
if (!packfile_store_read_object_info(odb->packfiles, real, oi, flags))
708-
return 0;
709-
710709
/* Most likely it's a loose object. */
711-
for (source = odb->sources; source; source = source->next)
712-
if (!odb_source_loose_read_object_info(source, real, oi, flags))
710+
for (source = odb->sources; source; source = source->next) {
711+
if (!packfile_store_read_object_info(source->packfiles, real, oi, flags) ||
712+
!odb_source_loose_read_object_info(source, real, oi, flags))
713713
return 0;
714+
}
714715

715716
/* Not a loose object; someone else may have just packed it. */
716717
if (!(flags & OBJECT_INFO_QUICK)) {
717718
odb_reprepare(odb->repo->objects);
718-
if (!packfile_store_read_object_info(odb->packfiles, real, oi, flags))
719-
return 0;
719+
for (source = odb->sources; source; source = source->next)
720+
if (!packfile_store_read_object_info(source->packfiles, real, oi, flags))
721+
return 0;
720722
}
721723

722724
/*
@@ -975,13 +977,14 @@ int odb_freshen_object(struct object_database *odb,
975977
{
976978
struct odb_source *source;
977979

978-
if (packfile_store_freshen_object(odb->packfiles, oid))
979-
return 1;
980-
981980
odb_prepare_alternates(odb);
982-
for (source = odb->sources; source; source = source->next)
981+
for (source = odb->sources; source; source = source->next) {
982+
if (packfile_store_freshen_object(source->packfiles, oid))
983+
return 1;
984+
983985
if (odb_source_loose_freshen_object(source, oid))
984986
return 1;
987+
}
985988

986989
return 0;
987990
}
@@ -1064,7 +1067,6 @@ struct object_database *odb_new(struct repository *repo,
10641067
o->sources = odb_source_new(o, primary_source, true);
10651068
o->sources_tail = &o->sources->next;
10661069
o->alternate_db = xstrdup_or_null(secondary_sources);
1067-
o->packfiles = packfile_store_new(o->sources);
10681070

10691071
free(to_free);
10701072

@@ -1077,9 +1079,8 @@ void odb_close(struct object_database *o)
10771079
{
10781080
struct odb_source *source;
10791081

1080-
packfile_store_close(o->packfiles);
1081-
10821082
for (source = o->sources; source; source = source->next) {
1083+
packfile_store_close(source->packfiles);
10831084
if (source->midx)
10841085
close_midx(source->midx);
10851086
source->midx = NULL;
@@ -1118,7 +1119,6 @@ void odb_free(struct object_database *o)
11181119
free((char *) o->cached_objects[i].value.buf);
11191120
free(o->cached_objects);
11201121

1121-
packfile_store_free(o->packfiles);
11221122
string_list_clear(&o->submodule_source_paths, 0);
11231123

11241124
chdir_notify_unregister(NULL, odb_update_commondir, o);
@@ -1141,13 +1141,13 @@ void odb_reprepare(struct object_database *o)
11411141
o->loaded_alternates = 0;
11421142
odb_prepare_alternates(o);
11431143

1144-
for (source = o->sources; source; source = source->next)
1144+
for (source = o->sources; source; source = source->next) {
11451145
odb_source_loose_reprepare(source);
1146+
packfile_store_reprepare(source->packfiles);
1147+
}
11461148

11471149
o->approximate_object_count_valid = 0;
11481150

1149-
packfile_store_reprepare(o->packfiles);
1150-
11511151
obj_read_unlock();
11521152
}
11531153

odb.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ struct odb_source {
5151
/* Private state for loose objects. */
5252
struct odb_source_loose *loose;
5353

54+
/* Should only be accessed directly by packfile.c and midx.c. */
55+
struct packfile_store *packfiles;
56+
5457
/*
5558
* private data
5659
*
@@ -128,9 +131,6 @@ struct object_database {
128131
struct commit_graph *commit_graph;
129132
unsigned commit_graph_attempted : 1; /* if loading has been attempted */
130133

131-
/* Should only be accessed directly by packfile.c and midx.c. */
132-
struct packfile_store *packfiles;
133-
134134
/*
135135
* This is meant to hold a *small* number of objects that you would
136136
* want odb_read_object() to be able to return, but yet you do not want

odb/streaming.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,12 @@ static int istream_source(struct odb_read_stream **out,
185185
{
186186
struct odb_source *source;
187187

188-
if (!packfile_store_read_object_stream(out, odb->packfiles, oid))
189-
return 0;
190-
191188
odb_prepare_alternates(odb);
192-
for (source = odb->sources; source; source = source->next)
193-
if (!odb_source_loose_read_object_stream(out, source, oid))
189+
for (source = odb->sources; source; source = source->next) {
190+
if (!packfile_store_read_object_stream(out, source->packfiles, oid) ||
191+
!odb_source_loose_read_object_stream(out, source, oid))
194192
return 0;
193+
}
195194

196195
return open_istream_incore(out, odb, oid);
197196
}

0 commit comments

Comments
 (0)