From a5b34d21521c015cd41ced4a3fdde57d79891eb3 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 3 Oct 2016 16:35:03 -0400 Subject: alternates: provide helper for adding to alternates list The submodule code wants to temporarily add an alternate object store to our in-memory alt_odb list, but does it manually. Let's provide a helper so it can reuse the code in link_alt_odb_entry(). While we're adding our new add_to_alternates_memory(), let's document add_to_alternates_file(), as the two are related. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 6fc0e5ae68..258ce6b0f0 100644 --- a/cache.h +++ b/cache.h @@ -1389,10 +1389,22 @@ extern struct alternate_object_database { extern void prepare_alt_odb(void); extern void read_info_alternates(const char * relative_base, int depth); extern char *compute_alternate_path(const char *path, struct strbuf *err); -extern void add_to_alternates_file(const char *reference); typedef int alt_odb_fn(struct alternate_object_database *, void *); extern int foreach_alt_odb(alt_odb_fn, void*); +/* + * Add the directory to the on-disk alternates file; the new entry will also + * take effect in the current process. + */ +extern void add_to_alternates_file(const char *dir); + +/* + * Add the directory to the in-memory list of alternates (along with any + * recursive alternates it points to), but do not modify the on-disk alternates + * file. + */ +extern void add_to_alternates_memory(const char *dir); + struct pack_window { struct pack_window *next; unsigned char *base; -- cgit v1.2.1 From 7f0fa2c02a6543bdadae3c4a492daae7dbc8c042 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 3 Oct 2016 16:35:31 -0400 Subject: alternates: provide helper for allocating alternate Allocating a struct alternate_object_database is tricky, as we must over-allocate the buffer to provide scratch space, and then put in particular '/' and NUL markers. Let's encapsulate this in a function so that the complexity doesn't leak into callers (and so that we can modify it later). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 258ce6b0f0..ece2c7c9b8 100644 --- a/cache.h +++ b/cache.h @@ -1392,6 +1392,12 @@ extern char *compute_alternate_path(const char *path, struct strbuf *err); typedef int alt_odb_fn(struct alternate_object_database *, void *); extern int foreach_alt_odb(alt_odb_fn, void*); +/* + * Allocate a "struct alternate_object_database" but do _not_ actually + * add it to the list of alternates. + */ +struct alternate_object_database *alloc_alt_odb(const char *dir); + /* * Add the directory to the on-disk alternates file; the new entry will also * take effect in the current process. -- cgit v1.2.1 From 597f9134ded20f882e2bf6bca8b0e1f03981b98d Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 3 Oct 2016 16:35:51 -0400 Subject: alternates: use a separate scratch space The alternate_object_database struct uses a single buffer both for storing the path to the alternate, and as a scratch buffer for forming object names. This is efficient (since otherwise we'd end up storing the path twice), but it makes life hard for callers who just want to know the path to the alternate. They have to remember to stop reading after "alt->name - alt->base" bytes, and to subtract one for the trailing '/'. It would be much simpler if they could simply access a NUL-terminated path string. We could encapsulate this in a function which puts a NUL in the scratch buffer and returns the string, but that opens up questions about the lifetime of the result. The first time another caller uses the alternate, the scratch buffer may get other data tacked onto it. Let's instead just store the root path separately from the scratch buffer. There aren't enough alternates being stored for the duplicated data to matter for performance, and this keeps things simple and safe for the callers. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'cache.h') diff --git a/cache.h b/cache.h index ece2c7c9b8..555ba713de 100644 --- a/cache.h +++ b/cache.h @@ -1383,8 +1383,11 @@ extern void remove_scheduled_dirs(void); extern struct alternate_object_database { struct alternate_object_database *next; + char *name; - char base[FLEX_ARRAY]; /* more */ + char *scratch; + + char path[FLEX_ARRAY]; } *alt_odb_list; extern void prepare_alt_odb(void); extern void read_info_alternates(const char * relative_base, int depth); -- cgit v1.2.1 From 38dbe5f07837afceaec95fae5981d36eeb4917bd Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 3 Oct 2016 16:36:04 -0400 Subject: alternates: store scratch buffer as strbuf We pre-size the scratch buffer to hold a loose object filename of the form "xx/yyyy...", which leads to allocation code that is hard to verify. We have to use some magic numbers during the initial allocation, and then writers must blindly assume that the buffer is big enough. Using a strbuf makes it more clear that we cannot overflow. Unfortunately, we do still need some magic numbers to grow our strbuf before calling fill_sha1_path(), but the strbuf growth is much closer to the point of use. This makes it easier to see that it's correct, and opens the possibility of pushing it even further down if fill_sha1_path() learns to work on strbufs. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 555ba713de..5d36ffa1f2 100644 --- a/cache.h +++ b/cache.h @@ -1384,8 +1384,9 @@ extern void remove_scheduled_dirs(void); extern struct alternate_object_database { struct alternate_object_database *next; - char *name; - char *scratch; + /* see alt_scratch_buf() */ + struct strbuf scratch; + size_t base_len; char path[FLEX_ARRAY]; } *alt_odb_list; @@ -1414,6 +1415,14 @@ extern void add_to_alternates_file(const char *dir); */ extern void add_to_alternates_memory(const char *dir); +/* + * Returns a scratch strbuf pre-filled with the alternate object directory, + * including a trailing slash, which can be used to access paths in the + * alternate. Always use this over direct access to alt->scratch, as it + * cleans up any previous use of the scratch buffer. + */ +extern struct strbuf *alt_scratch_buf(struct alternate_object_database *alt); + struct pack_window { struct pack_window *next; unsigned char *base; -- cgit v1.2.1