odb/source-loose: wire up `count_objects()` callback
Move `odb_source_loose_count_objects()` and its associated helpers from "object-file.c" into "odb/source-loose.c" and wire it up as the `count_objects()` callback of the loose source. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>main
parent
8a6da81cc1
commit
2ade08ac29
|
|
@ -466,6 +466,7 @@ out:
|
|||
|
||||
static int too_many_loose_objects(int limit)
|
||||
{
|
||||
struct odb_source_files *files = odb_source_files_downcast(the_repository->objects->sources);
|
||||
/*
|
||||
* This is weird, but stems from legacy behaviour: the GC auto
|
||||
* threshold was always essentially interpreted as if it was rounded up
|
||||
|
|
@ -474,9 +475,8 @@ static int too_many_loose_objects(int limit)
|
|||
int auto_threshold = DIV_ROUND_UP(limit, 256) * 256;
|
||||
unsigned long loose_count;
|
||||
|
||||
if (odb_source_loose_count_objects(the_repository->objects->sources,
|
||||
ODB_COUNT_OBJECTS_APPROXIMATE,
|
||||
&loose_count) < 0)
|
||||
if (odb_source_count_objects(&files->loose->base, ODB_COUNT_OBJECTS_APPROXIMATE,
|
||||
&loose_count) < 0)
|
||||
return 0;
|
||||
|
||||
return loose_count > auto_threshold;
|
||||
|
|
|
|||
|
|
@ -1602,66 +1602,6 @@ int for_each_loose_file_in_source(struct odb_source *source,
|
|||
return r;
|
||||
}
|
||||
|
||||
static int count_loose_object(const struct object_id *oid UNUSED,
|
||||
struct object_info *oi UNUSED,
|
||||
void *payload)
|
||||
{
|
||||
unsigned long *count = payload;
|
||||
(*count)++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int odb_source_loose_count_objects(struct odb_source *source,
|
||||
enum odb_count_objects_flags flags,
|
||||
unsigned long *out)
|
||||
{
|
||||
struct odb_source_files *files = odb_source_files_downcast(source);
|
||||
const unsigned hexsz = source->odb->repo->hash_algo->hexsz - 2;
|
||||
char *path = NULL;
|
||||
DIR *dir = NULL;
|
||||
int ret;
|
||||
|
||||
if (flags & ODB_COUNT_OBJECTS_APPROXIMATE) {
|
||||
unsigned long count = 0;
|
||||
struct dirent *ent;
|
||||
|
||||
path = xstrfmt("%s/17", source->path);
|
||||
|
||||
dir = opendir(path);
|
||||
if (!dir) {
|
||||
if (errno == ENOENT) {
|
||||
*out = 0;
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = error_errno("cannot open object shard '%s'", path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((ent = readdir(dir)) != NULL) {
|
||||
if (strspn(ent->d_name, "0123456789abcdef") != hexsz ||
|
||||
ent->d_name[hexsz] != '\0')
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
|
||||
*out = count * 256;
|
||||
ret = 0;
|
||||
} else {
|
||||
struct odb_for_each_object_options opts = { 0 };
|
||||
*out = 0;
|
||||
ret = odb_source_for_each_object(&files->loose->base, NULL, count_loose_object,
|
||||
out, &opts);
|
||||
}
|
||||
|
||||
out:
|
||||
if (dir)
|
||||
closedir(dir);
|
||||
free(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int check_stream_oid(git_zstream *stream,
|
||||
const char *hdr,
|
||||
unsigned long size,
|
||||
|
|
|
|||
|
|
@ -96,20 +96,6 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr,
|
|||
each_loose_subdir_fn subdir_cb,
|
||||
void *data);
|
||||
|
||||
/*
|
||||
* Count the number of loose objects in this source.
|
||||
*
|
||||
* The object count is approximated by opening a single sharding directory for
|
||||
* loose objects and scanning its contents. The result is then extrapolated by
|
||||
* 256. This should generally work as a reasonable estimate given that the
|
||||
* object hash is supposed to be indistinguishable from random.
|
||||
*
|
||||
* Returns 0 on success, a negative error code otherwise.
|
||||
*/
|
||||
int odb_source_loose_count_objects(struct odb_source *source,
|
||||
enum odb_count_objects_flags flags,
|
||||
unsigned long *out);
|
||||
|
||||
/**
|
||||
* format_object_header() is a thin wrapper around s xsnprintf() that
|
||||
* writes the initial "<type> <obj-len>" part of the loose object
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ static int odb_source_files_count_objects(struct odb_source *source,
|
|||
if (!(flags & ODB_COUNT_OBJECTS_APPROXIMATE)) {
|
||||
unsigned long loose_count;
|
||||
|
||||
ret = odb_source_loose_count_objects(source, flags, &loose_count);
|
||||
ret = odb_source_count_objects(&files->loose->base, flags, &loose_count);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
|
|
|
|||
|
|
@ -520,6 +520,66 @@ static int odb_source_loose_find_abbrev_len(struct odb_source *source,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int count_loose_object(const struct object_id *oid UNUSED,
|
||||
struct object_info *oi UNUSED,
|
||||
void *payload)
|
||||
{
|
||||
unsigned long *count = payload;
|
||||
(*count)++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int odb_source_loose_count_objects(struct odb_source *source,
|
||||
enum odb_count_objects_flags flags,
|
||||
unsigned long *out)
|
||||
{
|
||||
struct odb_source_loose *loose = odb_source_loose_downcast(source);
|
||||
const unsigned hexsz = source->odb->repo->hash_algo->hexsz - 2;
|
||||
char *path = NULL;
|
||||
DIR *dir = NULL;
|
||||
int ret;
|
||||
|
||||
if (flags & ODB_COUNT_OBJECTS_APPROXIMATE) {
|
||||
unsigned long count = 0;
|
||||
struct dirent *ent;
|
||||
|
||||
path = xstrfmt("%s/17", source->path);
|
||||
|
||||
dir = opendir(path);
|
||||
if (!dir) {
|
||||
if (errno == ENOENT) {
|
||||
*out = 0;
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = error_errno("cannot open object shard '%s'", path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((ent = readdir(dir)) != NULL) {
|
||||
if (strspn(ent->d_name, "0123456789abcdef") != hexsz ||
|
||||
ent->d_name[hexsz] != '\0')
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
|
||||
*out = count * 256;
|
||||
ret = 0;
|
||||
} else {
|
||||
struct odb_for_each_object_options opts = { 0 };
|
||||
*out = 0;
|
||||
ret = odb_source_for_each_object(&loose->base, NULL, count_loose_object,
|
||||
out, &opts);
|
||||
}
|
||||
|
||||
out:
|
||||
if (dir)
|
||||
closedir(dir);
|
||||
free(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void odb_source_loose_clear_cache(struct odb_source_loose *loose)
|
||||
{
|
||||
oidtree_clear(loose->cache);
|
||||
|
|
@ -577,6 +637,7 @@ struct odb_source_loose *odb_source_loose_new(struct odb_source_files *files)
|
|||
loose->base.read_object_stream = odb_source_loose_read_object_stream;
|
||||
loose->base.for_each_object = odb_source_loose_for_each_object;
|
||||
loose->base.find_abbrev_len = odb_source_loose_find_abbrev_len;
|
||||
loose->base.count_objects = odb_source_loose_count_objects;
|
||||
|
||||
if (!is_absolute_path(loose->base.path))
|
||||
chdir_notify_register(NULL, odb_source_loose_reparent, loose);
|
||||
|
|
|
|||
Loading…
Reference in New Issue