ref-cache: use a callback function to fill the cache

It is a leveling violation for `ref_cache` to know about `files_ref_store` or that it should call `read_loose_refs()` to lazily fill cache directories. So instead, have its constructor take as an argument a callback function that it should use for lazy-filling, and change `files_ref_store` to supply a pointer to function `read_loose_refs` (renamed to `loose_fill_ref_dir`) when creating the ref cache for its loose refs. This means that we can generify the type of the back-pointer in `struct ref_cache` from `files_ref_store` to `ref_store`. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael Haggerty committed Apr 16, 2017 at 08:41 UTC df30875987329bb46e54ec7be0eb29c33702de3a
3 files changed +38 -13
refs/files-backend.c
+6 -4
@@ -386,7 +386,7 @@ static struct packed_ref_cache *get_packed_ref_cache(struct files_ref_store *ref
386
387 refs->packed = xcalloc(1, sizeof(*refs->packed));
388 acquire_packed_ref_cache(refs->packed);
389 - refs->packed->cache = create_ref_cache(refs);
389 + refs->packed->cache = create_ref_cache(&refs->base, NULL);
390 refs->packed->cache->root->flag &= ~REF_INCOMPLETE;
391 f = fopen(packed_refs_file, "r");
392 if (f) {
@@ -430,9 +430,11 @@ static void add_packed_ref(struct files_ref_store *refs,
430 * (without recursing). dirname must end with '/'. dir must be the
431 * directory entry corresponding to dirname.
432 */
433 -void read_loose_refs(const char *dirname, struct ref_dir *dir)
433 +static void loose_fill_ref_dir(struct ref_store *ref_store,
434 + struct ref_dir *dir, const char *dirname)
435 {
435 - struct files_ref_store *refs = dir->cache->ref_store;
436 + struct files_ref_store *refs =
437 + files_downcast(ref_store, REF_STORE_READ, "fill_ref_dir");
438 DIR *d;
439 struct dirent *de;
440 int dirnamelen = strlen(dirname);
@@ -515,7 +517,7 @@ static struct ref_dir *get_loose_refs(struct files_ref_store *refs)
517 * are about to read the only subdirectory that can
518 * hold references:
519 */
518 - refs->loose = create_ref_cache(refs);
520 + refs->loose = create_ref_cache(&refs->base, loose_fill_ref_dir);
521
522 /* We're going to fill the top level ourselves: */
523 refs->loose->root->flag &= ~REF_INCOMPLETE;
refs/ref-cache.c
+7 -5
@@ -4,9 +4,6 @@
4 #include "ref-cache.h"
5 #include "../iterator.h"
6
7 -/* FIXME: This declaration shouldn't be here */
8 -void read_loose_refs(const char *dirname, struct ref_dir *dir);
9 -
7 void add_entry_to_dir(struct ref_dir *dir, struct ref_entry *entry)
8 {
9 ALLOC_GROW(dir->entries, dir->nr + 1, dir->alloc);
@@ -25,7 +22,10 @@ struct ref_dir *get_ref_dir(struct ref_entry *entry)
22 assert(entry->flag & REF_DIR);
23 dir = &entry->u.subdir;
24 if (entry->flag & REF_INCOMPLETE) {
28 - read_loose_refs(entry->name, dir);
25 + if (!dir->cache->fill_ref_dir)
26 + die("BUG: incomplete ref_store without fill_ref_dir function");
27 +
28 + dir->cache->fill_ref_dir(dir->cache->ref_store, dir, entry->name);
29
30 /*
31 * Manually add refs/bisect, which, being
@@ -63,11 +63,13 @@ struct ref_entry *create_ref_entry(const char *refname,
63 return ref;
64 }
65
66 -struct ref_cache *create_ref_cache(struct files_ref_store *refs)
66 +struct ref_cache *create_ref_cache(struct ref_store *refs,
67 + fill_ref_dir_fn *fill_ref_dir)
68 {
69 struct ref_cache *ret = xcalloc(1, sizeof(*ret));
70
71 ret->ref_store = refs;
72 + ret->fill_ref_dir = fill_ref_dir;
73 ret->root = create_dir_entry(ret, "", 0, 1);
74 return ret;
75 }
refs/ref-cache.h
+25 -4
@@ -1,11 +1,27 @@
1 #ifndef REFS_REF_CACHE_H
2 #define REFS_REF_CACHE_H
3
4 +struct ref_dir;
5 +
6 +/*
7 + * If this ref_cache is filled lazily, this function is used to load
8 + * information into the specified ref_dir (shallow or deep, at the
9 + * option of the ref_store). dirname includes a trailing slash.
10 + */
11 +typedef void fill_ref_dir_fn(struct ref_store *ref_store,
12 + struct ref_dir *dir, const char *dirname);
13 +
14 struct ref_cache {
15 struct ref_entry *root;
16
7 - /* A pointer to the files_ref_store whose cache this is: */
8 - struct files_ref_store *ref_store;
17 + /* A pointer to the ref_store whose cache this is: */
18 + struct ref_store *ref_store;
19 +
20 + /*
21 + * Function used (if necessary) to lazily-fill cache. May be
22 + * NULL.
23 + */
24 + fill_ref_dir_fn *fill_ref_dir;
25 };
26
27 /*
@@ -174,9 +190,14 @@ struct ref_entry *create_ref_entry(const char *refname,
190
191 /*
192 * Return a pointer to a new `ref_cache`. Its top-level starts out
177 - * marked incomplete.
193 + * marked incomplete. If `fill_ref_dir` is non-NULL, it is the
194 + * function called to fill in incomplete directories in the
195 + * `ref_cache` when they are accessed. If it is NULL, then the whole
196 + * `ref_cache` must be filled (including clearing its directories'
197 + * `REF_INCOMPLETE` bits) before it is used.
198 */
179 -struct ref_cache *create_ref_cache(struct files_ref_store *refs);
199 +struct ref_cache *create_ref_cache(struct ref_store *refs,
200 + fill_ref_dir_fn *fill_ref_dir);
201
202 /*
203 * Free the `ref_cache` and all of its associated data.