3 #include "cache-tree.h"
7 struct cache_tree *cache_tree(void)
9 struct cache_tree *it = xcalloc(1, sizeof(struct cache_tree));
14 void cache_tree_free(struct cache_tree *it)
20 for (i = 0; i < it->subtree_nr; i++)
21 cache_tree_free(it->down[i]->cache_tree);
26 static struct cache_tree_sub *find_subtree(struct cache_tree *it,
32 struct cache_tree_sub *down;
33 for (i = 0; i < it->subtree_nr; i++) {
35 if (down->namelen == pathlen &&
36 !memcmp(down->name, path, pathlen))
41 if (it->subtree_alloc <= it->subtree_nr) {
42 it->subtree_alloc = alloc_nr(it->subtree_alloc);
43 it->down = xrealloc(it->down, it->subtree_alloc *
46 down = xmalloc(sizeof(*down) + pathlen + 1);
47 down->cache_tree = NULL; /* cache_tree(); */
48 down->namelen = pathlen;
49 memcpy(down->name, path, pathlen);
50 down->name[pathlen] = 0; /* not strictly needed */
51 it->down[it->subtree_nr++] = down;
55 void cache_tree_invalidate_path(struct cache_tree *it, const char *path)
59 * ==> find "a", have it invalidate "b/c"
62 * ==> if "a" exists as a subtree, remove it.
66 struct cache_tree_sub *down;
70 slash = strchr(path, '/');
74 namelen = strlen(path);
75 for (i = 0; i < it->subtree_nr; i++) {
76 if (it->down[i]->namelen == namelen &&
77 !memcmp(it->down[i]->name, path, namelen))
80 if (i < it->subtree_nr) {
81 cache_tree_free(it->down[i]->cache_tree);
86 * move 4 and 5 up one place (2 entries)
87 * 2 = 6 - 3 - 1 = subtree_nr - i - 1
89 memmove(it->down+i, it->down+i+1,
90 sizeof(struct cache_tree_sub *) *
91 (it->subtree_nr - i - 1));
96 namelen = slash - path;
97 down = find_subtree(it, path, namelen, 0);
99 cache_tree_invalidate_path(down->cache_tree, slash + 1);
102 static int verify_cache(struct cache_entry **cache,
107 /* Verify that the tree is merged */
109 for (i = 0; i < entries; i++) {
110 struct cache_entry *ce = cache[i];
113 fprintf(stderr, "...\n");
116 fprintf(stderr, "%s: unmerged (%s)\n",
117 ce->name, sha1_to_hex(ce->sha1));
123 /* Also verify that the cache does not have path and path/file
124 * at the same time. At this point we know the cache has only
128 for (i = 0; i < entries - 1; i++) {
129 /* path/file always comes after path because of the way
130 * the cache is sorted. Also path can appear only once,
131 * which means conflicting one would immediately follow.
133 const char *this_name = cache[i]->name;
134 const char *next_name = cache[i+1]->name;
135 int this_len = strlen(this_name);
136 if (this_len < strlen(next_name) &&
137 strncmp(this_name, next_name, this_len) == 0 &&
138 next_name[this_len] == '/') {
140 fprintf(stderr, "...\n");
143 fprintf(stderr, "You have both %s and %s\n",
144 this_name, next_name);
152 static void discard_unused_subtrees(struct cache_tree *it)
154 struct cache_tree_sub **down = it->down;
155 int nr = it->subtree_nr;
157 for (dst = src = 0; src < nr; src++) {
158 struct cache_tree_sub *s = down[src];
162 cache_tree_free(s->cache_tree);
169 static int update_one(struct cache_tree *it,
170 struct cache_entry **cache,
176 unsigned long size, offset;
180 if (0 <= it->entry_count && has_sha1_file(it->sha1))
181 return it->entry_count;
184 * We first scan for subtrees and update them; we start by
185 * marking existing subtrees -- the ones that are unmarked
186 * should not be in the result.
188 for (i = 0; i < it->subtree_nr; i++)
189 it->down[i]->used = 0;
192 * Find the subtrees and update them.
194 for (i = 0; i < entries; i++) {
195 struct cache_entry *ce = cache[i];
196 struct cache_tree_sub *sub;
197 const char *path, *slash;
198 int pathlen, sublen, subcnt;
201 pathlen = ce_namelen(ce);
202 if (pathlen <= baselen || memcmp(base, path, baselen))
203 break; /* at the end of this level */
205 slash = strchr(path + baselen, '/');
209 * a/bbb/c (base = a/, slash = /c)
211 * path+baselen = bbb/c, sublen = 3
213 sublen = slash - (path + baselen);
214 sub = find_subtree(it, path + baselen, sublen, 1);
215 if (!sub->cache_tree)
216 sub->cache_tree = cache_tree();
217 subcnt = update_one(sub->cache_tree,
218 cache + i, entries - i,
220 baselen + sublen + 1,
226 discard_unused_subtrees(it);
229 * Then write out the tree object for this level.
232 buffer = xmalloc(size);
235 for (i = 0; i < entries; i++) {
236 struct cache_entry *ce = cache[i];
237 struct cache_tree_sub *sub;
238 const char *path, *slash;
240 const unsigned char *sha1;
244 pathlen = ce_namelen(ce);
245 if (pathlen <= baselen || memcmp(base, path, baselen))
246 break; /* at the end of this level */
248 slash = strchr(path + baselen, '/');
250 entlen = slash - (path + baselen);
251 sub = find_subtree(it, path + baselen, entlen, 0);
253 die("cache-tree.c: '%.*s' in '%s' not found",
254 entlen, path + baselen, path);
255 i += sub->cache_tree->entry_count - 1;
256 sha1 = sub->cache_tree->sha1;
261 mode = ntohl(ce->ce_mode);
262 entlen = pathlen - baselen;
264 if (!missing_ok && !has_sha1_file(sha1))
265 return error("invalid object %s", sha1_to_hex(sha1));
268 continue; /* entry being removed */
270 if (size < offset + entlen + 100) {
271 size = alloc_nr(offset + entlen + 100);
272 buffer = xrealloc(buffer, size);
274 offset += sprintf(buffer + offset,
275 "%o %.*s", mode, entlen, path + baselen);
276 buffer[offset++] = 0;
277 memcpy(buffer + offset, sha1, 20);
281 fprintf(stderr, "cache-tree %o %.*s\n",
282 mode, entlen, path + baselen);
286 write_sha1_file(buffer, offset, tree_type, it->sha1);
290 fprintf(stderr, "cache-tree (%d ent, %d subtree) %s\n",
291 it->entry_count, it->subtree_nr,
292 sha1_to_hex(it->sha1));
297 int cache_tree_update(struct cache_tree *it,
298 struct cache_entry **cache,
303 i = verify_cache(cache, entries);
306 i = update_one(it, cache, entries, "", 0, missing_ok);
312 static void *write_one(struct cache_tree *it,
317 unsigned long *offset)
321 /* One "cache-tree" entry consists of the following:
322 * path (NUL terminated)
323 * entry_count, subtree_nr ("%d %d\n")
324 * tree-sha1 (missing if invalid)
325 * subtree_nr "cache-tree" entries for subtrees.
327 if (*size < *offset + pathlen + 100) {
328 *size = alloc_nr(*offset + pathlen + 100);
329 buffer = xrealloc(buffer, *size);
331 *offset += sprintf(buffer + *offset, "%.*s%c%d %d\n",
333 it->entry_count, it->subtree_nr);
336 if (0 <= it->entry_count)
337 fprintf(stderr, "cache-tree <%.*s> (%d ent, %d subtree) %s\n",
338 pathlen, path, it->entry_count, it->subtree_nr,
339 sha1_to_hex(it->sha1));
341 fprintf(stderr, "cache-tree <%.*s> (%d subtree) invalid\n",
342 pathlen, path, it->subtree_nr);
345 if (0 <= it->entry_count) {
346 memcpy(buffer + *offset, it->sha1, 20);
349 for (i = 0; i < it->subtree_nr; i++) {
350 struct cache_tree_sub *down = it->down[i];
351 buffer = write_one(down->cache_tree, down->name, down->namelen,
352 buffer, size, offset);
357 static void *cache_tree_write(const unsigned char *cache_sha1,
358 struct cache_tree *root,
359 unsigned long *offset_p)
362 unsigned long size = 8192;
363 char *buffer = xmalloc(size);
365 /* the cache checksum of the corresponding index file. */
366 memcpy(buffer, cache_sha1, 20);
369 return write_one(root, path, 0, buffer, &size, offset_p);
372 static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
374 const char *buf = *buffer;
375 unsigned long size = *size_p;
376 struct cache_tree *it;
380 /* skip name, but make sure name exists */
381 while (size && *buf) {
389 if (sscanf(buf, "%d %d\n", &it->entry_count, &subtree_nr) != 2)
391 while (size && *buf && *buf != '\n') {
398 if (0 <= it->entry_count) {
401 memcpy(it->sha1, buf, 20);
407 if (0 <= it->entry_count)
408 fprintf(stderr, "cache-tree <%s> (%d ent, %d subtree) %s\n",
409 *buffer, it->entry_count, subtree_nr,
410 sha1_to_hex(it->sha1));
412 fprintf(stderr, "cache-tree <%s> (%d subtrees) invalid\n",
413 *buffer, subtree_nr);
417 * Just a heuristic -- we do not add directories that often but
418 * we do not want to have to extend it immediately when we do,
421 it->subtree_alloc = subtree_nr + 2;
422 it->down = xcalloc(it->subtree_alloc, sizeof(struct cache_tree_sub *));
423 for (i = 0; i < subtree_nr; i++) {
424 /* read each subtree */
425 struct cache_tree *sub;
426 const char *name = buf;
428 sub = read_one(&buf, &size);
431 namelen = strlen(name);
432 it->down[i] = find_subtree(it, name, namelen, 1);
433 it->down[i]->cache_tree = sub;
435 if (subtree_nr != it->subtree_nr)
436 die("cache-tree: internal error");
446 static struct cache_tree *cache_tree_read(unsigned char *sha1,
450 /* check the cache-tree matches the index */
451 if (memcmp(buffer, sha1, 20))
452 return NULL; /* checksum mismatch */
454 return NULL; /* not the whole tree */
457 return read_one(&buffer, &size);
460 struct cache_tree *read_cache_tree(unsigned char *sha1)
465 unsigned long size = 0;
467 struct cache_tree *it;
469 sprintf(path, "%s.aux", get_index_file());
470 fd = open(path, O_RDONLY);
477 map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
479 if (map == MAP_FAILED)
481 it = cache_tree_read(sha1, map, size);
488 int write_cache_tree(const unsigned char *sha1, struct cache_tree *root)
491 unsigned long size = 0;
495 sprintf(path, "%s.aux", get_index_file());
500 fd = open(path, O_WRONLY|O_CREAT, 0666);
503 buffer = buf = cache_tree_write(sha1, root, &size);
505 int written = xwrite(fd, buf, size);