find: do not recurse into directories with depth == --maxdepth

This may avoid many, many unnecessary stat() calls

function                                             old     new   delta
fileAction                                           718     758     +40

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2009-09-27 01:51:47 +02:00
parent 48f116198d
commit 6c750f1518

View File

@ -65,7 +65,7 @@
IF_FEATURE_FIND_XDEV(static dev_t *xdev_dev;) IF_FEATURE_FIND_XDEV(static dev_t *xdev_dev;)
IF_FEATURE_FIND_XDEV(static int xdev_count;) IF_FEATURE_FIND_XDEV(static int xdev_count;)
typedef int (*action_fp)(const char *fileName, struct stat *statbuf, void *) FAST_FUNC; typedef int (*action_fp)(const char *fileName, const struct stat *statbuf, void *) FAST_FUNC;
typedef struct { typedef struct {
action_fp f; action_fp f;
@ -77,7 +77,7 @@ typedef struct {
#define ACTS(name, ...) typedef struct { action a; __VA_ARGS__ } action_##name; #define ACTS(name, ...) typedef struct { action a; __VA_ARGS__ } action_##name;
#define ACTF(name) \ #define ACTF(name) \
static int FAST_FUNC func_##name(const char *fileName UNUSED_PARAM, \ static int FAST_FUNC func_##name(const char *fileName UNUSED_PARAM, \
struct stat *statbuf UNUSED_PARAM, \ const struct stat *statbuf UNUSED_PARAM, \
action_##name* ap UNUSED_PARAM) action_##name* ap UNUSED_PARAM)
ACTS(print) ACTS(print)
@ -139,7 +139,7 @@ static char* subst(const char *src, unsigned count, const char* filename)
* bit 0=1: matched successfully (TRUE) * bit 0=1: matched successfully (TRUE)
*/ */
static int exec_actions(action ***appp, const char *fileName, struct stat *statbuf) static int exec_actions(action ***appp, const char *fileName, const struct stat *statbuf)
{ {
int cur_group; int cur_group;
int cur_action; int cur_action;
@ -392,26 +392,34 @@ static int FAST_FUNC fileAction(const char *fileName,
if (depth < minmaxdepth[0]) return TRUE; if (depth < minmaxdepth[0]) return TRUE;
if (depth > minmaxdepth[1]) return SKIP; if (depth > minmaxdepth[1]) return SKIP;
#undef minmaxdepth
#endif #endif
#if ENABLE_FEATURE_FIND_XDEV #if ENABLE_FEATURE_FIND_XDEV
if (S_ISDIR(statbuf->st_mode) && xdev_count) { if (S_ISDIR(statbuf->st_mode)) {
for (i = 0; i < xdev_count; i++) { if (xdev_count) {
if (xdev_dev[i] == statbuf->st_dev) for (i = 0; i < xdev_count; i++) {
break; if (xdev_dev[i] == statbuf->st_dev)
} goto found;
if (i == xdev_count) }
return SKIP; return SKIP;
found: ;
}
} }
#endif #endif
i = exec_actions(actions, fileName, statbuf); i = exec_actions(actions, fileName, statbuf);
/* Had no explicit -print[0] or -exec? then print */ /* Had no explicit -print[0] or -exec? then print */
if ((i & TRUE) && need_print) if ((i & TRUE) && need_print)
puts(fileName); puts(fileName);
#if ENABLE_FEATURE_FIND_MAXDEPTH
if (S_ISDIR(statbuf->st_mode))
if (depth == minmaxdepth[1])
return SKIP;
#endif
/* Cannot return 0: our caller, recursive_action(), /* Cannot return 0: our caller, recursive_action(),
* will perror() and skip dirs (if called on dir) */ * will perror() and skip dirs (if called on dir) */
return (i & SKIP) ? SKIP : TRUE; return (i & SKIP) ? SKIP : TRUE;
#undef minmaxdepth
} }