]> git.ipfire.org Git - thirdparty/git.git/commitdiff
object-file: move loose object cache into loose source
authorPatrick Steinhardt <ps@pks.im>
Mon, 3 Nov 2025 07:42:01 +0000 (08:42 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 3 Nov 2025 20:18:46 +0000 (12:18 -0800)
Our loose objects use a cache that (optionally) stores all objects for
each of the opened sharding directories. This cache is located in the
`struct odb_source`, but now that we have `struct odb_source_loose` it
makes sense to move it into the latter structure so that all state that
relates to loose objects is entirely self-contained.

Do so. While at it, rename corresponding functions to have a prefix that
relates to `struct odb_source_loose`.

Note that despite this prefix, the functions still accept a `struct
odb_source` as input. This is done intentionally: once we introduce
pluggable object databases, we will continue to accept this struct but
then do a cast inside these functions to `struct odb_source_loose`. This
design is similar to how we do it for our ref backends.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
loose.c
object-file.c
object-file.h
object-name.c
odb.c
odb.h

diff --git a/loose.c b/loose.c
index e8ea6e7e24ba31218579c92fb506b012f2b72f12..8cc7573ff2b2d9206daaf10f542ec566be412b91 100644 (file)
--- a/loose.c
+++ b/loose.c
@@ -1,6 +1,7 @@
 #include "git-compat-util.h"
 #include "hash.h"
 #include "path.h"
+#include "object-file.h"
 #include "odb.h"
 #include "hex.h"
 #include "repository.h"
@@ -54,7 +55,7 @@ static int insert_loose_map(struct odb_source *source,
        inserted |= insert_oid_pair(map->to_compat, oid, compat_oid);
        inserted |= insert_oid_pair(map->to_storage, compat_oid, oid);
        if (inserted)
-               oidtree_insert(source->loose_objects_cache, compat_oid);
+               oidtree_insert(source->loose->cache, compat_oid);
 
        return inserted;
 }
@@ -66,9 +67,9 @@ static int load_one_loose_object_map(struct repository *repo, struct odb_source
 
        if (!source->loose_map)
                loose_object_map_init(&source->loose_map);
-       if (!source->loose_objects_cache) {
-               ALLOC_ARRAY(source->loose_objects_cache, 1);
-               oidtree_init(source->loose_objects_cache);
+       if (!source->loose->cache) {
+               ALLOC_ARRAY(source->loose->cache, 1);
+               oidtree_init(source->loose->cache);
        }
 
        insert_loose_map(source, repo->hash_algo->empty_tree, repo->compat_hash_algo->empty_tree);
index cd6aa561fa7db28144dfc9f8c49c2e5ca6e3191b..fef00d6d3d082aa5bd80c67c46024b93652dd6fe 100644 (file)
@@ -223,7 +223,7 @@ static int quick_has_loose(struct repository *r,
 
        odb_prepare_alternates(r->objects);
        for (source = r->objects->sources; source; source = source->next) {
-               if (oidtree_contains(odb_loose_cache(source, oid), oid))
+               if (oidtree_contains(odb_source_loose_cache(source, oid), oid))
                        return 1;
        }
        return 0;
@@ -1802,44 +1802,44 @@ static int append_loose_object(const struct object_id *oid,
        return 0;
 }
 
-struct oidtree *odb_loose_cache(struct odb_source *source,
-                               const struct object_id *oid)
+struct oidtree *odb_source_loose_cache(struct odb_source *source,
+                                      const struct object_id *oid)
 {
        int subdir_nr = oid->hash[0];
        struct strbuf buf = STRBUF_INIT;
-       size_t word_bits = bitsizeof(source->loose_objects_subdir_seen[0]);
+       size_t word_bits = bitsizeof(source->loose->subdir_seen[0]);
        size_t word_index = subdir_nr / word_bits;
        size_t mask = (size_t)1u << (subdir_nr % word_bits);
        uint32_t *bitmap;
 
        if (subdir_nr < 0 ||
-           (size_t) subdir_nr >= bitsizeof(source->loose_objects_subdir_seen))
+           (size_t) subdir_nr >= bitsizeof(source->loose->subdir_seen))
                BUG("subdir_nr out of range");
 
-       bitmap = &source->loose_objects_subdir_seen[word_index];
+       bitmap = &source->loose->subdir_seen[word_index];
        if (*bitmap & mask)
-               return source->loose_objects_cache;
-       if (!source->loose_objects_cache) {
-               ALLOC_ARRAY(source->loose_objects_cache, 1);
-               oidtree_init(source->loose_objects_cache);
+               return source->loose->cache;
+       if (!source->loose->cache) {
+               ALLOC_ARRAY(source->loose->cache, 1);
+               oidtree_init(source->loose->cache);
        }
        strbuf_addstr(&buf, source->path);
        for_each_file_in_obj_subdir(subdir_nr, &buf,
                                    source->odb->repo->hash_algo,
                                    append_loose_object,
                                    NULL, NULL,
-                                   source->loose_objects_cache);
+                                   source->loose->cache);
        *bitmap |= mask;
        strbuf_release(&buf);
-       return source->loose_objects_cache;
+       return source->loose->cache;
 }
 
 void odb_clear_loose_cache(struct odb_source *source)
 {
-       oidtree_clear(source->loose_objects_cache);
-       FREE_AND_NULL(source->loose_objects_cache);
-       memset(&source->loose_objects_subdir_seen, 0,
-              sizeof(source->loose_objects_subdir_seen));
+       oidtree_clear(source->loose->cache);
+       FREE_AND_NULL(source->loose->cache);
+       memset(&source->loose->subdir_seen, 0,
+              sizeof(source->loose->subdir_seen));
 }
 
 static int check_stream_oid(git_zstream *stream,
@@ -2006,5 +2006,8 @@ struct odb_source_loose *odb_source_loose_new(struct odb_source *source)
 
 void odb_source_loose_free(struct odb_source_loose *loose)
 {
+       if (!loose)
+               return;
+       odb_clear_loose_cache(loose->source);
        free(loose);
 }
index 695a7e8e7c4b0b3efc7c54dd46ccc7a0ab4d2a9a..90da69cf5f7d59aaf9bd9c6c45e48179b2652cfd 100644 (file)
@@ -20,6 +20,18 @@ struct odb_source;
 
 struct odb_source_loose {
        struct odb_source *source;
+
+       /*
+        * Used to store the results of readdir(3) calls when we are OK
+        * sacrificing accuracy due to races for speed. That includes
+        * object existence with OBJECT_INFO_QUICK, as well as
+        * our search for unique abbreviated hashes. Don't use it for tasks
+        * requiring greater accuracy!
+        *
+        * Be sure to call odb_load_loose_cache() before using.
+        */
+       uint32_t subdir_seen[8]; /* 256 bits */
+       struct oidtree *cache;
 };
 
 struct odb_source_loose *odb_source_loose_new(struct odb_source *source);
@@ -29,8 +41,8 @@ void odb_source_loose_free(struct odb_source_loose *loose);
  * Populate and return the loose object cache array corresponding to the
  * given object ID.
  */
-struct oidtree *odb_loose_cache(struct odb_source *source,
-                               const struct object_id *oid);
+struct oidtree *odb_source_loose_cache(struct odb_source *source,
+                                      const struct object_id *oid);
 
 /* Empty the loose object cache for the specified object directory. */
 void odb_clear_loose_cache(struct odb_source *source);
index 766c757042a38950f7b498dc7fa92b72befea264..8ce0ef7c23a6bd78c5770bef51d31bba88a11323 100644 (file)
@@ -116,7 +116,7 @@ static void find_short_object_filename(struct disambiguate_state *ds)
        struct odb_source *source;
 
        for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next)
-               oidtree_each(odb_loose_cache(source, &ds->bin_pfx),
+               oidtree_each(odb_source_loose_cache(source, &ds->bin_pfx),
                                &ds->bin_pfx, ds->len, match_prefix, ds);
 }
 
diff --git a/odb.c b/odb.c
index 2d06ab0bb85c27d824ab7229cb22b00e6cf8fb71..87d84688c638cce55c92e401dd324c5e3136fb1a 100644 (file)
--- a/odb.c
+++ b/odb.c
@@ -370,7 +370,6 @@ static void odb_source_free(struct odb_source *source)
 {
        free(source->path);
        odb_source_loose_free(source->loose);
-       odb_clear_loose_cache(source);
        loose_object_map_clear(&source->loose_map);
        free(source);
 }
diff --git a/odb.h b/odb.h
index 49b398bedae64067251a15b3e7f5087576de6c89..77104396afe4aa4db606b046f75455f683af900a 100644 (file)
--- a/odb.h
+++ b/odb.h
@@ -51,18 +51,6 @@ struct odb_source {
        /* Private state for loose objects. */
        struct odb_source_loose *loose;
 
-       /*
-        * Used to store the results of readdir(3) calls when we are OK
-        * sacrificing accuracy due to races for speed. That includes
-        * object existence with OBJECT_INFO_QUICK, as well as
-        * our search for unique abbreviated hashes. Don't use it for tasks
-        * requiring greater accuracy!
-        *
-        * Be sure to call odb_load_loose_cache() before using.
-        */
-       uint32_t loose_objects_subdir_seen[8]; /* 256 bits */
-       struct oidtree *loose_objects_cache;
-
        /* Map between object IDs for loose objects. */
        struct loose_object_map *loose_map;