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>
This commit is contained in:
		
				
					committed by
					
						
						Junio C Hamano
					
				
			
			
				
	
			
			
			
						parent
						
							e00d1a4ff7
						
					
				
				
					commit
					df30875987
				
			@ -386,7 +386,7 @@ static struct packed_ref_cache *get_packed_ref_cache(struct files_ref_store *ref
 | 
			
		||||
 | 
			
		||||
		refs->packed = xcalloc(1, sizeof(*refs->packed));
 | 
			
		||||
		acquire_packed_ref_cache(refs->packed);
 | 
			
		||||
		refs->packed->cache = create_ref_cache(refs);
 | 
			
		||||
		refs->packed->cache = create_ref_cache(&refs->base, NULL);
 | 
			
		||||
		refs->packed->cache->root->flag &= ~REF_INCOMPLETE;
 | 
			
		||||
		f = fopen(packed_refs_file, "r");
 | 
			
		||||
		if (f) {
 | 
			
		||||
@ -430,9 +430,11 @@ static void add_packed_ref(struct files_ref_store *refs,
 | 
			
		||||
 * (without recursing).  dirname must end with '/'.  dir must be the
 | 
			
		||||
 * directory entry corresponding to dirname.
 | 
			
		||||
 */
 | 
			
		||||
void read_loose_refs(const char *dirname, struct ref_dir *dir)
 | 
			
		||||
static void loose_fill_ref_dir(struct ref_store *ref_store,
 | 
			
		||||
			       struct ref_dir *dir, const char *dirname)
 | 
			
		||||
{
 | 
			
		||||
	struct files_ref_store *refs = dir->cache->ref_store;
 | 
			
		||||
	struct files_ref_store *refs =
 | 
			
		||||
		files_downcast(ref_store, REF_STORE_READ, "fill_ref_dir");
 | 
			
		||||
	DIR *d;
 | 
			
		||||
	struct dirent *de;
 | 
			
		||||
	int dirnamelen = strlen(dirname);
 | 
			
		||||
@ -515,7 +517,7 @@ static struct ref_dir *get_loose_refs(struct files_ref_store *refs)
 | 
			
		||||
		 * are about to read the only subdirectory that can
 | 
			
		||||
		 * hold references:
 | 
			
		||||
		 */
 | 
			
		||||
		refs->loose = create_ref_cache(refs);
 | 
			
		||||
		refs->loose = create_ref_cache(&refs->base, loose_fill_ref_dir);
 | 
			
		||||
 | 
			
		||||
		/* We're going to fill the top level ourselves: */
 | 
			
		||||
		refs->loose->root->flag &= ~REF_INCOMPLETE;
 | 
			
		||||
 | 
			
		||||
@ -4,9 +4,6 @@
 | 
			
		||||
#include "ref-cache.h"
 | 
			
		||||
#include "../iterator.h"
 | 
			
		||||
 | 
			
		||||
/* FIXME: This declaration shouldn't be here */
 | 
			
		||||
void read_loose_refs(const char *dirname, struct ref_dir *dir);
 | 
			
		||||
 | 
			
		||||
void add_entry_to_dir(struct ref_dir *dir, struct ref_entry *entry)
 | 
			
		||||
{
 | 
			
		||||
	ALLOC_GROW(dir->entries, dir->nr + 1, dir->alloc);
 | 
			
		||||
@ -25,7 +22,10 @@ struct ref_dir *get_ref_dir(struct ref_entry *entry)
 | 
			
		||||
	assert(entry->flag & REF_DIR);
 | 
			
		||||
	dir = &entry->u.subdir;
 | 
			
		||||
	if (entry->flag & REF_INCOMPLETE) {
 | 
			
		||||
		read_loose_refs(entry->name, dir);
 | 
			
		||||
		if (!dir->cache->fill_ref_dir)
 | 
			
		||||
			die("BUG: incomplete ref_store without fill_ref_dir function");
 | 
			
		||||
 | 
			
		||||
		dir->cache->fill_ref_dir(dir->cache->ref_store, dir, entry->name);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Manually add refs/bisect, which, being
 | 
			
		||||
@ -63,11 +63,13 @@ struct ref_entry *create_ref_entry(const char *refname,
 | 
			
		||||
	return ref;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ref_cache *create_ref_cache(struct files_ref_store *refs)
 | 
			
		||||
struct ref_cache *create_ref_cache(struct ref_store *refs,
 | 
			
		||||
				   fill_ref_dir_fn *fill_ref_dir)
 | 
			
		||||
{
 | 
			
		||||
	struct ref_cache *ret = xcalloc(1, sizeof(*ret));
 | 
			
		||||
 | 
			
		||||
	ret->ref_store = refs;
 | 
			
		||||
	ret->fill_ref_dir = fill_ref_dir;
 | 
			
		||||
	ret->root = create_dir_entry(ret, "", 0, 1);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,27 @@
 | 
			
		||||
#ifndef REFS_REF_CACHE_H
 | 
			
		||||
#define REFS_REF_CACHE_H
 | 
			
		||||
 | 
			
		||||
struct ref_dir;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * If this ref_cache is filled lazily, this function is used to load
 | 
			
		||||
 * information into the specified ref_dir (shallow or deep, at the
 | 
			
		||||
 * option of the ref_store). dirname includes a trailing slash.
 | 
			
		||||
 */
 | 
			
		||||
typedef void fill_ref_dir_fn(struct ref_store *ref_store,
 | 
			
		||||
			     struct ref_dir *dir, const char *dirname);
 | 
			
		||||
 | 
			
		||||
struct ref_cache {
 | 
			
		||||
	struct ref_entry *root;
 | 
			
		||||
 | 
			
		||||
	/* A pointer to the files_ref_store whose cache this is: */
 | 
			
		||||
	struct files_ref_store *ref_store;
 | 
			
		||||
	/* A pointer to the ref_store whose cache this is: */
 | 
			
		||||
	struct ref_store *ref_store;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Function used (if necessary) to lazily-fill cache. May be
 | 
			
		||||
	 * NULL.
 | 
			
		||||
	 */
 | 
			
		||||
	fill_ref_dir_fn *fill_ref_dir;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@ -174,9 +190,14 @@ struct ref_entry *create_ref_entry(const char *refname,
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return a pointer to a new `ref_cache`. Its top-level starts out
 | 
			
		||||
 * marked incomplete.
 | 
			
		||||
 * marked incomplete. If `fill_ref_dir` is non-NULL, it is the
 | 
			
		||||
 * function called to fill in incomplete directories in the
 | 
			
		||||
 * `ref_cache` when they are accessed. If it is NULL, then the whole
 | 
			
		||||
 * `ref_cache` must be filled (including clearing its directories'
 | 
			
		||||
 * `REF_INCOMPLETE` bits) before it is used.
 | 
			
		||||
 */
 | 
			
		||||
struct ref_cache *create_ref_cache(struct files_ref_store *refs);
 | 
			
		||||
struct ref_cache *create_ref_cache(struct ref_store *refs,
 | 
			
		||||
				   fill_ref_dir_fn *fill_ref_dir);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Free the `ref_cache` and all of its associated data.
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user