@matheusbsbs / matheus-bagliano / commits / 443e061a41
Fork 0

Avoid using 'lstat()' to figure out directories

If we have an up-to-date index entry for a file in that directory, we can know that the directories leading up to that file must be directories. No need to do an lstat() on the directory. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Linus Torvalds committed Jul 9, 2009 at 13:14 UTC 443e061a41bee30de34793648793ed70477ac575
1 file changed +42 -5
dir.c
+42 -5
@@ -566,18 +566,55 @@ static int in_pathspec(const char *path, int len, const struct path_simplify *si
566 return 0;
567 }
568
569 +static int get_index_dtype(const char *path, int len)
570 +{
571 + int pos;
572 + struct cache_entry *ce;
573 +
574 + ce = cache_name_exists(path, len, 0);
575 + if (ce) {
576 + if (!ce_uptodate(ce))
577 + return DT_UNKNOWN;
578 + if (S_ISGITLINK(ce->ce_mode))
579 + return DT_DIR;
580 + /*
581 + * Nobody actually cares about the
582 + * difference between DT_LNK and DT_REG
583 + */
584 + return DT_REG;
585 + }
586 +
587 + /* Try to look it up as a directory */
588 + pos = cache_name_pos(path, len);
589 + if (pos >= 0)
590 + return DT_UNKNOWN;
591 + pos = -pos-1;
592 + while (pos < active_nr) {
593 + ce = active_cache[pos++];
594 + if (strncmp(ce->name, path, len))
595 + break;
596 + if (ce->name[len] > '/')
597 + break;
598 + if (ce->name[len] < '/')
599 + continue;
600 + if (!ce_uptodate(ce))
601 + break; /* continue? */
602 + return DT_DIR;
603 + }
604 + return DT_UNKNOWN;
605 +}
606 +
607 static int get_dtype(struct dirent *de, const char *path, int len)
608 {
609 int dtype = de ? DTYPE(de) : DT_UNKNOWN;
572 - struct cache_entry *ce;
610 struct stat st;
611
612 if (dtype != DT_UNKNOWN)
613 return dtype;
577 - ce = cache_name_exists(path, len, 0);
578 - if (ce && ce_uptodate(ce))
579 - st.st_mode = ce->ce_mode;
580 - else if (lstat(path, &st))
614 + dtype = get_index_dtype(path, len);
615 + if (dtype != DT_UNKNOWN)
616 + return dtype;
617 + if (lstat(path, &st))
618 return dtype;
619 if (S_ISREG(st.st_mode))
620 return DT_REG;