Git fork
at reftables-rust 216 lines 7.8 kB view raw
1#ifndef REFS_REF_CACHE_H 2#define REFS_REF_CACHE_H 3 4#include "hash.h" 5 6struct ref_dir; 7struct ref_store; 8struct repository; 9 10/* 11 * If this ref_cache is filled lazily, this function is used to load 12 * information into the specified ref_dir (shallow or deep, at the 13 * option of the ref_store). dirname includes a trailing slash. 14 */ 15typedef void fill_ref_dir_fn(struct ref_store *ref_store, 16 struct ref_dir *dir, const char *dirname); 17 18struct ref_cache { 19 struct ref_entry *root; 20 21 /* A pointer to the ref_store whose cache this is: */ 22 struct ref_store *ref_store; 23 24 /* 25 * Function used (if necessary) to lazily-fill cache. May be 26 * NULL. 27 */ 28 fill_ref_dir_fn *fill_ref_dir; 29}; 30 31/* 32 * Information used (along with the information in ref_entry) to 33 * describe a single cached reference. This data structure only 34 * occurs embedded in a union in struct ref_entry, and only when 35 * (ref_entry->flag & REF_DIR) is zero. 36 */ 37struct ref_value { 38 /* 39 * The name of the object to which this reference resolves 40 * (which may be a tag object). If REF_ISBROKEN, this is 41 * null. If REF_ISSYMREF, then this is the name of the object 42 * referred to by the last reference in the symlink chain. 43 */ 44 struct object_id oid; 45 char *referent; 46}; 47 48/* 49 * Information used (along with the information in ref_entry) to 50 * describe a level in the hierarchy of references. This data 51 * structure only occurs embedded in a union in struct ref_entry, and 52 * only when (ref_entry.flag & REF_DIR) is set. In that case, 53 * (ref_entry.flag & REF_INCOMPLETE) determines whether the references 54 * in the directory have already been read: 55 * 56 * (ref_entry.flag & REF_INCOMPLETE) unset -- a directory of loose 57 * or packed references, already read. 58 * 59 * (ref_entry.flag & REF_INCOMPLETE) set -- a directory of loose 60 * references that hasn't been read yet (nor has any of its 61 * subdirectories). 62 * 63 * Entries within a directory are stored within a growable array of 64 * pointers to ref_entries (entries, nr, alloc). Entries 0 <= i < 65 * sorted are sorted by their component name in strcmp() order and the 66 * remaining entries are unsorted. 67 * 68 * Loose references are read lazily, one directory at a time. When a 69 * directory of loose references is read, then all of the references 70 * in that directory are stored, and REF_INCOMPLETE stubs are created 71 * for any subdirectories, but the subdirectories themselves are not 72 * read. The reading is triggered by get_ref_dir(). 73 */ 74struct ref_dir { 75 int nr, alloc; 76 77 /* 78 * Entries with index 0 <= i < sorted are sorted by name. New 79 * entries are appended to the list unsorted, and are sorted 80 * only when required; thus we avoid the need to sort the list 81 * after the addition of every reference. 82 */ 83 int sorted; 84 85 /* The ref_cache containing this entry: */ 86 struct ref_cache *cache; 87 88 struct ref_entry **entries; 89}; 90 91/* 92 * Bit values for ref_entry::flag. REF_ISSYMREF=0x01, 93 * REF_ISPACKED=0x02, REF_ISBROKEN=0x04 and REF_BAD_NAME=0x08 are 94 * public values; see refs.h. 95 */ 96 97/* ref_entry represents a directory of references */ 98#define REF_DIR 0x10 99 100/* 101 * Entry has not yet been read from disk (used only for REF_DIR 102 * entries representing loose references) 103 */ 104#define REF_INCOMPLETE 0x20 105 106/* 107 * A ref_entry represents either a reference or a "subdirectory" of 108 * references. 109 * 110 * Each directory in the reference namespace is represented by a 111 * ref_entry with (flags & REF_DIR) set and containing a subdir member 112 * that holds the entries in that directory that have been read so 113 * far. If (flags & REF_INCOMPLETE) is set, then the directory and 114 * its subdirectories haven't been read yet. REF_INCOMPLETE is only 115 * used for loose reference directories. 116 * 117 * References are represented by a ref_entry with (flags & REF_DIR) 118 * unset and a value member that describes the reference's value. The 119 * flag member is at the ref_entry level, but it is also needed to 120 * interpret the contents of the value field (in other words, a 121 * ref_value object is not very much use without the enclosing 122 * ref_entry). 123 * 124 * Reference names cannot end with slash and directories' names are 125 * always stored with a trailing slash (except for the top-level 126 * directory, which is always denoted by ""). This has two nice 127 * consequences: (1) when the entries in each subdir are sorted 128 * lexicographically by name (as they usually are), the references in 129 * a whole tree can be generated in lexicographic order by traversing 130 * the tree in left-to-right, depth-first order; (2) the names of 131 * references and subdirectories cannot conflict, and therefore the 132 * presence of an empty subdirectory does not block the creation of a 133 * similarly-named reference. (The fact that reference names with the 134 * same leading components can conflict *with each other* is a 135 * separate issue that is regulated by refs_verify_refname_available().) 136 * 137 * Please note that the name field contains the fully-qualified 138 * reference (or subdirectory) name. Space could be saved by only 139 * storing the relative names. But that would require the full names 140 * to be generated on the fly when iterating in do_for_each_ref(), and 141 * would break callback functions, who have always been able to assume 142 * that the name strings that they are passed will not be freed during 143 * the iteration. 144 */ 145struct ref_entry { 146 unsigned char flag; /* ISSYMREF? ISPACKED? */ 147 union { 148 struct ref_value value; /* if not (flags&REF_DIR) */ 149 struct ref_dir subdir; /* if (flags&REF_DIR) */ 150 } u; 151 /* 152 * The full name of the reference (e.g., "refs/heads/master") 153 * or the full name of the directory with a trailing slash 154 * (e.g., "refs/heads/"): 155 */ 156 char name[FLEX_ARRAY]; 157}; 158 159/* 160 * Return the index of the entry with the given refname from the 161 * ref_dir (non-recursively), sorting dir if necessary. Return -1 if 162 * no such entry is found. dir must already be complete. 163 */ 164int search_ref_dir(struct ref_dir *dir, const char *refname, size_t len); 165 166struct ref_dir *get_ref_dir(struct ref_entry *entry); 167 168/* 169 * Create a struct ref_entry object for the specified dirname. 170 * dirname is the name of the directory with a trailing slash (e.g., 171 * "refs/heads/") or "" for the top-level directory. 172 */ 173struct ref_entry *create_dir_entry(struct ref_cache *cache, 174 const char *dirname, size_t len); 175 176struct ref_entry *create_ref_entry(const char *refname, 177 const char *referent, 178 const struct object_id *oid, int flag); 179 180/* 181 * Return a pointer to a new `ref_cache`. Its top-level starts out 182 * marked incomplete. If `fill_ref_dir` is non-NULL, it is the 183 * function called to fill in incomplete directories in the 184 * `ref_cache` when they are accessed. If it is NULL, then the whole 185 * `ref_cache` must be filled (including clearing its directories' 186 * `REF_INCOMPLETE` bits) before it is used, and `refs` can be NULL, 187 * too. 188 */ 189struct ref_cache *create_ref_cache(struct ref_store *refs, 190 fill_ref_dir_fn *fill_ref_dir); 191 192/* 193 * Free the `ref_cache` and all of its associated data. 194 */ 195void free_ref_cache(struct ref_cache *cache); 196 197/* 198 * Add a ref_entry to the end of dir (unsorted). Entry is always 199 * stored directly in dir; no recursion into subdirectories is 200 * done. 201 */ 202void add_entry_to_dir(struct ref_dir *dir, struct ref_entry *entry); 203 204/* 205 * Start iterating over references in `cache`. If `prefix` is 206 * specified, only include references whose names start with that 207 * prefix. If `prime_dir` is true, then fill any incomplete 208 * directories before beginning the iteration. The output is ordered 209 * by refname. 210 */ 211struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache, 212 const char *prefix, 213 struct repository *repo, 214 int prime_dir); 215 216#endif /* REFS_REF_CACHE_H */