handle alternates paths the same as the main object dir

When we generate loose file paths for the main object directory, the caller provides a buffer to loose_object_path (formerly sha1_file_name). The callers generally keep their own static buffer to avoid excessive reallocations. But for alternate directories, each struct carries its own scratch buffer. This is needlessly different; let's unify them. We could go either direction here, but this patch moves the alternates struct over to the main directory style (rather than vice-versa). Technically the alternates style is more efficient, as it avoids rewriting the object directory name on each call. But this is unlikely to matter in practice, as we avoid reallocations either way (and nobody has ever noticed or complained that the main object directory is copying a few extra bytes before making a much more expensive system call). And this has the advantage that the reusable buffers are tied to particular calls, which makes the invalidation rules simpler (for example, the return value from stat_sha1_file() used to be invalidated by basically any other object call, but now it is affected only by other calls to stat_sha1_file()). We do steal the trick from alt_sha1_path() of returning a pointer to the filled buffer, which makes a few conversions more convenient. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Nov 12, 2018 at 09:49 UTC f3f043a103b7a7da57272ecf3252bda6089e41ae
4 files changed +23 -44
object-store.h
+1 -13
@@ -10,10 +10,6 @@
10 struct object_directory {
11 struct object_directory *next;
12
13 - /* see alt_scratch_buf() */
14 - struct strbuf scratch;
15 - size_t base_len;
16 -
13 /*
14 * Used to store the results of readdir(3) calls when searching
15 * for unique abbreviated hashes. This cache is never
@@ -54,14 +50,6 @@ void add_to_alternates_file(const char *dir);
50 */
51 void add_to_alternates_memory(const char *dir);
52
57 -/*
58 - * Returns a scratch strbuf pre-filled with the alternate object directory,
59 - * including a trailing slash, which can be used to access paths in the
60 - * alternate. Always use this over direct access to alt->scratch, as it
61 - * cleans up any previous use of the scratch buffer.
62 - */
63 -struct strbuf *alt_scratch_buf(struct object_directory *odb);
64 -
53 struct packed_git {
54 struct packed_git *next;
55 struct list_head mru;
@@ -157,7 +145,7 @@ void raw_object_store_clear(struct raw_object_store *o);
145 * Put in `buf` the name of the file in the local object database that
146 * would be used to store a loose object with the specified sha1.
147 */
160 -void loose_object_path(struct repository *r, struct strbuf *buf, const unsigned char *sha1);
148 +const char *loose_object_path(struct repository *r, struct strbuf *buf, const unsigned char *sha1);
149
150 void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size);
151
object.c
-1
@@ -484,7 +484,6 @@ struct raw_object_store *raw_object_store_new(void)
484
485 static void free_alt_odb(struct object_directory *odb)
486 {
487 - strbuf_release(&odb->scratch);
487 oid_array_clear(&odb->loose_objects_cache);
488 free(odb);
489 }
sha1-file.c
+16 -28
@@ -346,27 +346,20 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)
346 }
347 }
348
349 -void loose_object_path(struct repository *r, struct strbuf *buf,
350 - const unsigned char *sha1)
349 +static const char *odb_loose_path(const char *path, struct strbuf *buf,
350 + const unsigned char *sha1)
351 {
352 strbuf_reset(buf);
353 - strbuf_addstr(buf, r->objects->objectdir);
353 + strbuf_addstr(buf, path);
354 strbuf_addch(buf, '/');
355 fill_sha1_path(buf, sha1);
356 + return buf->buf;
357 }
358
358 -struct strbuf *alt_scratch_buf(struct object_directory *odb)
359 +const char *loose_object_path(struct repository *r, struct strbuf *buf,
360 + const unsigned char *sha1)
361 {
360 - strbuf_setlen(&odb->scratch, odb->base_len);
361 - return &odb->scratch;
362 -}
363 -
364 -static const char *alt_sha1_path(struct object_directory *odb,
365 - const unsigned char *sha1)
366 -{
367 - struct strbuf *buf = alt_scratch_buf(odb);
368 - fill_sha1_path(buf, sha1);
369 - return buf->buf;
362 + return odb_loose_path(r->objects->objectdir, buf, sha1);
363 }
364
365 /*
@@ -547,9 +540,6 @@ struct object_directory *alloc_alt_odb(const char *dir)
540 struct object_directory *ent;
541
542 FLEX_ALLOC_STR(ent, path, dir);
550 - strbuf_init(&ent->scratch, 0);
551 - strbuf_addf(&ent->scratch, "%s/", dir);
552 - ent->base_len = ent->scratch.len;
543
544 return ent;
545 }
@@ -745,10 +735,12 @@ static int check_and_freshen_local(const struct object_id *oid, int freshen)
735 static int check_and_freshen_nonlocal(const struct object_id *oid, int freshen)
736 {
737 struct object_directory *odb;
738 + static struct strbuf path = STRBUF_INIT;
739 +
740 prepare_alt_odb(the_repository);
741 for (odb = the_repository->objects->alt_odb_list; odb; odb = odb->next) {
750 - const char *path = alt_sha1_path(odb, oid->hash);
751 - if (check_and_freshen_file(path, freshen))
742 + odb_loose_path(odb->path, &path, oid->hash);
743 + if (check_and_freshen_file(path.buf, freshen))
744 return 1;
745 }
746 return 0;
@@ -889,7 +881,7 @@ int git_open_cloexec(const char *name, int flags)
881 *
882 * The "path" out-parameter will give the path of the object we found (if any).
883 * Note that it may point to static storage and is only valid until another
892 - * call to loose_object_path(), etc.
884 + * call to stat_sha1_file().
885 */
886 static int stat_sha1_file(struct repository *r, const unsigned char *sha1,
887 struct stat *st, const char **path)
@@ -897,16 +889,14 @@ static int stat_sha1_file(struct repository *r, const unsigned char *sha1,
889 struct object_directory *odb;
890 static struct strbuf buf = STRBUF_INIT;
891
900 - loose_object_path(r, &buf, sha1);
901 - *path = buf.buf;
902 -
892 + *path = loose_object_path(r, &buf, sha1);
893 if (!lstat(*path, st))
894 return 0;
895
896 prepare_alt_odb(r);
897 errno = ENOENT;
898 for (odb = r->objects->alt_odb_list; odb; odb = odb->next) {
909 - *path = alt_sha1_path(odb, sha1);
899 + *path = odb_loose_path(odb->path, &buf, sha1);
900 if (!lstat(*path, st))
901 return 0;
902 }
@@ -926,9 +916,7 @@ static int open_sha1_file(struct repository *r,
916 int most_interesting_errno;
917 static struct strbuf buf = STRBUF_INIT;
918
929 - loose_object_path(r, &buf, sha1);
930 - *path = buf.buf;
931 -
919 + *path = loose_object_path(r, &buf, sha1);
920 fd = git_open(*path);
921 if (fd >= 0)
922 return fd;
@@ -936,7 +924,7 @@ static int open_sha1_file(struct repository *r,
924
925 prepare_alt_odb(r);
926 for (odb = r->objects->alt_odb_list; odb; odb = odb->next) {
939 - *path = alt_sha1_path(odb, sha1);
927 + *path = odb_loose_path(odb->path, &buf, sha1);
928 fd = git_open(*path);
929 if (fd >= 0)
930 return fd;
sha1-name.c
+6 -2
@@ -97,6 +97,7 @@ static void find_short_object_filename(struct disambiguate_state *ds)
97 int subdir_nr = ds->bin_pfx.hash[0];
98 struct object_directory *odb;
99 static struct object_directory *fakeent;
100 + struct strbuf buf = STRBUF_INIT;
101
102 if (!fakeent) {
103 /*
@@ -114,8 +115,9 @@ static void find_short_object_filename(struct disambiguate_state *ds)
115 int pos;
116
117 if (!odb->loose_objects_subdir_seen[subdir_nr]) {
117 - struct strbuf *buf = alt_scratch_buf(odb);
118 - for_each_file_in_obj_subdir(subdir_nr, buf,
118 + strbuf_reset(&buf);
119 + strbuf_addstr(&buf, odb->path);
120 + for_each_file_in_obj_subdir(subdir_nr, &buf,
121 append_loose_object,
122 NULL, NULL,
123 &odb->loose_objects_cache);
@@ -134,6 +136,8 @@ static void find_short_object_filename(struct disambiguate_state *ds)
136 pos++;
137 }
138 }
139 +
140 + strbuf_release(&buf);
141 }
142
143 static int match_sha(unsigned len, const unsigned char *a, const unsigned char *b)