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