wip: "full" findr
Creating direct equivilant of fd for performance testing, before reducing scope to needed features.
This commit is contained in:
28
bench.sh
28
bench.sh
@@ -38,16 +38,17 @@ echo
|
|||||||
|
|
||||||
# --- file counts ---
|
# --- file counts ---
|
||||||
echo "=== File counts ==="
|
echo "=== File counts ==="
|
||||||
printf " findr --ignored : %8d\n" "$("$FINDR" --ignored "$TARGET" 2>/dev/null | wc -l)"
|
printf " fd -a . : %8d\n" "$(fd -a . "$TARGET" 2>/dev/null | wc -l)"
|
||||||
|
printf " findr : %8d\n" "$("$FINDR" "$TARGET" 2>/dev/null | wc -l)"
|
||||||
echo
|
echo
|
||||||
printf " fd . -t f --exclude .git : %8d\n" "$(fd . -t f --exclude .git "$TARGET" 2>/dev/null | wc -l)"
|
printf " fd -a -H . : %8d\n" "$(fd -a -H . "$TARGET" 2>/dev/null | wc -l)"
|
||||||
printf " findr --no-hidden : %8d\n" "$("$FINDR" --no-hidden "$TARGET" 2>/dev/null | wc -l)"
|
printf " findr -H : %8d\n" "$("$FINDR" -H "$TARGET" 2>/dev/null | wc -l)"
|
||||||
echo
|
echo
|
||||||
printf " fd . -H -t f --exclude .git : %8d\n" "$(fd . -H -t f --exclude .git "$TARGET" 2>/dev/null | wc -l)"
|
printf " fd -a -HI . : %8d\n" "$(fd -a -HI . "$TARGET" 2>/dev/null | wc -l)"
|
||||||
printf " findr (respect) : %8d\n" "$("$FINDR" "$TARGET" 2>/dev/null | wc -l)"
|
printf " findr -HI : %8d\n" "$("$FINDR" -HI "$TARGET" 2>/dev/null | wc -l)"
|
||||||
echo
|
echo
|
||||||
printf " fd . -HI -t f --exclude .git: %8d\n" "$(fd . -HI -t f --exclude .git "$TARGET" 2>/dev/null | wc -l)"
|
printf " fd -a -E .git . : %8d\n" "$(fd -a -E .git . "$TARGET" 2>/dev/null | wc -l)"
|
||||||
printf " findr -I (all) : %8d\n" "$("$FINDR" -I "$TARGET" 2>/dev/null | wc -l)"
|
printf " findr -E .git : %8d\n" "$("$FINDR" -E .git "$TARGET" 2>/dev/null | wc -l)"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# --- benchmarks ---
|
# --- benchmarks ---
|
||||||
@@ -57,13 +58,14 @@ hyperfine \
|
|||||||
--warmup 2 \
|
--warmup 2 \
|
||||||
--runs 5 \
|
--runs 5 \
|
||||||
--export-markdown "$RESULTS_FILE" \
|
--export-markdown "$RESULTS_FILE" \
|
||||||
"$FINDR --ignored \"$TARGET\" > /dev/null" \
|
"fd -a . \"$TARGET\" > /dev/null" \
|
||||||
"fd . -t f --exclude .git \"$TARGET\" > /dev/null" \
|
|
||||||
"$FINDR --no-hidden \"$TARGET\" > /dev/null" \
|
|
||||||
"fd . -H -t f --exclude .git \"$TARGET\" > /dev/null" \
|
|
||||||
"$FINDR \"$TARGET\" > /dev/null" \
|
"$FINDR \"$TARGET\" > /dev/null" \
|
||||||
"fd . -HI -t f --exclude .git \"$TARGET\" > /dev/null" \
|
"fd -a -H . \"$TARGET\" > /dev/null" \
|
||||||
"$FINDR -I \"$TARGET\" > /dev/null"
|
"$FINDR -H \"$TARGET\" > /dev/null" \
|
||||||
|
"fd -a -HI . \"$TARGET\" > /dev/null" \
|
||||||
|
"$FINDR -HI \"$TARGET\" > /dev/null" \
|
||||||
|
"fd -a -E .git . \"$TARGET\" > /dev/null" \
|
||||||
|
"$FINDR -E .git \"$TARGET\" > /dev/null"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
echo "=== Results written to $RESULTS_FILE ==="
|
echo "=== Results written to $RESULTS_FILE ==="
|
||||||
|
|||||||
19
findr.odin
19
findr.odin
@@ -8,7 +8,7 @@ main :: proc() {
|
|||||||
args := os.args
|
args := os.args
|
||||||
|
|
||||||
opts: WalkOptions
|
opts: WalkOptions
|
||||||
opts.include_hidden = true
|
opts.include_hidden = false
|
||||||
opts.ignore_mode = .Respected
|
opts.ignore_mode = .Respected
|
||||||
|
|
||||||
excludes := make([dynamic]string)
|
excludes := make([dynamic]string)
|
||||||
@@ -22,12 +22,8 @@ main :: proc() {
|
|||||||
for i < len(args) {
|
for i < len(args) {
|
||||||
arg := args[i]
|
arg := args[i]
|
||||||
switch {
|
switch {
|
||||||
case arg == "-I":
|
|
||||||
opts.ignore_mode = .All
|
|
||||||
case arg == "--ignored":
|
case arg == "--ignored":
|
||||||
opts.ignore_mode = .Ignored
|
opts.ignore_mode = .Ignored
|
||||||
case arg == "--no-hidden":
|
|
||||||
opts.include_hidden = false
|
|
||||||
case arg == "-E":
|
case arg == "-E":
|
||||||
i += 1
|
i += 1
|
||||||
if i < len(args) {
|
if i < len(args) {
|
||||||
@@ -35,8 +31,17 @@ main :: proc() {
|
|||||||
}
|
}
|
||||||
case strings.has_prefix(arg, "-E"):
|
case strings.has_prefix(arg, "-E"):
|
||||||
append(&excludes, arg[2:])
|
append(&excludes, arg[2:])
|
||||||
case len(arg) > 0 && arg[0] == '-':
|
case len(arg) > 1 && arg[0] == '-':
|
||||||
// unknown flag, skip
|
for c, j in arg[1:] {
|
||||||
|
switch c {
|
||||||
|
case 'H':
|
||||||
|
opts.include_hidden = true
|
||||||
|
case 'I':
|
||||||
|
opts.ignore_mode = .All
|
||||||
|
case 'a':
|
||||||
|
// no-op: accepted for fd compatibility
|
||||||
|
}
|
||||||
|
}
|
||||||
case:
|
case:
|
||||||
if pattern == "" {
|
if pattern == "" {
|
||||||
pattern = arg
|
pattern = arg
|
||||||
|
|||||||
@@ -63,7 +63,9 @@ test_dir_only_pattern :: proc(t: ^testing.T) {
|
|||||||
create_dir(env, "repo/ignored_dir")
|
create_dir(env, "repo/ignored_dir")
|
||||||
create_file(env, "repo/.gitignore", "ignored_dir/\n")
|
create_file(env, "repo/.gitignore", "ignored_dir/\n")
|
||||||
|
|
||||||
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .Ignored}, {})
|
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .Ignored}, {
|
||||||
|
"repo/ignored_dir/",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@(test)
|
@(test)
|
||||||
@@ -158,7 +160,7 @@ test_nested_gitignore_respected_mode :: proc(t: ^testing.T) {
|
|||||||
// important.log: un-ignored by nested negation → emitted
|
// important.log: un-ignored by nested negation → emitted
|
||||||
// debug.log: ignored by root → skipped
|
// debug.log: ignored by root → skipped
|
||||||
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .Respected}, {
|
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .Respected}, {
|
||||||
"repo/.gitignore", "repo/sub/.gitignore", "repo/sub/important.log",
|
"repo/", "repo/.gitignore", "repo/sub/", "repo/sub/.gitignore", "repo/sub/important.log",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,7 +255,7 @@ test_all_mode_emits_all_files :: proc(t: ^testing.T) {
|
|||||||
create_file(env, "repo/normal.txt")
|
create_file(env, "repo/normal.txt")
|
||||||
|
|
||||||
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .All}, {
|
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .All}, {
|
||||||
"repo/.env", "repo/.gitignore", "repo/secrets.env", "repo/normal.txt",
|
"repo/", "repo/.env", "repo/.gitignore", "repo/secrets.env", "repo/normal.txt",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +270,7 @@ test_all_mode_descends_everywhere :: proc(t: ^testing.T) {
|
|||||||
create_file(env, "repo/build/output.txt")
|
create_file(env, "repo/build/output.txt")
|
||||||
|
|
||||||
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .All}, {
|
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .All}, {
|
||||||
"repo/.gitignore", "repo/build/output.txt",
|
"repo/", "repo/.gitignore", "repo/build/", "repo/build/output.txt",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +290,7 @@ test_respected_mode_skips_gitignored :: proc(t: ^testing.T) {
|
|||||||
create_file(env, "repo/normal.txt")
|
create_file(env, "repo/normal.txt")
|
||||||
|
|
||||||
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .Respected}, {
|
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .Respected}, {
|
||||||
"repo/.gitignore", "repo/normal.txt",
|
"repo/", "repo/.gitignore", "repo/normal.txt",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,7 +306,7 @@ test_respected_mode_prunes_ignored_dirs :: proc(t: ^testing.T) {
|
|||||||
create_file(env, "repo/main.txt")
|
create_file(env, "repo/main.txt")
|
||||||
|
|
||||||
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .Respected}, {
|
assert_output(t, env, nil, {include_hidden = true, ignore_mode = .Respected}, {
|
||||||
"repo/.gitignore", "repo/main.txt",
|
"repo/", "repo/.gitignore", "repo/main.txt",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
walker.odin
22
walker.odin
@@ -230,6 +230,12 @@ process_dir :: proc(pool: ^WalkerPool, item: WorkItem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if is_dir {
|
if is_dir {
|
||||||
|
if should_emit && matches_pattern(pool, entry.name) {
|
||||||
|
dir_path_out := join_path_dir(dir_path, entry.name)
|
||||||
|
sync.mutex_lock(&pool.results_mutex)
|
||||||
|
append(pool.results, dir_path_out)
|
||||||
|
sync.mutex_unlock(&pool.results_mutex)
|
||||||
|
}
|
||||||
if !ignored {
|
if !ignored {
|
||||||
child_rel, _ := strings.clone(entry_rel)
|
child_rel, _ := strings.clone(entry_rel)
|
||||||
child_path := join_path(dir_path, entry.name)
|
child_path := join_path(dir_path, entry.name)
|
||||||
@@ -367,3 +373,19 @@ join_path :: proc(parent, child: string) -> string {
|
|||||||
result, _ := strings.clone(s)
|
result, _ := strings.clone(s)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
join_path_dir :: proc(parent, child: string) -> string {
|
||||||
|
b: strings.Builder
|
||||||
|
strings.builder_init(&b)
|
||||||
|
defer strings.builder_destroy(&b)
|
||||||
|
|
||||||
|
fmt.sbprintf(&b, "%s", parent)
|
||||||
|
if len(parent) == 0 || parent[len(parent) - 1] != '/' {
|
||||||
|
fmt.sbprintf(&b, "/")
|
||||||
|
}
|
||||||
|
fmt.sbprintf(&b, "%s/", child)
|
||||||
|
|
||||||
|
s := strings.to_string(b)
|
||||||
|
result, _ := strings.clone(s)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user