diff options
| author | Edward Thomson <ethomson@edwardthomson.com> | 2021-12-12 09:19:25 -0500 |
|---|---|---|
| committer | Edward Thomson <ethomson@edwardthomson.com> | 2022-06-20 17:09:47 -0400 |
| commit | 4d7ec76c42d9bcf2ed4f59e0efff2f4e6e810808 (patch) | |
| tree | 39a049a75076b45abefe99554a21637c63f1abd2 | |
| parent | dbccfc203e776196ea2901dbcb652bba6a848a30 (diff) | |
| download | libgit2-4d7ec76c42d9bcf2ed4f59e0efff2f4e6e810808.tar.gz | |
odb: add git_odb_loose_backend_options
Move the arguments to `git_odb_loose` into an options structure.
| -rw-r--r-- | include/git2/odb_backend.h | 46 | ||||
| -rw-r--r-- | src/libgit2/odb.c | 6 | ||||
| -rw-r--r-- | src/libgit2/odb_loose.c | 59 | ||||
| -rw-r--r-- | tests/libgit2/odb/loose.c | 15 | ||||
| -rw-r--r-- | tests/libgit2/odb/sorting.c | 3 |
5 files changed, 91 insertions, 38 deletions
diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h index d93ac7348..d65aeec5a 100644 --- a/include/git2/odb_backend.h +++ b/include/git2/odb_backend.h @@ -34,25 +34,55 @@ GIT_BEGIN_DECL */ GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir); +typedef enum { + GIT_ODB_BACKEND_LOOSE_FSYNC = (1 << 0) +} git_odb_backend_loose_flag_t; + +/** Options for configuring a loose object backend. */ +typedef struct { + unsigned int version; /**< version for the struct */ + + /** A combination of the `git_odb_backend_loose_flag_t` types. */ + uint32_t flags; + + /** + * zlib compression level to use (0-9), where 1 is the fastest + * at the expense of larger files, and 9 produces the best + * compression at the expense of speed. 0 indicates that no + * compression should be performed. -1 is the default (currently + * optimizing for speed). + */ + int compression_level; + + /** Permissions to use creating a directory or 0 for defaults */ + unsigned int dir_mode; + + /** Permissions to use creating a file or 0 for defaults */ + unsigned int file_mode; +} git_odb_backend_loose_options; + +/* The current version of the diff options structure */ +#define GIT_ODB_BACKEND_LOOSE_OPTIONS_VERSION 1 + +/* Stack initializer for diff options. Alternatively use + * `git_diff_options_init` programmatic initialization. + */ +#define GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT \ + { GIT_ODB_BACKEND_LOOSE_OPTIONS_VERSION, 0, -1 } + /** * Create a backend for loose objects * * @param out location to store the odb backend pointer * @param objects_dir the Git repository's objects directory - * @param compression_level zlib compression level to use - * @param do_fsync whether to do an fsync() after writing - * @param dir_mode permissions to use creating a directory or 0 for defaults - * @param file_mode permissions to use creating a file or 0 for defaults + * @param opts options for the loose object backend or NULL * * @return 0 or an error code */ GIT_EXTERN(int) git_odb_backend_loose( git_odb_backend **out, const char *objects_dir, - int compression_level, - int do_fsync, - unsigned int dir_mode, - unsigned int file_mode); + git_odb_backend_loose_options *opts); /** * Create a backend out of a single packfile diff --git a/src/libgit2/odb.c b/src/libgit2/odb.c index 4e2e07af3..1f9911dcc 100644 --- a/src/libgit2/odb.c +++ b/src/libgit2/odb.c @@ -625,6 +625,7 @@ int git_odb__add_default_backends( struct stat st; ino_t inode; git_odb_backend *loose, *packed; + git_odb_backend_loose_options loose_opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT; /* TODO: inodes are not really relevant on Win32, so we need to find * a cross-platform workaround for this */ @@ -659,8 +660,11 @@ int git_odb__add_default_backends( git_mutex_unlock(&db->lock); #endif + if (db->do_fsync) + loose_opts.flags |= GIT_ODB_BACKEND_LOOSE_FSYNC; + /* add the loose object backend */ - if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 || + if (git_odb_backend_loose(&loose, objects_dir, &loose_opts) < 0 || add_backend_internal(db, loose, git_odb__loose_priority, as_alternates, inode) < 0) return -1; diff --git a/src/libgit2/odb_loose.c b/src/libgit2/odb_loose.c index f5013df5d..1885fa293 100644 --- a/src/libgit2/odb_loose.c +++ b/src/libgit2/odb_loose.c @@ -46,10 +46,7 @@ typedef struct { typedef struct loose_backend { git_odb_backend parent; - int object_zlib_level; /** loose object zlib compression level. */ - int fsync_object_files; /** loose object file fsync flag. */ - mode_t object_file_mode; - mode_t object_dir_mode; + git_odb_backend_loose_options options; size_t objects_dirlen; char objects_dir[GIT_FLEX_ARRAY]; @@ -100,7 +97,9 @@ static int object_file_name( static int object_mkdir(const git_str *name, const loose_backend *be) { return git_futils_mkdir_relative( - name->ptr + be->objects_dirlen, be->objects_dir, be->object_dir_mode, + name->ptr + be->objects_dirlen, + be->objects_dir, + be->options.dir_mode, GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR, NULL); } @@ -827,9 +826,10 @@ static void loose_backend__writestream_free(git_odb_stream *_stream) static int filebuf_flags(loose_backend *backend) { int flags = GIT_FILEBUF_TEMPORARY | - (backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT); + (backend->options.compression_level << GIT_FILEBUF_DEFLATE_SHIFT); - if (backend->fsync_object_files || git_repository__fsync_gitdir) + if ((backend->options.flags & GIT_ODB_BACKEND_LOOSE_FSYNC) || + git_repository__fsync_gitdir) flags |= GIT_FILEBUF_FSYNC; return flags; @@ -865,7 +865,7 @@ static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backe if (git_str_joinpath(&tmp_path, backend->objects_dir, "tmp_object") < 0 || git_filebuf_open(&stream->fbuf, tmp_path.ptr, filebuf_flags(backend), - backend->object_file_mode) < 0 || + backend->options.file_mode) < 0 || stream->stream.write((git_odb_stream *)stream, hdr, hdrlen) < 0) { git_filebuf_cleanup(&stream->fbuf); @@ -1083,7 +1083,7 @@ static int loose_backend__write(git_odb_backend *_backend, const git_oid *oid, c if (git_str_joinpath(&final_path, backend->objects_dir, "tmp_object") < 0 || git_filebuf_open(&fbuf, final_path.ptr, filebuf_flags(backend), - backend->object_file_mode) < 0) + backend->options.file_mode) < 0) { error = -1; goto cleanup; @@ -1126,13 +1126,31 @@ static void loose_backend__free(git_odb_backend *_backend) git__free(_backend); } +static void normalize_options( + git_odb_backend_loose_options *opts, + const git_odb_backend_loose_options *given_opts) +{ + git_odb_backend_loose_options init = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT; + + if (given_opts) + memcpy(opts, given_opts, sizeof(git_odb_backend_loose_options)); + else + memcpy(opts, &init, sizeof(git_odb_backend_loose_options)); + + if (opts->compression_level < 0) + opts->compression_level = Z_BEST_SPEED; + + if (opts->dir_mode == 0) + opts->dir_mode = GIT_OBJECT_DIR_MODE; + + if (opts->file_mode == 0) + opts->file_mode = GIT_OBJECT_FILE_MODE; +} + int git_odb_backend_loose( git_odb_backend **backend_out, const char *objects_dir, - int compression_level, - int do_fsync, - unsigned int dir_mode, - unsigned int file_mode) + git_odb_backend_loose_options *opts) { loose_backend *backend; size_t objects_dirlen, alloclen; @@ -1150,22 +1168,11 @@ int git_odb_backend_loose( backend->parent.version = GIT_ODB_BACKEND_VERSION; backend->objects_dirlen = objects_dirlen; memcpy(backend->objects_dir, objects_dir, objects_dirlen); + if (backend->objects_dir[backend->objects_dirlen - 1] != '/') backend->objects_dir[backend->objects_dirlen++] = '/'; - if (compression_level < 0) - compression_level = Z_BEST_SPEED; - - if (dir_mode == 0) - dir_mode = GIT_OBJECT_DIR_MODE; - - if (file_mode == 0) - file_mode = GIT_OBJECT_FILE_MODE; - - backend->object_zlib_level = compression_level; - backend->fsync_object_files = do_fsync; - backend->object_dir_mode = dir_mode; - backend->object_file_mode = file_mode; + normalize_options(&backend->options, opts); backend->parent.read = &loose_backend__read; backend->parent.write = &loose_backend__write; diff --git a/tests/libgit2/odb/loose.c b/tests/libgit2/odb/loose.c index 5da1f09df..20b329f69 100644 --- a/tests/libgit2/odb/loose.c +++ b/tests/libgit2/odb/loose.c @@ -196,6 +196,7 @@ static void test_write_object_permission( git_oid oid; struct stat statbuf; mode_t mask, os_mask; + git_odb_backend_loose_options opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT; /* Windows does not return group/user bits from stat, * files are never executable. @@ -209,8 +210,11 @@ static void test_write_object_permission( mask = p_umask(0); p_umask(mask); + opts.dir_mode = dir_mode; + opts.file_mode = file_mode; + cl_git_pass(git_odb_new(&odb, NULL)); - cl_git_pass(git_odb_backend_loose(&backend, "test-objects", -1, 0, dir_mode, file_mode)); + cl_git_pass(git_odb_backend_loose(&backend, "test-objects", &opts)); cl_git_pass(git_odb_add_backend(odb, backend, 1)); cl_git_pass(git_odb_write(&oid, odb, "Test data\n", 10, GIT_OBJECT_BLOB)); @@ -243,9 +247,16 @@ static void write_object_to_loose_odb(int fsync) git_odb *odb; git_odb_backend *backend; git_oid oid; + git_odb_backend_loose_options opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT; + + if (fsync) + opts.flags |= GIT_ODB_BACKEND_LOOSE_FSYNC; + + opts.dir_mode = 0777; + opts.file_mode = 0666; cl_git_pass(git_odb_new(&odb, NULL)); - cl_git_pass(git_odb_backend_loose(&backend, "test-objects", -1, fsync, 0777, 0666)); + cl_git_pass(git_odb_backend_loose(&backend, "test-objects", &opts)); cl_git_pass(git_odb_add_backend(odb, backend, 1)); cl_git_pass(git_odb_write(&oid, odb, "Test data\n", 10, GIT_OBJECT_BLOB)); git_odb_free(odb); diff --git a/tests/libgit2/odb/sorting.c b/tests/libgit2/odb/sorting.c index 36c45071e..33ce289b5 100644 --- a/tests/libgit2/odb/sorting.c +++ b/tests/libgit2/odb/sorting.c @@ -79,10 +79,11 @@ void test_odb_sorting__override_default_backend_priority(void) { git_odb *new_odb; git_odb_backend *loose, *packed, *backend; + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_LOOSE_PRIORITY, 5)); cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_PACKED_PRIORITY, 3)); git_odb_backend_pack(&packed, "./testrepo.git/objects"); - git_odb_backend_loose(&loose, "./testrepo.git/objects", -1, 0, 0, 0); + git_odb_backend_loose(&loose, "./testrepo.git/objects", NULL); cl_git_pass(git_odb_open(&new_odb, cl_fixture("testrepo.git/objects"), NULL)); cl_assert_equal_sz(2, git_odb_num_backends(new_odb)); |
