diff options
-rw-r--r-- | cmdline.h | 8 | ||||
-rw-r--r-- | eval.c | 6 | ||||
-rw-r--r-- | parse.c | 39 | ||||
-rw-r--r-- | stat.c | 5 | ||||
-rw-r--r-- | stat.h | 10 |
5 files changed, 37 insertions, 31 deletions
@@ -22,6 +22,7 @@ #define BFS_CMDLINE_H #include "color.h" +#include "trie.h" /** * Various debugging flags. @@ -56,11 +57,6 @@ struct root { }; /** - * An open file for the command line. - */ -struct open_file; - -/** * The parsed command line. */ struct cmdline { @@ -103,7 +99,7 @@ struct cmdline { struct expr *expr; /** All the open files owned by the command line. */ - struct open_file *open_files; + struct trie open_files; /** The number of open files owned by the command line. */ int nopen_files; }; @@ -1142,10 +1142,8 @@ static bool eval_file_unique(struct eval_state *state, struct trie *seen) { return false; } - // Glue the device and inode numbers together as a unique ID - unsigned char id[sizeof(statbuf->dev) + sizeof(statbuf->ino)]; - memcpy(id, &statbuf->dev, sizeof(statbuf->dev)); - memcpy(id + sizeof(statbuf->dev), &statbuf->ino, sizeof(statbuf->ino)); + bfs_file_id id; + bfs_stat_id(statbuf, &id); struct trie_leaf *leaf = trie_insert_mem(seen, id, sizeof(id)); if (!leaf) { @@ -246,12 +246,6 @@ struct open_file { CFILE *cfile; /** The path to the file (for diagnostics). */ const char *path; - /** Device number (for deduplication). */ - dev_t dev; - /** Inode number (for deduplication). */ - ino_t ino; - /** The next open file in the chain. */ - struct open_file *next; }; /** @@ -268,9 +262,9 @@ int free_cmdline(struct cmdline *cmdline) { free_bfs_mtab(cmdline->mtab); - struct open_file *ofile = cmdline->open_files; - while (ofile) { - struct open_file *next = ofile->next; + struct trie_leaf *leaf; + while ((leaf = trie_first_leaf(&cmdline->open_files))) { + struct open_file *ofile = (struct open_file *)leaf->value; if (cfclose(ofile->cfile) != 0) { if (cerr) { @@ -280,8 +274,9 @@ int free_cmdline(struct cmdline *cmdline) { } free(ofile); - ofile = next; + trie_remove_mem(&cmdline->open_files, leaf->key, leaf->length); } + trie_destroy(&cmdline->open_files); if (cout && fflush(cout->file) != 0) { if (cerr) { @@ -429,26 +424,27 @@ static int expr_open(struct parser_state *state, struct expr *expr, const char * goto out_close; } - for (struct open_file *ofile = cmdline->open_files; ofile; ofile = ofile->next) { - if (ofile->dev == sb.dev && ofile->ino == sb.ino) { - expr->cfile = ofile->cfile; - ret = 0; - goto out_close; - } + bfs_file_id id; + bfs_stat_id(&sb, &id); + + struct trie_leaf *leaf = trie_insert_mem(&cmdline->open_files, id, sizeof(id)); + if (leaf->value) { + struct open_file *ofile = (struct open_file *)leaf->value; + expr->cfile = ofile->cfile; + ret = 0; + goto out_close; } struct open_file *ofile = malloc(sizeof(*ofile)); if (!ofile) { perror("malloc()"); + trie_remove_mem(&cmdline->open_files, leaf->key, leaf->length); goto out_close; } ofile->cfile = cfile; ofile->path = path; - ofile->dev = sb.dev; - ofile->ino = sb.ino; - ofile->next = cmdline->open_files; - cmdline->open_files = ofile; + leaf->value = ofile; ++cmdline->nopen_files; expr->cfile = cfile; @@ -3139,9 +3135,10 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) { cmdline->ignore_races = false; cmdline->unique = false; cmdline->expr = &expr_true; - cmdline->open_files = NULL; cmdline->nopen_files = 0; + trie_init(&cmdline->open_files); + static char* default_argv[] = {"bfs", NULL}; if (argc < 1) { argc = 1; @@ -334,3 +334,8 @@ const struct timespec *bfs_stat_time(const struct bfs_stat *buf, enum bfs_stat_f return NULL; } } + +void bfs_stat_id(const struct bfs_stat *buf, bfs_file_id *id) { + memcpy(*id, &buf->dev, sizeof(buf->dev)); + memcpy(*id + sizeof(buf->dev), &buf->ino, sizeof(buf->ino)); +} @@ -126,4 +126,14 @@ int bfs_fstat(int fd, struct bfs_stat *buf); */ const struct timespec *bfs_stat_time(const struct bfs_stat *buf, enum bfs_stat_field field); +/** + * A unique ID for a file. + */ +typedef unsigned char bfs_file_id[sizeof(dev_t) + sizeof(ino_t)]; + +/** + * Compute a unique ID for a file. + */ +void bfs_stat_id(const struct bfs_stat *buf, bfs_file_id *id); + #endif // BFS_STAT_H |