Skip to content

Commit b336144

Browse files
jltoblergitster
authored andcommitted
bulk-checkin: remove global transaction state
Object database transactions in the bulk-checkin subsystem rely on global state to track transaction status. Stop relying on global state and instead store the transaction in the `struct object_database`. Functions that operate on transactions are updated to now wire transaction state. Signed-off-by: Justin Tobler <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9851830 commit b336144

File tree

9 files changed

+94
-52
lines changed

9 files changed

+94
-52
lines changed

builtin/add.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ int cmd_add(int argc,
389389
char *seen = NULL;
390390
char *ps_matched = NULL;
391391
struct lock_file lock_file = LOCK_INIT;
392+
struct odb_transaction *transaction;
392393

393394
repo_config(repo, add_config, NULL);
394395

@@ -574,7 +575,7 @@ int cmd_add(int argc,
574575
string_list_clear(&only_match_skip_worktree, 0);
575576
}
576577

577-
begin_odb_transaction();
578+
transaction = begin_odb_transaction(repo->objects);
578579

579580
ps_matched = xcalloc(pathspec.nr, 1);
580581
if (add_renormalize)
@@ -593,7 +594,7 @@ int cmd_add(int argc,
593594

594595
if (chmod_arg && pathspec.nr)
595596
exit_status |= chmod_pathspec(repo, &pathspec, chmod_arg[0], show_only);
596-
end_odb_transaction();
597+
end_odb_transaction(transaction);
597598

598599
finish:
599600
if (write_locked_index(repo->index, &lock_file,

builtin/unpack-objects.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ static void unpack_all(void)
584584
{
585585
int i;
586586
unsigned char *hdr = fill(sizeof(struct pack_header));
587+
struct odb_transaction *transaction;
587588

588589
if (get_be32(hdr) != PACK_SIGNATURE)
589590
die("bad pack file");
@@ -599,12 +600,12 @@ static void unpack_all(void)
599600
progress = start_progress(the_repository,
600601
_("Unpacking objects"), nr_objects);
601602
CALLOC_ARRAY(obj_list, nr_objects);
602-
begin_odb_transaction();
603+
transaction = begin_odb_transaction(the_repository->objects);
603604
for (i = 0; i < nr_objects; i++) {
604605
unpack_one(i);
605606
display_progress(progress, i + 1);
606607
}
607-
end_odb_transaction();
608+
end_odb_transaction(transaction);
608609
stop_progress(&progress);
609610

610611
if (delta_list)

builtin/update-index.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static void report(const char *fmt, ...)
7777
* objects invisible while a transaction is active, so flush the
7878
* transaction here before reporting a change made by update-index.
7979
*/
80-
flush_odb_transaction();
80+
flush_odb_transaction(the_repository->objects->transaction);
8181
va_start(vp, fmt);
8282
vprintf(fmt, vp);
8383
putchar('\n');
@@ -940,6 +940,7 @@ int cmd_update_index(int argc,
940940
strbuf_getline_fn getline_fn;
941941
int parseopt_state = PARSE_OPT_UNKNOWN;
942942
struct repository *r = the_repository;
943+
struct odb_transaction *transaction;
943944
struct option options[] = {
944945
OPT_BIT('q', NULL, &refresh_args.flags,
945946
N_("continue refresh even when index needs update"),
@@ -1130,7 +1131,7 @@ int cmd_update_index(int argc,
11301131
* Allow the object layer to optimize adding multiple objects in
11311132
* a batch.
11321133
*/
1133-
begin_odb_transaction();
1134+
transaction = begin_odb_transaction(the_repository->objects);
11341135
while (ctx.argc) {
11351136
if (parseopt_state != PARSE_OPT_DONE)
11361137
parseopt_state = parse_options_step(&ctx, options,
@@ -1213,7 +1214,7 @@ int cmd_update_index(int argc,
12131214
/*
12141215
* By now we have added all of the new objects
12151216
*/
1216-
end_odb_transaction();
1217+
end_odb_transaction(transaction);
12171218

12181219
if (split_index > 0) {
12191220
if (repo_config_get_split_index(the_repository) == 0)

bulk-checkin.c

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ struct bulk_checkin_packfile {
3030
uint32_t nr_written;
3131
};
3232

33-
static struct odb_transaction {
33+
struct odb_transaction {
34+
struct object_database *odb;
35+
3436
int nesting;
3537
struct tmp_objdir *objdir;
3638
struct bulk_checkin_packfile packfile;
37-
} transaction;
39+
};
3840

3941
static void finish_tmp_packfile(struct strbuf *basename,
4042
const char *pack_tmp_name,
@@ -98,12 +100,12 @@ static void flush_bulk_checkin_packfile(struct bulk_checkin_packfile *state)
98100
/*
99101
* Cleanup after batch-mode fsync_object_files.
100102
*/
101-
static void flush_batch_fsync(void)
103+
static void flush_batch_fsync(struct odb_transaction *transaction)
102104
{
103105
struct strbuf temp_path = STRBUF_INIT;
104106
struct tempfile *temp;
105107

106-
if (!transaction.objdir)
108+
if (!transaction->objdir)
107109
return;
108110

109111
/*
@@ -125,8 +127,8 @@ static void flush_batch_fsync(void)
125127
* Make the object files visible in the primary ODB after their data is
126128
* fully durable.
127129
*/
128-
tmp_objdir_migrate(transaction.objdir);
129-
transaction.objdir = NULL;
130+
tmp_objdir_migrate(transaction->objdir);
131+
transaction->objdir = NULL;
130132
}
131133

132134
static int already_written(struct bulk_checkin_packfile *state, struct object_id *oid)
@@ -325,23 +327,24 @@ static int deflate_blob_to_pack(struct bulk_checkin_packfile *state,
325327
return 0;
326328
}
327329

328-
void prepare_loose_object_bulk_checkin(void)
330+
void prepare_loose_object_bulk_checkin(struct odb_transaction *transaction)
329331
{
330332
/*
331333
* We lazily create the temporary object directory
332334
* the first time an object might be added, since
333335
* callers may not know whether any objects will be
334336
* added at the time they call begin_odb_transaction.
335337
*/
336-
if (!transaction.nesting || transaction.objdir)
338+
if (!transaction || transaction->objdir)
337339
return;
338340

339-
transaction.objdir = tmp_objdir_create(the_repository, "bulk-fsync");
340-
if (transaction.objdir)
341-
tmp_objdir_replace_primary_odb(transaction.objdir, 0);
341+
transaction->objdir = tmp_objdir_create(the_repository, "bulk-fsync");
342+
if (transaction->objdir)
343+
tmp_objdir_replace_primary_odb(transaction->objdir, 0);
342344
}
343345

344-
void fsync_loose_object_bulk_checkin(int fd, const char *filename)
346+
void fsync_loose_object_bulk_checkin(struct odb_transaction *transaction,
347+
int fd, const char *filename)
345348
{
346349
/*
347350
* If we have an active ODB transaction, we issue a call that
@@ -350,44 +353,65 @@ void fsync_loose_object_bulk_checkin(int fd, const char *filename)
350353
* before renaming the objects to their final names as part of
351354
* flush_batch_fsync.
352355
*/
353-
if (!transaction.objdir ||
356+
if (!transaction || !transaction->objdir ||
354357
git_fsync(fd, FSYNC_WRITEOUT_ONLY) < 0) {
355358
if (errno == ENOSYS)
356359
warning(_("core.fsyncMethod = batch is unsupported on this platform"));
357360
fsync_or_die(fd, filename);
358361
}
359362
}
360363

361-
int index_blob_bulk_checkin(struct object_id *oid,
362-
int fd, size_t size,
364+
int index_blob_bulk_checkin(struct odb_transaction *transaction,
365+
struct object_id *oid, int fd, size_t size,
363366
const char *path, unsigned flags)
364367
{
365-
int status = deflate_blob_to_pack(&transaction.packfile, oid, fd, size,
366-
path, flags);
367-
if (!transaction.nesting)
368-
flush_bulk_checkin_packfile(&transaction.packfile);
368+
int status;
369+
370+
if (transaction) {
371+
status = deflate_blob_to_pack(&transaction->packfile, oid, fd,
372+
size, path, flags);
373+
} else {
374+
struct bulk_checkin_packfile state = { 0 };
375+
376+
status = deflate_blob_to_pack(&state, oid, fd, size, path, flags);
377+
flush_bulk_checkin_packfile(&state);
378+
}
379+
369380
return status;
370381
}
371382

372-
void begin_odb_transaction(void)
383+
struct odb_transaction *begin_odb_transaction(struct object_database *odb)
373384
{
374-
transaction.nesting += 1;
385+
if (!odb->transaction) {
386+
CALLOC_ARRAY(odb->transaction, 1);
387+
odb->transaction->odb = odb;
388+
}
389+
390+
odb->transaction->nesting += 1;
391+
392+
return odb->transaction;
375393
}
376394

377-
void flush_odb_transaction(void)
395+
void flush_odb_transaction(struct odb_transaction *transaction)
378396
{
379-
flush_batch_fsync();
380-
flush_bulk_checkin_packfile(&transaction.packfile);
397+
if (!transaction)
398+
return;
399+
400+
flush_batch_fsync(transaction);
401+
flush_bulk_checkin_packfile(&transaction->packfile);
381402
}
382403

383-
void end_odb_transaction(void)
404+
void end_odb_transaction(struct odb_transaction *transaction)
384405
{
385-
transaction.nesting -= 1;
386-
if (transaction.nesting < 0)
406+
if (!transaction || transaction->nesting == 0)
387407
BUG("Unbalanced ODB transaction nesting");
388408

389-
if (transaction.nesting)
409+
transaction->nesting -= 1;
410+
411+
if (transaction->nesting)
390412
return;
391413

392-
flush_odb_transaction();
414+
flush_odb_transaction(transaction);
415+
transaction->odb->transaction = NULL;
416+
free(transaction);
393417
}

bulk-checkin.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@
55
#define BULK_CHECKIN_H
66

77
#include "object.h"
8+
#include "odb.h"
89

9-
void prepare_loose_object_bulk_checkin(void);
10-
void fsync_loose_object_bulk_checkin(int fd, const char *filename);
10+
struct odb_transaction;
11+
12+
void prepare_loose_object_bulk_checkin(struct odb_transaction *transaction);
13+
void fsync_loose_object_bulk_checkin(struct odb_transaction *transaction,
14+
int fd, const char *filename);
1115

1216
/*
1317
* This creates one packfile per large blob unless bulk-checkin
@@ -24,8 +28,8 @@ void fsync_loose_object_bulk_checkin(int fd, const char *filename);
2428
* binary blobs, they generally do not want to get any conversion, and
2529
* callers should avoid this code path when filters are requested.
2630
*/
27-
int index_blob_bulk_checkin(struct object_id *oid,
28-
int fd, size_t size,
31+
int index_blob_bulk_checkin(struct odb_transaction *transaction,
32+
struct object_id *oid, int fd, size_t size,
2933
const char *path, unsigned flags);
3034

3135
/*
@@ -35,20 +39,20 @@ int index_blob_bulk_checkin(struct object_id *oid,
3539
* and objects are only visible after the outermost transaction
3640
* is complete or the transaction is flushed.
3741
*/
38-
void begin_odb_transaction(void);
42+
struct odb_transaction *begin_odb_transaction(struct object_database *odb);
3943

4044
/*
4145
* Make any objects that are currently part of a pending object
4246
* database transaction visible. It is valid to call this function
4347
* even if no transaction is active.
4448
*/
45-
void flush_odb_transaction(void);
49+
void flush_odb_transaction(struct odb_transaction *transaction);
4650

4751
/*
4852
* Tell the object database to make any objects from the
4953
* current transaction visible if this is the final nested
5054
* transaction.
5155
*/
52-
void end_odb_transaction(void);
56+
void end_odb_transaction(struct odb_transaction *transaction);
5357

5458
#endif

cache-tree.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ static int update_one(struct cache_tree *it,
474474

475475
int cache_tree_update(struct index_state *istate, int flags)
476476
{
477+
struct odb_transaction *transaction;
477478
int skip, i;
478479

479480
i = verify_cache(istate, flags);
@@ -489,10 +490,10 @@ int cache_tree_update(struct index_state *istate, int flags)
489490

490491
trace_performance_enter();
491492
trace2_region_enter("cache_tree", "update", the_repository);
492-
begin_odb_transaction();
493+
transaction = begin_odb_transaction(the_repository->objects);
493494
i = update_one(istate->cache_tree, istate->cache, istate->cache_nr,
494495
"", 0, &skip, flags);
495-
end_odb_transaction();
496+
end_odb_transaction(transaction);
496497
trace2_region_leave("cache_tree", "update", the_repository);
497498
trace_performance_leave("cache_tree_update");
498499
if (i < 0)

object-file.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ static void close_loose_object(struct odb_source *source,
674674
goto out;
675675

676676
if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT))
677-
fsync_loose_object_bulk_checkin(fd, filename);
677+
fsync_loose_object_bulk_checkin(source->odb->transaction, fd, filename);
678678
else if (fsync_object_files > 0)
679679
fsync_or_die(fd, filename);
680680
else
@@ -852,7 +852,7 @@ static int write_loose_object(struct odb_source *source,
852852
static struct strbuf filename = STRBUF_INIT;
853853

854854
if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT))
855-
prepare_loose_object_bulk_checkin();
855+
prepare_loose_object_bulk_checkin(source->odb->transaction);
856856

857857
odb_loose_path(source, &filename, oid);
858858

@@ -941,7 +941,7 @@ int stream_loose_object(struct odb_source *source,
941941
int hdrlen;
942942

943943
if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT))
944-
prepare_loose_object_bulk_checkin();
944+
prepare_loose_object_bulk_checkin(source->odb->transaction);
945945

946946
/* Since oid is not determined, save tmp file to odb path. */
947947
strbuf_addf(&filename, "%s/", source->path);
@@ -1263,8 +1263,9 @@ int index_fd(struct index_state *istate, struct object_id *oid,
12631263
ret = index_core(istate, oid, fd, xsize_t(st->st_size),
12641264
type, path, flags);
12651265
else
1266-
ret = index_blob_bulk_checkin(oid, fd, xsize_t(st->st_size), path,
1267-
flags);
1266+
ret = index_blob_bulk_checkin(the_repository->objects->transaction,
1267+
oid, fd, xsize_t(st->st_size),
1268+
path, flags);
12681269
close(fd);
12691270
return ret;
12701271
}

odb.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct odb_source {
8484

8585
struct packed_git;
8686
struct cached_object_entry;
87+
struct odb_transaction;
8788

8889
/*
8990
* The object database encapsulates access to objects in a repository. It
@@ -94,6 +95,13 @@ struct object_database {
9495
/* Repository that owns this database. */
9596
struct repository *repo;
9697

98+
/*
99+
* State of current current object database transaction. Only one
100+
* transaction may be pending at a time. Is NULL when no transaction is
101+
* configured.
102+
*/
103+
struct odb_transaction *transaction;
104+
97105
/*
98106
* Set of all object directories; the main directory is first (and
99107
* cannot be NULL after initialization). Subsequent directories are

read-cache.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3947,6 +3947,7 @@ int add_files_to_cache(struct repository *repo, const char *prefix,
39473947
const struct pathspec *pathspec, char *ps_matched,
39483948
int include_sparse, int flags)
39493949
{
3950+
struct odb_transaction *transaction;
39503951
struct update_callback_data data;
39513952
struct rev_info rev;
39523953

@@ -3972,9 +3973,9 @@ int add_files_to_cache(struct repository *repo, const char *prefix,
39723973
* This function is invoked from commands other than 'add', which
39733974
* may not have their own transaction active.
39743975
*/
3975-
begin_odb_transaction();
3976+
transaction = begin_odb_transaction(repo->objects);
39763977
run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
3977-
end_odb_transaction();
3978+
end_odb_transaction(transaction);
39783979

39793980
release_revisions(&rev);
39803981
return !!data.add_errors;

0 commit comments

Comments
 (0)