commit d572f5860a456fe9ab48d8444dd4cbec28fcae6c from: Stefan Sperling date: Fri Aug 02 13:42:42 2019 UTC eliminate strlen() calls during fileindex rb tree searches commit - 6bf2c31673f0b01187622ccb597eb02eae487be8 commit + d572f5860a456fe9ab48d8444dd4cbec28fcae6c blob - 34114a210f4a19103a09e908e8a037fb1ba73374 blob + 929be76fb48b7a1098cb03f674b1c4ff5f5e08a5 --- include/got_path.h +++ include/got_path.h @@ -51,9 +51,9 @@ int got_path_is_child(const char *, const char *, size /* * Like strcmp() but orders children in subdirectories directly after - * their parents. + * their parents. String lengths must also be passed in. */ -int got_path_cmp(const char *, const char *); +int got_path_cmp(const char *, const char *, size_t, size_t); /* * Path lists allow for predictable concurrent iteration over multiple lists blob - 90e0c5f503c35d412627f3f375b6bdea585afe27 blob + ddcbf40125d27f94162bfe698fd1bf4b255e7390 --- lib/fileindex.c +++ lib/fileindex.c @@ -548,6 +548,8 @@ read_fileindex_entry(struct got_fileindex_entry **entr goto done; err = read_fileindex_path(&entry->path, ctx, infile); + if (err == NULL) + entry->path_len = strlen(entry->path); done: if (err) got_fileindex_entry_free(entry); @@ -695,7 +697,8 @@ diff_fileindex_tree(struct got_fileindex *fileindex, err = got_error_from_errno("asprintf"); break; } - cmp = got_path_cmp((*ie)->path, te_path); + cmp = got_path_cmp((*ie)->path, te_path, + (*ie)->path_len, strlen(te_path)); free(te_path); if (cmp == 0) { if (got_path_is_child((*ie)->path, path, @@ -914,7 +917,8 @@ diff_fileindex_dir(struct got_fileindex *fileindex, err = got_error_from_errno("asprintf"); break; } - cmp = got_path_cmp((*ie)->path, de_path); + cmp = got_path_cmp((*ie)->path, de_path, + (*ie)->path_len, strlen(path) + 1 + de->d_namlen); free(de_path); if (cmp == 0) { err = cb->diff_old_new(cb_arg, *ie, de, path); blob - 3e7fc839a1a76055f7215853e6bd1819dd0140d1 blob + 41f2dcdaa4e970012cbda6aefd5199f0c86fa2a2 --- lib/got_lib_fileindex.h +++ lib/got_lib_fileindex.h @@ -55,6 +55,7 @@ struct got_fileindex_entry { * Variable length, and NUL-padded to a multiple of 8 on disk. */ char *path; + size_t path_len; /* strlen(path) -- kept in memory only! */ /* More data could be here if F_EXTENDED is set; To be determined... */ }; @@ -73,7 +74,7 @@ static inline int got_fileindex_cmp(const struct got_fileindex_entry *e1, const struct got_fileindex_entry *e2) { - return got_path_cmp(e1->path, e2->path); + return got_path_cmp(e1->path, e2->path, e1->path_len, e2->path_len); } RB_PROTOTYPE(got_fileindex_tree, got_fileindex_entry, entry, got_fileindex_cmp); blob - a4c1a16f65eda672d07082db8de443723702caa4 blob + 3605ef1847b2bd3c005f0b2f16f925acf2d76f4d --- lib/path.c +++ lib/path.c @@ -159,10 +159,8 @@ got_path_is_child(const char *child, const char *paren } int -got_path_cmp(const char *path1, const char *path2) +got_path_cmp(const char *path1, const char *path2, size_t len1, size_t len2) { - size_t len1 = strlen(path1); - size_t len2 = strlen(path2); size_t min_len = MIN(len1, len2); size_t i = 0; @@ -234,7 +232,8 @@ got_pathlist_insert(struct got_pathlist_entry **insert */ pe = TAILQ_LAST(pathlist, got_pathlist_head); while (pe) { - int cmp = got_path_cmp(pe->path, path); + int cmp = got_path_cmp(pe->path, path, + strlen(pe->path), strlen(path)); if (cmp == 0) { free(new); /* duplicate */ return NULL; blob - 9f0f7dfad2a3e7de7c9fa8c144bb43dcb96c4654 blob + 5f009d7c9cfb1874b2d260ba7df35257cb60d768 --- lib/reference.c +++ lib/reference.c @@ -639,8 +639,10 @@ insert_ref(struct got_reflist_entry **newp, struct got */ re = SIMPLEQ_FIRST(refs); while (re) { - cmp = got_path_cmp(got_ref_get_name(re->ref), - got_ref_get_name(new->ref)); + const char *name = got_ref_get_name(re->ref); + const char *new_name = got_ref_get_name(new->ref); + cmp = got_path_cmp(name, new_name, strlen(name), + strlen(new_name)); if (cmp == 0) { /* duplicate */ free(new->id); blob - 77022f311e883e0e67963e20af490976c2e29719 blob + b23c7b50712196bd076f5de77b17498bae85707b --- lib/worktree.c +++ lib/worktree.c @@ -2207,7 +2207,8 @@ status_old_new(void *arg, struct got_fileindex_entry * if (a->cancel_cb && a->cancel_cb(a->cancel_arg)) return got_error(GOT_ERR_CANCELLED); - if (got_path_cmp(parent_path, a->status_path) != 0 && + if (got_path_cmp(parent_path, a->status_path, + strlen(parent_path), a->status_path_len) != 0 && !got_path_is_child(parent_path, a->status_path, a->status_path_len)) return NULL; blob - 951b0e5d9dcc4b66f8910ab132b9b27642090cff blob + 07e0baa80ab15cf50861022e1fc478bf14075a7a --- regress/path/path_test.c +++ regress/path/path_test.c @@ -84,7 +84,8 @@ path_cmp(void) const char *path1 = test_data[i].path1; const char *path2 = test_data[i].path2; int expected = test_data[i].expected; - int cmp = got_path_cmp(path1, path2); + int cmp = got_path_cmp(path1, path2, + strlen(path1), strlen(path2)); if (cmp != expected) { test_printf("%d: '%s' vs '%s' == %d; expected %d\n",