mirror of
https://github.com/git/git.git
synced 2026-03-11 09:29:49 +01:00
object-file: generalize counting objects
Generalize the function introduced in the preceding commit to not only be able to approximate the number of loose objects, but to also provide an accurate count. The behaviour can be toggled via a new flag. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
3b5ca32b5f
commit
f7d1918469
@@ -474,8 +474,9 @@ 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_approximate_object_count(the_repository->objects->sources,
|
||||
&loose_count) < 0)
|
||||
if (odb_source_loose_count_objects(the_repository->objects->sources,
|
||||
ODB_COUNT_OBJECTS_APPROXIMATE,
|
||||
&loose_count) < 0)
|
||||
return 0;
|
||||
|
||||
return loose_count > auto_threshold;
|
||||
|
||||
@@ -1868,40 +1868,56 @@ int odb_source_loose_for_each_object(struct odb_source *source,
|
||||
NULL, NULL, &data);
|
||||
}
|
||||
|
||||
int odb_source_loose_approximate_object_count(struct odb_source *source,
|
||||
unsigned long *out)
|
||||
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)
|
||||
{
|
||||
const unsigned hexsz = source->odb->repo->hash_algo->hexsz - 2;
|
||||
unsigned long count = 0;
|
||||
struct dirent *ent;
|
||||
char *path = NULL;
|
||||
DIR *dir = NULL;
|
||||
int ret;
|
||||
|
||||
path = xstrfmt("%s/17", source->path);
|
||||
if (flags & ODB_COUNT_OBJECTS_APPROXIMATE) {
|
||||
unsigned long count = 0;
|
||||
struct dirent *ent;
|
||||
|
||||
dir = opendir(path);
|
||||
if (!dir) {
|
||||
if (errno == ENOENT) {
|
||||
*out = 0;
|
||||
ret = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
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 {
|
||||
ret = odb_source_loose_for_each_object(source, NULL, count_loose_object,
|
||||
out, 0);
|
||||
}
|
||||
|
||||
*out = count * 256;
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
if (dir)
|
||||
closedir(dir);
|
||||
|
||||
@@ -149,8 +149,9 @@ int odb_source_loose_for_each_object(struct odb_source *source,
|
||||
*
|
||||
* Returns 0 on success, a negative error code otherwise.
|
||||
*/
|
||||
int odb_source_loose_approximate_object_count(struct odb_source *source,
|
||||
unsigned long *out);
|
||||
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
|
||||
|
||||
9
odb.h
9
odb.h
@@ -500,6 +500,15 @@ int odb_for_each_object(struct object_database *odb,
|
||||
void *cb_data,
|
||||
unsigned flags);
|
||||
|
||||
enum odb_count_objects_flags {
|
||||
/*
|
||||
* Instead of providing an accurate count, allow the number of objects
|
||||
* to be approximated. Details of how this approximation works are
|
||||
* subject to the specific source's implementation.
|
||||
*/
|
||||
ODB_COUNT_OBJECTS_APPROXIMATE = (1 << 0),
|
||||
};
|
||||
|
||||
enum {
|
||||
/*
|
||||
* By default, `odb_write_object()` does not actually write anything
|
||||
|
||||
Reference in New Issue
Block a user