mirror of
https://github.com/git/git.git
synced 2026-08-08 00:52:31 +00:00
Merge branch 'ps/odb-generalize-prepare'
The 'reprepare()' callback for object database sources has been generalized into a 'prepare()' callback with an optional flush cache flag, and a new 'odb_prepare()' wrapper has been introduced to allow pre-opening object database sources. * ps/odb-generalize-prepare: odb: introduce `odb_prepare()` odb/source: generalize `reprepare()` callback
This commit is contained in:
@@ -25,12 +25,11 @@
|
||||
#include "setup.h"
|
||||
#include "submodule.h"
|
||||
#include "submodule-config.h"
|
||||
#include "object-file.h"
|
||||
#include "object-name.h"
|
||||
#include "odb.h"
|
||||
#include "odb/source.h"
|
||||
#include "oid-array.h"
|
||||
#include "oidset.h"
|
||||
#include "packfile.h"
|
||||
#include "pager.h"
|
||||
#include "path.h"
|
||||
#include "promisor-remote.h"
|
||||
@@ -1357,15 +1356,8 @@ int cmd_grep(int argc,
|
||||
if (recurse_submodules)
|
||||
repo_read_gitmodules(the_repository, 1);
|
||||
|
||||
if (startup_info->have_repository) {
|
||||
struct odb_source *source;
|
||||
|
||||
odb_prepare_alternates(the_repository->objects);
|
||||
for (source = the_repository->objects->sources; source; source = source->next) {
|
||||
struct odb_source_files *files = odb_source_files_downcast(source);
|
||||
odb_source_packed_prepare(files->packed);
|
||||
}
|
||||
}
|
||||
if (startup_info->have_repository)
|
||||
odb_prepare(the_repository->objects, 0);
|
||||
|
||||
start_threads(&opt);
|
||||
} else {
|
||||
|
||||
2
midx.c
2
midx.c
@@ -101,7 +101,7 @@ static int midx_read_object_offsets(const unsigned char *chunk_start,
|
||||
|
||||
struct multi_pack_index *get_multi_pack_index(struct odb_source_packed *source)
|
||||
{
|
||||
odb_source_packed_prepare(source);
|
||||
odb_source_prepare(&source->base, 0);
|
||||
return source->midx;
|
||||
}
|
||||
|
||||
|
||||
18
odb.c
18
odb.c
@@ -1070,7 +1070,7 @@ void odb_free(struct object_database *o)
|
||||
free(o);
|
||||
}
|
||||
|
||||
void odb_reprepare(struct object_database *o)
|
||||
void odb_prepare(struct object_database *o, enum odb_prepare_flags flags)
|
||||
{
|
||||
struct odb_source *source;
|
||||
|
||||
@@ -1082,13 +1082,19 @@ void odb_reprepare(struct object_database *o)
|
||||
* the linked list, so existing odbs will continue to exist for
|
||||
* the lifetime of the process.
|
||||
*/
|
||||
o->loaded_alternates = 0;
|
||||
if (flags & ODB_PREPARE_FLUSH_CACHES) {
|
||||
o->loaded_alternates = 0;
|
||||
o->object_count_valid = 0;
|
||||
}
|
||||
|
||||
odb_prepare_alternates(o);
|
||||
|
||||
for (source = o->sources; source; source = source->next)
|
||||
odb_source_reprepare(source);
|
||||
|
||||
o->object_count_valid = 0;
|
||||
odb_source_prepare(source, flags);
|
||||
|
||||
obj_read_unlock();
|
||||
}
|
||||
|
||||
void odb_reprepare(struct object_database *o)
|
||||
{
|
||||
odb_prepare(o, ODB_PREPARE_FLUSH_CACHES);
|
||||
}
|
||||
|
||||
16
odb.h
16
odb.h
@@ -124,10 +124,22 @@ void odb_free(struct object_database *o);
|
||||
*/
|
||||
void odb_close(struct object_database *o);
|
||||
|
||||
enum odb_prepare_flags {
|
||||
/*
|
||||
* Flush caches, reload alternates and then re-prepare each object
|
||||
* source so that new objects may become accessible.
|
||||
*/
|
||||
ODB_PREPARE_FLUSH_CACHES = (1 << 0),
|
||||
};
|
||||
|
||||
/*
|
||||
* Clear caches, reload alternates and then reload object sources so that new
|
||||
* objects may become accessible.
|
||||
* Prepare the object database for use. Calling this function is generally not
|
||||
* needed, but can be useful in case the caller wants to pre-open individual
|
||||
* sources.
|
||||
*/
|
||||
void odb_prepare(struct object_database *o, enum odb_prepare_flags flags);
|
||||
|
||||
/* Equivalent to `odb_prepare(o, ODB_PREPARE_FLUSH_CACHES)`. */
|
||||
void odb_reprepare(struct object_database *o);
|
||||
|
||||
/*
|
||||
|
||||
@@ -41,11 +41,12 @@ static void odb_source_files_close(struct odb_source *source)
|
||||
odb_source_close(&files->packed->base);
|
||||
}
|
||||
|
||||
static void odb_source_files_reprepare(struct odb_source *source)
|
||||
static void odb_source_files_prepare(struct odb_source *source,
|
||||
enum odb_prepare_flags flags)
|
||||
{
|
||||
struct odb_source_files *files = odb_source_files_downcast(source);
|
||||
odb_source_reprepare(&files->loose->base);
|
||||
odb_source_reprepare(&files->packed->base);
|
||||
odb_source_prepare(&files->loose->base, flags);
|
||||
odb_source_prepare(&files->packed->base, flags);
|
||||
}
|
||||
|
||||
static int odb_source_files_read_object_info(struct odb_source *source,
|
||||
@@ -273,7 +274,7 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb,
|
||||
|
||||
files->base.free = odb_source_files_free;
|
||||
files->base.close = odb_source_files_close;
|
||||
files->base.reprepare = odb_source_files_reprepare;
|
||||
files->base.prepare = odb_source_files_prepare;
|
||||
files->base.read_object_info = odb_source_files_read_object_info;
|
||||
files->base.read_object_stream = odb_source_files_read_object_stream;
|
||||
files->base.for_each_object = odb_source_files_for_each_object;
|
||||
|
||||
@@ -325,7 +325,8 @@ static void odb_source_inmemory_close(struct odb_source *source UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
static void odb_source_inmemory_reprepare(struct odb_source *source UNUSED)
|
||||
static void odb_source_inmemory_prepare(struct odb_source *source UNUSED,
|
||||
enum odb_prepare_flags flags UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -365,7 +366,7 @@ struct odb_source_inmemory *odb_source_inmemory_new(struct object_database *odb)
|
||||
|
||||
source->base.free = odb_source_inmemory_free;
|
||||
source->base.close = odb_source_inmemory_close;
|
||||
source->base.reprepare = odb_source_inmemory_reprepare;
|
||||
source->base.prepare = odb_source_inmemory_prepare;
|
||||
source->base.read_object_info = odb_source_inmemory_read_object_info;
|
||||
source->base.read_object_stream = odb_source_inmemory_read_object_stream;
|
||||
source->base.for_each_object = odb_source_inmemory_for_each_object;
|
||||
|
||||
@@ -664,10 +664,12 @@ static void odb_source_loose_clear_cache(struct odb_source_loose *loose)
|
||||
sizeof(loose->subdir_seen));
|
||||
}
|
||||
|
||||
static void odb_source_loose_reprepare(struct odb_source *source)
|
||||
static void odb_source_loose_prepare(struct odb_source *source,
|
||||
enum odb_prepare_flags flags)
|
||||
{
|
||||
struct odb_source_loose *loose = odb_source_loose_downcast(source);
|
||||
odb_source_loose_clear_cache(loose);
|
||||
if (flags & ODB_PREPARE_FLUSH_CACHES)
|
||||
odb_source_loose_clear_cache(loose);
|
||||
}
|
||||
|
||||
static void odb_source_loose_close(struct odb_source *source UNUSED)
|
||||
@@ -708,7 +710,7 @@ struct odb_source_loose *odb_source_loose_new(struct object_database *odb,
|
||||
|
||||
loose->base.free = odb_source_loose_free;
|
||||
loose->base.close = odb_source_loose_close;
|
||||
loose->base.reprepare = odb_source_loose_reprepare;
|
||||
loose->base.prepare = odb_source_loose_prepare;
|
||||
loose->base.read_object_info = odb_source_loose_read_object_info;
|
||||
loose->base.read_object_stream = odb_source_loose_read_object_stream;
|
||||
loose->base.for_each_object = odb_source_loose_for_each_object;
|
||||
|
||||
@@ -15,7 +15,7 @@ static int find_pack_entry(struct odb_source_packed *store,
|
||||
{
|
||||
struct packfile_list_entry *l;
|
||||
|
||||
odb_source_packed_prepare(store);
|
||||
odb_source_prepare(&store->base, 0);
|
||||
if (store->midx && fill_midx_entry(store->midx, oid, e))
|
||||
return 1;
|
||||
|
||||
@@ -47,7 +47,7 @@ static int odb_source_packed_read_object_info(struct odb_source *source,
|
||||
* been added since the last time we have prepared the packfile store.
|
||||
*/
|
||||
if (flags & OBJECT_INFO_SECOND_READ)
|
||||
odb_source_reprepare(source);
|
||||
odb_source_prepare(source, ODB_PREPARE_FLUSH_CACHES);
|
||||
|
||||
if (!find_pack_entry(packed, oid, &e))
|
||||
return 1;
|
||||
@@ -692,27 +692,25 @@ static int sort_pack(const struct packfile_list_entry *a,
|
||||
return -1;
|
||||
}
|
||||
|
||||
void odb_source_packed_prepare(struct odb_source_packed *source)
|
||||
{
|
||||
if (source->initialized)
|
||||
return;
|
||||
|
||||
prepare_multi_pack_index_one(source);
|
||||
prepare_packed_git_one(source);
|
||||
|
||||
sort_packs(&source->packs.head, sort_pack);
|
||||
for (struct packfile_list_entry *e = source->packs.head; e; e = e->next)
|
||||
if (!e->next)
|
||||
source->packs.tail = e;
|
||||
|
||||
source->initialized = true;
|
||||
}
|
||||
|
||||
static void odb_source_packed_reprepare(struct odb_source *source)
|
||||
static void odb_source_packed_prepare(struct odb_source *source,
|
||||
enum odb_prepare_flags flags)
|
||||
{
|
||||
struct odb_source_packed *packed = odb_source_packed_downcast(source);
|
||||
packed->initialized = false;
|
||||
odb_source_packed_prepare(packed);
|
||||
|
||||
if (flags & ODB_PREPARE_FLUSH_CACHES)
|
||||
packed->initialized = false;
|
||||
if (packed->initialized)
|
||||
return;
|
||||
|
||||
prepare_multi_pack_index_one(packed);
|
||||
prepare_packed_git_one(packed);
|
||||
|
||||
sort_packs(&packed->packs.head, sort_pack);
|
||||
for (struct packfile_list_entry *e = packed->packs.head; e; e = e->next)
|
||||
if (!e->next)
|
||||
packed->packs.tail = e;
|
||||
|
||||
packed->initialized = true;
|
||||
}
|
||||
|
||||
static void odb_source_packed_reparent(const char *name UNUSED,
|
||||
@@ -768,7 +766,7 @@ struct odb_source_packed *odb_source_packed_new(struct object_database *odb,
|
||||
|
||||
packed->base.free = odb_source_packed_free;
|
||||
packed->base.close = odb_source_packed_close;
|
||||
packed->base.reprepare = odb_source_packed_reprepare;
|
||||
packed->base.prepare = odb_source_packed_prepare;
|
||||
packed->base.read_object_info = odb_source_packed_read_object_info;
|
||||
packed->base.read_object_stream = odb_source_packed_read_object_stream;
|
||||
packed->base.for_each_object = odb_source_packed_for_each_object;
|
||||
|
||||
@@ -82,13 +82,4 @@ static inline struct odb_source_packed *odb_source_packed_downcast(struct odb_so
|
||||
return container_of(source, struct odb_source_packed, base);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare the source by loading packfiles and multi-pack indices for
|
||||
* all alternates. This becomes a no-op if the source is already prepared.
|
||||
*
|
||||
* It shouldn't typically be necessary to call this function directly, as
|
||||
* functions that access the source know to prepare it.
|
||||
*/
|
||||
void odb_source_packed_prepare(struct odb_source_packed *source);
|
||||
|
||||
#endif
|
||||
|
||||
16
odb/source.h
16
odb/source.h
@@ -83,11 +83,12 @@ struct odb_source {
|
||||
void (*close)(struct odb_source *source);
|
||||
|
||||
/*
|
||||
* This callback is expected to clear underlying caches of the object
|
||||
* database source. The function is called when the repository has for
|
||||
* example just been repacked so that new objects will become visible.
|
||||
* This callback is expected to prepare the source so that it becomes
|
||||
* ready for use. It optionally clears underlying caches of the object
|
||||
* database source.
|
||||
*/
|
||||
void (*reprepare)(struct odb_source *source);
|
||||
void (*prepare)(struct odb_source *source,
|
||||
enum odb_prepare_flags flags);
|
||||
|
||||
/*
|
||||
* This callback is expected to read object information from the object
|
||||
@@ -308,13 +309,14 @@ static inline void odb_source_close(struct odb_source *source)
|
||||
}
|
||||
|
||||
/*
|
||||
* Reprepare the object database source and clear any caches. Depending on the
|
||||
* Prepare the object database source and clear any caches. Depending on the
|
||||
* backend used this may have the effect that concurrently-written objects
|
||||
* become visible.
|
||||
*/
|
||||
static inline void odb_source_reprepare(struct odb_source *source)
|
||||
static inline void odb_source_prepare(struct odb_source *source,
|
||||
enum odb_prepare_flags flags)
|
||||
{
|
||||
source->reprepare(source);
|
||||
source->prepare(source, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -855,7 +855,7 @@ void for_each_file_in_pack_dir(const char *objdir,
|
||||
|
||||
struct packfile_list_entry *packfile_store_get_packs(struct odb_source_packed *store)
|
||||
{
|
||||
odb_source_packed_prepare(store);
|
||||
odb_source_prepare(&store->base, 0);
|
||||
|
||||
if (store->midx) {
|
||||
struct multi_pack_index *m = store->midx;
|
||||
|
||||
Reference in New Issue
Block a user