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.