commit b504a804cf269d86aebf0f805cc5eb135423f76a from: Stefan Sperling date: Tue Jan 08 21:18:23 2019 UTC switch file index entries from TAILQ to got_pathset commit - 8f6d9a6a62b3640c758a23e26cd567e2e44406e1 commit + b504a804cf269d86aebf0f805cc5eb135423f76a blob - 05a75f232076b90a968af03806db100560885424 blob + 20cc091e54b2160f436901349992bfba5394f004 --- lib/fileindex.c +++ lib/fileindex.c @@ -25,6 +25,7 @@ #include "got_error.h" +#include "got_lib_pathset.h" #include "got_lib_fileindex.h" const struct got_error * @@ -94,71 +95,70 @@ const struct got_error * got_fileindex_entry_add(struct got_fileindex *fileindex, struct got_fileindex_entry *entry) { - /* TODO keep entries sorted by name */ - TAILQ_INSERT_TAIL(&fileindex->entries, entry, entry); - fileindex->nentries++; - return NULL; + return got_pathset_add(fileindex->entries, entry->path, entry); } -void +const struct got_error * got_fileindex_entry_remove(struct got_fileindex *fileindex, struct got_fileindex_entry *entry) { - TAILQ_REMOVE(&fileindex->entries, entry, entry); - fileindex->nentries--; + return got_pathset_remove(NULL, fileindex->entries, entry->path); } struct got_fileindex_entry * got_fileindex_entry_get(struct got_fileindex *fileindex, const char *path) { struct got_fileindex_entry *entry; - TAILQ_FOREACH(entry, &fileindex->entries, entry) { - if (strcmp(entry->path, path) == 0) - return entry; - } + entry = (struct got_fileindex_entry *)got_pathset_get( + fileindex->entries, path); + return entry; +} - return NULL; +struct pathset_cb_arg { + got_fileindex_cb cb; + void *cb_arg; +}; + +static const struct got_error * +pathset_cb(const char *path, void *data, void *arg) +{ + struct got_fileindex_entry *entry = data; + struct pathset_cb_arg *a = arg; + return (*a->cb)(a->cb_arg, entry); } const struct got_error * got_fileindex_for_each_entry_safe(struct got_fileindex *fileindex, - const struct got_error *(cb)(void *, struct got_fileindex_entry *), - void *cb_arg) + got_fileindex_cb cb, void *cb_arg) { - const struct got_error *err = NULL; - struct got_fileindex_entry *entry, *tmp; + struct pathset_cb_arg arg; - TAILQ_FOREACH_SAFE(entry, &fileindex->entries, entry, tmp) { - err = cb(cb_arg, entry); - if (err) - break; - } - - return err; + arg.cb = cb; + arg.cb_arg = cb_arg; + return got_pathset_for_each_safe(fileindex->entries, pathset_cb, &arg); } -struct got_fileindex * -got_fileindex_alloc(void) +const struct got_error * +got_fileindex_alloc(struct got_fileindex **fileindex) { - struct got_fileindex *fileindex; + *fileindex = calloc(1, sizeof(**fileindex)); + if (*fileindex == NULL) + return got_error_from_errno(); - fileindex = calloc(1, sizeof(*fileindex)); - if (fileindex) - TAILQ_INIT(&fileindex->entries); - return fileindex; + (*fileindex)->entries = got_pathset_alloc(); + if ((*fileindex)->entries == NULL) { + free(*fileindex); + *fileindex = NULL; + return got_error_from_errno(); + } + + return NULL; } void got_fileindex_free(struct got_fileindex *fileindex) { - struct got_fileindex_entry *entry; - - while (!TAILQ_EMPTY(&fileindex->entries)) { - entry = TAILQ_FIRST(&fileindex->entries); - TAILQ_REMOVE(&fileindex->entries, entry, entry); - got_fileindex_entry_free(entry); - fileindex->nentries--; - } + got_pathset_free(fileindex->entries); free(fileindex); } @@ -276,23 +276,38 @@ write_fileindex_entry(SHA1_CTX *ctx, struct got_filein return err; } +struct write_entry_cb_arg { + SHA1_CTX *ctx; + FILE *outfile; +}; + +static const struct got_error * +write_entry_cb(const char *path, void *data, void *arg) +{ + struct got_fileindex_entry *entry = data; + struct write_entry_cb_arg *a = arg; + + return write_fileindex_entry(a->ctx, entry, a->outfile); +} + const struct got_error * got_fileindex_write(struct got_fileindex *fileindex, FILE *outfile) { + const struct got_error *err = NULL; struct got_fileindex_hdr hdr; - struct got_fileindex_entry *entry; SHA1_CTX ctx; uint8_t sha1[SHA1_DIGEST_LENGTH]; size_t n; const size_t len = sizeof(hdr.signature) + sizeof(hdr.version) + sizeof(hdr.nentries); uint8_t buf[len]; + struct write_entry_cb_arg arg; SHA1Init(&ctx); hdr.signature = htobe32(GOT_FILE_INDEX_SIGNATURE); hdr.version = htobe32(GOT_FILE_INDEX_VERSION); - hdr.nentries = htobe32(fileindex->nentries); + hdr.nentries = htobe32(got_pathset_num_elements(fileindex->entries)); memcpy(buf, &hdr, len); SHA1Update(&ctx, buf, len); @@ -300,12 +315,12 @@ got_fileindex_write(struct got_fileindex *fileindex, F if (n != len) return got_ferror(outfile, GOT_ERR_IO); - TAILQ_FOREACH(entry, &fileindex->entries, entry) { - const struct got_error *err; - err = write_fileindex_entry(&ctx, entry, outfile); - if (err) - return err; - } + arg.ctx = &ctx; + arg.outfile = outfile; + err = got_pathset_for_each_safe(fileindex->entries, write_entry_cb, + &arg); + if (err) + return err; SHA1Final(sha1, &ctx); n = fwrite(sha1, 1, sizeof(sha1), outfile); blob - 327aba8462b861055c62b7528aebd302317f75d2 blob + 4330cebe1b3a76ce972add2e1139baa62d8d43c0 --- lib/got_lib_fileindex.h +++ lib/got_lib_fileindex.h @@ -22,7 +22,6 @@ * applied back to the filesystem. */ struct got_fileindex_entry { - TAILQ_ENTRY(got_fileindex_entry) entry; uint64_t ctime_sec; uint64_t ctime_nsec; uint64_t mtime_sec; @@ -70,8 +69,7 @@ struct got_fileindex_entry { #define GOT_INDEX_ENTRY_STAGE_THEIRS 3 struct got_fileindex { - uint32_t nentries; - TAILQ_HEAD(, got_fileindex_entry) entries; + struct got_pathset *entries; }; /* On-disk file index header structure. */ @@ -90,16 +88,17 @@ const struct got_error *got_fileindex_entry_update(str const struct got_error *got_fileindex_entry_alloc(struct got_fileindex_entry **, const char *, const char *, uint8_t *, uint8_t *); void got_fileindex_entry_free(struct got_fileindex_entry *); -struct got_fileindex *got_fileindex_alloc(void); +const struct got_error *got_fileindex_alloc(struct got_fileindex **); void got_fileindex_free(struct got_fileindex *); const struct got_error *got_fileindex_write(struct got_fileindex *, FILE *); const struct got_error *got_fileindex_entry_add(struct got_fileindex *, struct got_fileindex_entry *); -void got_fileindex_entry_remove(struct got_fileindex *, +const struct got_error *got_fileindex_entry_remove(struct got_fileindex *, struct got_fileindex_entry *); struct got_fileindex_entry *got_fileindex_entry_get(struct got_fileindex *, const char *); const struct got_error *got_fileindex_read(struct got_fileindex *, FILE *); +typedef const struct got_error *(*got_fileindex_cb)(void *, + struct got_fileindex_entry *); const struct got_error *got_fileindex_for_each_entry_safe( - struct got_fileindex *, - const struct got_error *(cb)(void *, struct got_fileindex_entry *), void *); + struct got_fileindex *, got_fileindex_cb cb, void *); blob - 56b380323951c2f2a1076ffd847d16bcd37724bf blob + 55c345789881a19b86a5f73f6ce10fb6fbde2ff0 --- lib/worktree.c +++ lib/worktree.c @@ -925,11 +925,9 @@ got_worktree_checkout_files(struct got_worktree *workt if (err) return err; - fileindex = got_fileindex_alloc(); - if (fileindex == NULL) { - err = got_error_from_errno(); + err = got_fileindex_alloc(&fileindex); + if (err) goto done; - } if (asprintf(&fileindex_path, "%s/%s/%s", worktree->root_path, GOT_WORKTREE_GOT_DIR, GOT_WORKTREE_FILE_INDEX) == -1) {