aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2025-11-03 08:42:01 +0100
committerJunio C Hamano <gitster@pobox.com>2025-11-03 12:18:46 -0800
commit90a93f9dea88532623ef7422dbc21d8dc70a58dd (patch)
tree5874725a677983485dfc406ab5dbfd0282e08bbb
parentece43d9dc70b1717484ee78b66aef4f9390c2b2b (diff)
downloadgit-90a93f9dea88532623ef7422dbc21d8dc70a58dd.tar.gz
object-file: move loose object cache into loose source
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>
-rw-r--r--loose.c9
-rw-r--r--object-file.c35
-rw-r--r--object-file.h16
-rw-r--r--object-name.c2
-rw-r--r--odb.c1
-rw-r--r--odb.h12
6 files changed, 39 insertions, 36 deletions
diff --git a/loose.c b/loose.c
index e8ea6e7e24..8cc7573ff2 100644
--- 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);
diff --git a/object-file.c b/object-file.c
index cd6aa561fa..fef00d6d3d 100644
--- a/object-file.c
+++ b/object-file.c
@@ -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);
}
diff --git a/object-file.h b/object-file.h
index 695a7e8e7c..90da69cf5f 100644
--- a/object-file.h
+++ b/object-file.h
@@ -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);
diff --git a/object-name.c b/object-name.c
index 766c757042..8ce0ef7c23 100644
--- a/object-name.c
+++ b/object-name.c
@@ -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 2d06ab0bb8..87d84688c6 100644
--- 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 49b398beda..77104396af 100644
--- 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;