Skip to content

Commit 2b24db1

Browse files
pks-tgitster
authored andcommitted
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>
1 parent 222fdde commit 2b24db1

File tree

4 files changed

+53
-25
lines changed

4 files changed

+53
-25
lines changed

builtin/gc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,9 @@ static int too_many_loose_objects(int limit)
474474
int auto_threshold = DIV_ROUND_UP(limit, 256) * 256;
475475
unsigned long loose_count;
476476

477-
if (odb_source_loose_approximate_object_count(the_repository->objects->sources,
478-
&loose_count) < 0)
477+
if (odb_source_loose_count_objects(the_repository->objects->sources,
478+
ODB_COUNT_OBJECTS_APPROXIMATE,
479+
&loose_count) < 0)
479480
return 0;
480481

481482
return loose_count > auto_threshold;

object-file.c

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,40 +1868,57 @@ int odb_source_loose_for_each_object(struct odb_source *source,
18681868
NULL, NULL, &data);
18691869
}
18701870

1871-
int odb_source_loose_approximate_object_count(struct odb_source *source,
1872-
unsigned long *out)
1871+
static int count_loose_object(const struct object_id *oid UNUSED,
1872+
struct object_info *oi UNUSED,
1873+
void *payload)
1874+
{
1875+
unsigned long *count = payload;
1876+
(*count)++;
1877+
return 0;
1878+
}
1879+
1880+
int odb_source_loose_count_objects(struct odb_source *source,
1881+
enum odb_count_objects_flags flags,
1882+
unsigned long *out)
18731883
{
18741884
const unsigned hexsz = source->odb->repo->hash_algo->hexsz - 2;
1875-
unsigned long count = 0;
1876-
struct dirent *ent;
18771885
char *path = NULL;
18781886
DIR *dir = NULL;
18791887
int ret;
18801888

1881-
path = xstrfmt("%s/17", source->path);
1889+
if (flags & ODB_COUNT_OBJECTS_APPROXIMATE) {
1890+
unsigned long count = 0;
1891+
struct dirent *ent;
18821892

1883-
dir = opendir(path);
1884-
if (!dir) {
1885-
if (errno == ENOENT) {
1886-
*out = 0;
1887-
ret = 0;
1893+
path = xstrfmt("%s/17", source->path);
1894+
1895+
dir = opendir(path);
1896+
if (!dir) {
1897+
if (errno == ENOENT) {
1898+
*out = 0;
1899+
ret = 0;
1900+
goto out;
1901+
}
1902+
1903+
ret = error_errno("cannot open object shard '%s'", path);
18881904
goto out;
18891905
}
18901906

1891-
ret = error_errno("cannot open object shard '%s'", path);
1892-
goto out;
1893-
}
1907+
while ((ent = readdir(dir)) != NULL) {
1908+
if (strspn(ent->d_name, "0123456789abcdef") != hexsz ||
1909+
ent->d_name[hexsz] != '\0')
1910+
continue;
1911+
count++;
1912+
}
18941913

1895-
while ((ent = readdir(dir)) != NULL) {
1896-
if (strspn(ent->d_name, "0123456789abcdef") != hexsz ||
1897-
ent->d_name[hexsz] != '\0')
1898-
continue;
1899-
count++;
1914+
*out = count * 256;
1915+
ret = 0;
1916+
} else {
1917+
*out = 0;
1918+
ret = odb_source_loose_for_each_object(source, NULL, count_loose_object,
1919+
out, 0);
19001920
}
19011921

1902-
*out = count * 256;
1903-
ret = 0;
1904-
19051922
out:
19061923
if (dir)
19071924
closedir(dir);

object-file.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,9 @@ int odb_source_loose_for_each_object(struct odb_source *source,
149149
*
150150
* Returns 0 on success, a negative error code otherwise.
151151
*/
152-
int odb_source_loose_approximate_object_count(struct odb_source *source,
153-
unsigned long *out);
152+
int odb_source_loose_count_objects(struct odb_source *source,
153+
enum odb_count_objects_flags flags,
154+
unsigned long *out);
154155

155156
/**
156157
* format_object_header() is a thin wrapper around s xsnprintf() that

odb.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,15 @@ int odb_for_each_object(struct object_database *odb,
500500
void *cb_data,
501501
unsigned flags);
502502

503+
enum odb_count_objects_flags {
504+
/*
505+
* Instead of providing an accurate count, allow the number of objects
506+
* to be approximated. Details of how this approximation works are
507+
* subject to the specific source's implementation.
508+
*/
509+
ODB_COUNT_OBJECTS_APPROXIMATE = (1 << 0),
510+
};
511+
503512
enum {
504513
/*
505514
* By default, `odb_write_object()` does not actually write anything

0 commit comments

Comments
 (0)