]> git.ipfire.org Git - thirdparty/git.git/commitdiff
odb/source-loose: wire up `count_objects()` callback
authorPatrick Steinhardt <ps@pks.im>
Thu, 21 May 2026 08:22:30 +0000 (10:22 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 21 May 2026 13:35:19 +0000 (22:35 +0900)
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>
builtin/gc.c
object-file.c
object-file.h
odb/source-files.c
odb/source-loose.c

index 84a66d32404e4dbdba5e554d63a8cae55cce5f97..c26c93ee0fe4a3cbdb7b9241c1296e3b1b4aed7f 100644 (file)
@@ -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;
index 11957aa44f44fdc631e9c469e99c1d4870e2ac29..9b2044de3784e61c15a663f5934c7f3550073f55 100644 (file)
@@ -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,
index 96760db0e1cb2bfca7938a1d1c80595af46c7021..bc72d89f54891553ac618b2b8fb34868028ff7db 100644 (file)
@@ -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
index 4a54b10e4af11df6e998d7b45bd647a06b434718..d5454e170dee664830786bb33da56da56a562352 100644 (file)
@@ -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;
 
index 4b8d10bc870374fa8174ed419eaf43611f299e30..27be066327a3138d8619b6ad1168dc1cfb655b67 100644 (file)
@@ -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);