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