@matheusbsbs / matheus-bagliano / commits / d177cab048
Fork 0

Avoid some unnecessary lstat() calls

The commit sequence used to do if (file_exists(p->path)) add_file_to_cache(p->path, 0); where both "file_exists()" and "add_file_to_cache()" needed to do a lstat() on the path to do their work. This cuts down 'lstat()' calls for the partial commit case by two for each path we know about (because we do this twice per path). Just move the lstat() to the caller instead (that's all that "file_exists()" really does), and pass the stat information down to the add_to_cache() function. This essentially makes 'add_to_index()' the core function that adds a path to the index, getting the index pointer, the pathname and the stat information as arguments. There are then shorthand helper functions that use this core function: - 'add_to_cache()' is just 'add_to_index()' with the default index - 'add_file_to_cache/index()' is the same, but does the lstat() call itself, so you can pass just the pathname if you don't already have the stat information available. So old users of the 'add_file_to_xyzzy()' are essentially left unchanged, and this just exposes the more generic helper function that can take existing stat information into account. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Linus Torvalds committed May 9, 2008 at 09:11 UTC d177cab0480f9fa172103071203fed1bff95f5c2
3 files changed +23 -14
builtin-commit.c
+4 -2
@@ -175,9 +175,11 @@ static void add_remove_files(struct path_list *list)
175 {
176 int i;
177 for (i = 0; i < list->nr; i++) {
178 + struct stat st;
179 struct path_list_item *p = &(list->items[i]);
179 - if (file_exists(p->path))
180 - add_file_to_cache(p->path, 0);
180 +
181 + if (!lstat(p->path, &st))
182 + add_to_cache(p->path, &st, 0);
183 else
184 remove_file_from_cache(p->path);
185 }
cache.h
+2
@@ -261,6 +261,7 @@ static inline void remove_name_hash(struct cache_entry *ce)
261 #define add_cache_entry(ce, option) add_index_entry(&the_index, (ce), (option))
262 #define remove_cache_entry_at(pos) remove_index_entry_at(&the_index, (pos))
263 #define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))
264 +#define add_to_cache(path, st, verbose) add_to_index(&the_index, (path), (st), (verbose))
265 #define add_file_to_cache(path, verbose) add_file_to_index(&the_index, (path), (verbose))
266 #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL)
267 #define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))
@@ -365,6 +366,7 @@ extern int add_index_entry(struct index_state *, struct cache_entry *ce, int opt
366 extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really);
367 extern int remove_index_entry_at(struct index_state *, int pos);
368 extern int remove_file_from_index(struct index_state *, const char *path);
369 +extern int add_to_index(struct index_state *, const char *path, struct stat *, int verbose);
370 extern int add_file_to_index(struct index_state *, const char *path, int verbose);
371 extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh);
372 extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
read-cache.c
+17 -12
@@ -462,21 +462,18 @@ static struct cache_entry *create_alias_ce(struct cache_entry *ce, struct cache_
462 return new;
463 }
464
465 -int add_file_to_index(struct index_state *istate, const char *path, int verbose)
465 +int add_to_index(struct index_state *istate, const char *path, struct stat *st, int verbose)
466 {
467 int size, namelen;
468 - struct stat st;
468 + mode_t st_mode = st->st_mode;
469 struct cache_entry *ce, *alias;
470 unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY;
471
472 - if (lstat(path, &st))
473 - die("%s: unable to stat (%s)", path, strerror(errno));
474 -
475 - if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode))
472 + if (!S_ISREG(st_mode) && !S_ISLNK(st_mode) && !S_ISDIR(st_mode))
473 die("%s: can only add regular files, symbolic links or git-directories", path);
474
475 namelen = strlen(path);
479 - if (S_ISDIR(st.st_mode)) {
476 + if (S_ISDIR(st_mode)) {
477 while (namelen && path[namelen-1] == '/')
478 namelen--;
479 }
@@ -484,10 +481,10 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
481 ce = xcalloc(1, size);
482 memcpy(ce->name, path, namelen);
483 ce->ce_flags = namelen;
487 - fill_stat_cache_info(ce, &st);
484 + fill_stat_cache_info(ce, st);
485
486 if (trust_executable_bit && has_symlinks)
490 - ce->ce_mode = create_ce_mode(st.st_mode);
487 + ce->ce_mode = create_ce_mode(st_mode);
488 else {
489 /* If there is an existing entry, pick the mode bits and type
490 * from it, otherwise assume unexecutable regular file.
@@ -496,18 +493,18 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
493 int pos = index_name_pos_also_unmerged(istate, path, namelen);
494
495 ent = (0 <= pos) ? istate->cache[pos] : NULL;
499 - ce->ce_mode = ce_mode_from_stat(ent, st.st_mode);
496 + ce->ce_mode = ce_mode_from_stat(ent, st_mode);
497 }
498
499 alias = index_name_exists(istate, ce->name, ce_namelen(ce), ignore_case);
503 - if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, &st, ce_option)) {
500 + if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, st, ce_option)) {
501 /* Nothing changed, really */
502 free(ce);
503 ce_mark_uptodate(alias);
504 alias->ce_flags |= CE_ADDED;
505 return 0;
506 }
510 - if (index_path(ce->sha1, path, &st, 1))
507 + if (index_path(ce->sha1, path, st, 1))
508 die("unable to index file %s", path);
509 if (ignore_case && alias && different_name(ce, alias))
510 ce = create_alias_ce(ce, alias);
@@ -519,6 +516,14 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
516 return 0;
517 }
518
519 +int add_file_to_index(struct index_state *istate, const char *path, int verbose)
520 +{
521 + struct stat st;
522 + if (lstat(path, &st))
523 + die("%s: unable to stat (%s)", path, strerror(errno));
524 + return add_to_index(istate, path, &st, verbose);
525 +}
526 +
527 struct cache_entry *make_cache_entry(unsigned int mode,
528 const unsigned char *sha1, const char *path, int stage,
529 int refresh)