Skip to content

Commit 3a2e082

Browse files
peffgitster
authored andcommitted
object-store: provide helpers for loose_objects_cache
Our object_directory struct has a loose objects cache that all users of the struct can see. But the only one that knows how to load the cache is find_short_object_filename(). Let's extract that logic in to a reusable function. While we're at it, let's also reset the cache when we re-read the object directories. This shouldn't have an impact on performance, as re-reads are meant to be rare (and are already expensive, so we avoid them with things like OBJECT_INFO_QUICK). Since the cache is already meant to be an approximation, it's tempting to skip even this bit of safety. But it's necessary to allow more code to use it. For instance, fetch-pack explicitly re-reads the object directory after performing its fetch, and would be confused if we didn't clear the cache. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f0eaf63 commit 3a2e082

File tree

4 files changed

+48
-25
lines changed

4 files changed

+48
-25
lines changed

object-store.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ struct object_directory {
1111
struct object_directory *next;
1212

1313
/*
14-
* Used to store the results of readdir(3) calls when searching
15-
* for unique abbreviated hashes. This cache is never
16-
* invalidated, thus it's racy and not necessarily accurate.
17-
* That's fine for its purpose; don't use it for tasks requiring
18-
* greater accuracy!
14+
* Used to store the results of readdir(3) calls when we are OK
15+
* sacrificing accuracy due to races for speed. That includes
16+
* our search for unique abbreviated hashes. Don't use it for tasks
17+
* requiring greater accuracy!
18+
*
19+
* Be sure to call odb_load_loose_cache() before using.
1920
*/
2021
char loose_objects_subdir_seen[256];
2122
struct oid_array loose_objects_cache;
@@ -45,6 +46,13 @@ void add_to_alternates_file(const char *dir);
4546
*/
4647
void add_to_alternates_memory(const char *dir);
4748

49+
/*
50+
* Populate an odb's loose object cache for one particular subdirectory (i.e.,
51+
* the one that corresponds to the first byte of objects you're interested in,
52+
* from 0 to 255 inclusive).
53+
*/
54+
void odb_load_loose_cache(struct object_directory *odb, int subdir_nr);
55+
4856
struct packed_git {
4957
struct packed_git *next;
5058
struct list_head mru;

packfile.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,14 @@ static void prepare_packed_git(struct repository *r)
987987

988988
void reprepare_packed_git(struct repository *r)
989989
{
990+
struct object_directory *odb;
991+
992+
for (odb = r->objects->odb; odb; odb = odb->next) {
993+
oid_array_clear(&odb->loose_objects_cache);
994+
memset(&odb->loose_objects_subdir_seen, 0,
995+
sizeof(odb->loose_objects_subdir_seen));
996+
}
997+
990998
r->objects->approximate_object_count_valid = 0;
991999
r->objects->packed_git_initialized = 0;
9921000
prepare_packed_git(r);

sha1-file.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2125,6 +2125,32 @@ int for_each_loose_object(each_loose_object_fn cb, void *data,
21252125
return 0;
21262126
}
21272127

2128+
static int append_loose_object(const struct object_id *oid, const char *path,
2129+
void *data)
2130+
{
2131+
oid_array_append(data, oid);
2132+
return 0;
2133+
}
2134+
2135+
void odb_load_loose_cache(struct object_directory *odb, int subdir_nr)
2136+
{
2137+
struct strbuf buf = STRBUF_INIT;
2138+
2139+
if (subdir_nr < 0 ||
2140+
subdir_nr >= ARRAY_SIZE(odb->loose_objects_subdir_seen))
2141+
BUG("subdir_nr out of range");
2142+
2143+
if (odb->loose_objects_subdir_seen[subdir_nr])
2144+
return;
2145+
2146+
strbuf_addstr(&buf, odb->path);
2147+
for_each_file_in_obj_subdir(subdir_nr, &buf,
2148+
append_loose_object,
2149+
NULL, NULL,
2150+
&odb->loose_objects_cache);
2151+
odb->loose_objects_subdir_seen[subdir_nr] = 1;
2152+
}
2153+
21282154
static int check_stream_sha1(git_zstream *stream,
21292155
const char *hdr,
21302156
unsigned long size,

sha1-name.c

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -83,36 +83,19 @@ static void update_candidates(struct disambiguate_state *ds, const struct object
8383
/* otherwise, current can be discarded and candidate is still good */
8484
}
8585

86-
static int append_loose_object(const struct object_id *oid, const char *path,
87-
void *data)
88-
{
89-
oid_array_append(data, oid);
90-
return 0;
91-
}
92-
9386
static int match_sha(unsigned, const unsigned char *, const unsigned char *);
9487

9588
static void find_short_object_filename(struct disambiguate_state *ds)
9689
{
9790
int subdir_nr = ds->bin_pfx.hash[0];
9891
struct object_directory *odb;
99-
struct strbuf buf = STRBUF_INIT;
10092

10193
for (odb = the_repository->objects->odb;
10294
odb && !ds->ambiguous;
10395
odb = odb->next) {
10496
int pos;
10597

106-
if (!odb->loose_objects_subdir_seen[subdir_nr]) {
107-
strbuf_reset(&buf);
108-
strbuf_addstr(&buf, odb->path);
109-
for_each_file_in_obj_subdir(subdir_nr, &buf,
110-
append_loose_object,
111-
NULL, NULL,
112-
&odb->loose_objects_cache);
113-
odb->loose_objects_subdir_seen[subdir_nr] = 1;
114-
}
115-
98+
odb_load_loose_cache(odb, subdir_nr);
11699
pos = oid_array_lookup(&odb->loose_objects_cache, &ds->bin_pfx);
117100
if (pos < 0)
118101
pos = -1 - pos;
@@ -125,8 +108,6 @@ static void find_short_object_filename(struct disambiguate_state *ds)
125108
pos++;
126109
}
127110
}
128-
129-
strbuf_release(&buf);
130111
}
131112

132113
static int match_sha(unsigned len, const unsigned char *a, const unsigned char *b)

0 commit comments

Comments
 (0)