summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2023-10-12 10:41:04 -0400
committerTavian Barnes <tavianator@tavianator.com>2023-10-12 11:39:44 -0400
commit257227326fe60fe70e80433fd34d1ebcb2f9f623 (patch)
tree6723829711d91de9c565d9984a04fa858e59a37f /src
parenta029d95b5736a74879f32089514a5a6b63d6efbc (diff)
downloadbfs-257227326fe60fe70e80433fd34d1ebcb2f9f623.tar.xz
bftw: Don't force buffering for parallel dfs
Diffstat (limited to 'src')
-rw-r--r--src/bftw.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/bftw.c b/src/bftw.c
index 6eec42c..c0bff75 100644
--- a/src/bftw.c
+++ b/src/bftw.c
@@ -456,6 +456,33 @@ struct bftw_state {
struct BFTW ftwbuf;
};
+/** Check if we have to buffer files before visiting them. */
+static bool bftw_must_buffer(const struct bftw_state *state) {
+ if (state->flags & BFTW_SORT) {
+ // Have to buffer the files to sort them
+ return true;
+ }
+
+ if (state->strategy == BFTW_DFS && state->nthreads == 0) {
+ // Without buffering, we would get a not-quite-depth-first
+ // ordering:
+ //
+ // a
+ // b
+ // a/c
+ // a/c/d
+ // b/e
+ // b/e/f
+ //
+ // This is okay for iterative deepening, since the caller only
+ // sees files at the target depth. We also deem it okay for
+ // parallel searches, since the order is unpredictable anyway.
+ return true;
+ }
+
+ return false;
+}
+
/** Initialize the bftw() state. */
static int bftw_state_init(struct bftw_state *state, const struct bftw_args *args) {
state->paths = args->paths;
@@ -465,11 +492,6 @@ static int bftw_state_init(struct bftw_state *state, const struct bftw_args *arg
state->flags = args->flags;
state->strategy = args->strategy;
state->mtab = args->mtab;
-
- if ((state->flags & BFTW_SORT) || state->strategy == BFTW_DFS) {
- state->flags |= BFTW_BUFFER;
- }
-
state->error = 0;
if (args->nopenfd < 2) {
@@ -501,6 +523,9 @@ static int bftw_state_init(struct bftw_state *state, const struct bftw_args *arg
}
state->nthreads = nthreads;
+ if (bftw_must_buffer(state)) {
+ state->flags |= BFTW_BUFFER;
+ }
SLIST_INIT(&state->dir_batch);
SLIST_INIT(&state->to_open);