From 5d545fc676564d5592eff0f7c91749ea2cc5102d Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Fri, 15 Mar 2024 08:29:30 +0100 Subject: [PATCH 01/14] specify what each crate does --- Cargo.toml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5dfc40d..55b7613 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,13 +17,13 @@ license = false eula = false [dependencies] -clap = { version = "4.5.2", features = ["derive", "color"] } -rayon = "1.9.0" -mimalloc = { version = "0.1.39", default-features = false } -colored = "2.1.0" -memchr = "2.7.1" -crossbeam-channel = "0.5.12" -thin_str = "0.1.0" +clap = { version = "4.5.2", features = ["derive", "color"] } # Command line argument parser +colored = "2.1.0" # Colored output +rayon = "1.9.0" # Parallelism library +crossbeam-channel = "0.5.12" # Faster channels (mpmc) +mimalloc = { version = "0.1.39", default-features = false } # Faster allocator +thin_str = "0.1.0" # Thinner string (only 8 bytes) +memchr = "2.7.1" # Small substring search optimization [target.'cfg(target_os = "linux")'.dependencies] rustix = { version = "0.38.31", default-features = false, features = ["fs", "alloc"] } From c8253774c319b7a041ccac7c40ec91b68785cd74 Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Fri, 15 Mar 2024 08:37:09 +0100 Subject: [PATCH 02/14] doc(README): Change "Why I made it" to "Motivation" and explain it better; Add precompiled binary method to "Installation" --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d9952ed..ba5b087 100644 --- a/README.md +++ b/README.md @@ -136,12 +136,22 @@ If the --hidden flag is **not** set, hidden files/directories will be skipped, a hunt -s -e SomeFile | xargs rm -r -## Why I made it? -I found I used the `find` command just to search one file, so I wanted a simpler and faster option. +## Motivation +Normally when I search for a file, I don't know the exact subdirectory where it is, so I end up searching in the whole $HOME directory. + +Using the `find` command for this ended up being very slow, as it took a lot of time to traverse all the directories, and the output was also hard to read. + +`locate` was faster, but it didn't always find the file I was looking for, as it only searches in its database which isn't updated in real time. + +Seeing how `find` did not perform any parallelism at all, I decided to make a multithreaded version of it, and that's how Hunt was born. Hunt is multithreaded, so it's a lot faster than `find`, and more reliable than `locate` (recent files cannot be found with it). ## Installation +### Precompiled binaries +Download the latest binary from [releases](https://github.com/lyonsyonii/hunt-rs/releases). + +### Compile from source First check that you have [Rust](https://www.rust-lang.org/) installed, then run cargo install hunt From 42febe07d1373e2a3391a14556f32add6922d015 Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Fri, 15 Mar 2024 23:12:30 +0100 Subject: [PATCH 03/14] small changes --- src/search.rs | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/search.rs b/src/search.rs index b14aa4b..74db1d2 100644 --- a/src/search.rs +++ b/src/search.rs @@ -43,10 +43,11 @@ impl Search { // Search in directories rayon::scope(move |s| { - s.spawn(move |_| { - dirs.par_bridge() - .for_each(|dir| search_dir(dir.as_ref(), self, sender.clone())) - }); + for dir in dirs { + let sender = sender.clone(); + s.spawn(move |_| search_dir(dir.as_ref(), self, sender)); + } + drop(sender); receive_paths(receiver, self) }) } @@ -60,7 +61,7 @@ fn search_dir(path: impl AsRef, search: &Search, sender: Sender) { } return; }; - + rayon::scope(|s| { for entry in read.flatten() { let Some((result, is_dir)) = is_result(entry, search) else { @@ -82,13 +83,6 @@ fn is_result( ) -> Option<(Option, Option>)> { // Get entry name let path = entry.path(); - let fname = file_name(&path).unwrap(); - let fname = fname.to_string_lossy(); - let sname: std::borrow::Cow = if search.case_sensitive { - fname.as_ref().into() - } else { - fname.to_ascii_lowercase().into() - }; if search.explicit_ignore.binary_search(&path).is_ok() { return None; @@ -124,10 +118,18 @@ fn is_result( FileType::All => true, }; - let starts = search.starts.is_empty() || sname.starts_with(&search.starts); - let ends = search.ends.is_empty() || sname.ends_with(&search.ends); + let fname = file_name(&path).unwrap(); + let fname = fname.to_string_lossy(); + let sname: std::borrow::Cow = if search.case_sensitive { + fname.as_ref().into() + } else { + fname.to_ascii_lowercase().into() + }; + + let starts = || search.starts.is_empty() || sname.starts_with(&search.starts); + let ends = || search.ends.is_empty() || sname.ends_with(&search.ends); - if starts && ends && ftype { + if ftype && starts() && ends() { // If file name is equal to search name, write it to the "Exact" buffer if sname == search.name { return Some(( From d12198929a2f29ab09655ffced9905d58653fe80 Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Sat, 16 Mar 2024 01:10:11 +0100 Subject: [PATCH 04/14] removed perf annotations, now using the 'perf' command --- .gitignore | 3 ++- benchmarks/run | 5 +++++ src/main.rs | 41 ++--------------------------------------- src/print.rs | 31 ++++++++++++++----------------- src/search.rs | 6 ++---- 5 files changed, 25 insertions(+), 61 deletions(-) diff --git a/.gitignore b/.gitignore index cd8df14..1ce86e7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,8 @@ flamegraph.svg perf.data perf.data.old -search_db.rs +callgrind.out.* +gecko_profile.json main_*.rs.bak benchmarks/* !benchmarks/run \ No newline at end of file diff --git a/benchmarks/run b/benchmarks/run index 2921f44..b695245 100644 --- a/benchmarks/run +++ b/benchmarks/run @@ -4,6 +4,11 @@ cmd default() { echo "$doc" } +cmd profile() { + cargo build --profile profiling + perf record -F99 --call-graph dwarf ../target/profiling/hunt --hidden $HOME > /dev/null && perf script report gecko +} + sub bench { const build = cargo build --release const hunt = ../target/release/hunt diff --git a/src/main.rs b/src/main.rs index 2460ef2..82fcbb5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,48 +7,11 @@ mod structs; #[global_allocator] static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; -#[cfg(feature = "perf")] -pub(crate) struct Perf { - time: std::time::Duration, - ctx: &'static str, -} - -#[cfg(feature = "perf")] -impl Drop for Perf { - fn drop(&mut self) { - eprintln!("{}: {:?}", self.ctx, self.time); - } -} - -#[macro_export] -macro_rules! perf { - (ctx = $ctx:expr; $($code:tt)* ) => { - #[cfg(feature = "perf")] - let _start = std::time::Instant::now(); - $($code)* - #[cfg(feature = "perf")] - let _end = std::time::Instant::now(); - #[cfg(feature = "perf")] - $crate::Perf { - time: _end - _start, - ctx: $ctx - }; - }; - (disable; ctx = $ctx:expr; $($code:tt)* ) => { - $($code)* - }; - ($($code:tt)* ) => { - $crate::perf!(ctx = stringify!( $($code)* ); $($code)*) - }; -} - fn main() -> std::io::Result<()> { let search = structs::Cli::run(); - perf! { - ctx = "search"; - let buffers = search.search(); - } + let buffers = search.search(); search.print_results(buffers)?; + Ok(()) } diff --git a/src/print.rs b/src/print.rs index 5c116a1..3ab7aa5 100644 --- a/src/print.rs +++ b/src/print.rs @@ -18,25 +18,22 @@ impl Search { } return Ok(()); } - crate::perf! { - ctx = "sort"; - rayon::join(|| co.par_sort(), || ex.par_sort()); + + rayon::join(|| co.par_sort(), || ex.par_sort()); + + if self.output == Output::Normal { + writeln!(stdout, "Contains:")?; } - crate::perf! { - ctx = "print"; - if self.output == Output::Normal { - writeln!(stdout, "Contains:")?; - } - for path in co.into_iter() { - writeln!(stdout, "{path}")?; - } - if self.output == Output::Normal { - writeln!(stdout, "\nExact:")?; - } - for path in ex.into_iter() { - writeln!(stdout, "{path}")?; - } + for path in co.into_iter() { + writeln!(stdout, "{path}")?; + } + if self.output == Output::Normal { + writeln!(stdout, "\nExact:")?; + } + for path in ex.into_iter() { + writeln!(stdout, "{path}")?; } + Ok(()) } } diff --git a/src/search.rs b/src/search.rs index 74db1d2..73e3e2c 100644 --- a/src/search.rs +++ b/src/search.rs @@ -1,8 +1,6 @@ use crate::{ - searchresult::SearchResult, - structs::{Buffers, FileType, Output, Search}, + searchresult::SearchResult, structs::{Buffers, FileType, Output, Search} }; -use rayon::iter::{ParallelBridge, ParallelIterator}; use std::path::Path; type Receiver = crossbeam_channel::Receiver; @@ -155,7 +153,7 @@ fn is_result( fn receive_paths(receiver: Receiver, search: &Search) -> Buffers { use std::io::Write; - + // -f if search.first { let Ok(path) = receiver.recv() else { From 0f50adf89b8cbc1f0c210189c4108d923bf20102 Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Thu, 16 May 2024 23:15:06 +0200 Subject: [PATCH 05/14] add profi annotations for performance measures. Will not affect final executable --- Cargo.lock | 259 ++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 5 +- src/main.rs | 1 + src/print.rs | 7 +- src/search.rs | 8 +- src/structs.rs | 2 + 6 files changed, 277 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 048911d..978b33e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,18 +50,36 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + [[package]] name = "bitflags" version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +[[package]] +name = "bumpalo" +version = "3.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" + [[package]] name = "cc" version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "clap" version = "4.5.2" @@ -93,7 +111,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.52", ] [[package]] @@ -118,6 +136,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "comfy-table" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" +dependencies = [ + "strum", + "strum_macros", + "unicode-width", +] + [[package]] name = "crossbeam-channel" version = "0.5.12" @@ -152,12 +181,28 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "either" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.8" @@ -168,6 +213,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + [[package]] name = "heck" version = "0.4.1" @@ -183,12 +234,32 @@ dependencies = [ "crossbeam-channel", "memchr", "mimalloc", + "profi", "rayon", "rustix", "thin_str", "winapi-util", ] +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -217,6 +288,12 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + [[package]] name = "memchr" version = "2.7.1" @@ -232,6 +309,31 @@ dependencies = [ "libmimalloc-sys", ] +[[package]] +name = "minstant" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb9b5c752f145ac5046bccc3c4f62892e3c950c1d1eab80c5949cd68a2078db" +dependencies = [ + "ctor", + "web-time", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.78" @@ -241,6 +343,29 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profi" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459e6eeefd402b40e5b412c466000bd2bedb30452f8baccb5a658abcea660a4c" +dependencies = [ + "beef", + "comfy-table", + "indexmap", + "minstant", + "profi-attributes", + "rayon", +] + +[[package]] +name = "profi-attributes" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5de21eb23fff8887286dceb38007da2692d6ec8b330dcb23ddeeb0c84838274" +dependencies = [ + "proc-macro-crate", +] + [[package]] name = "quote" version = "1.0.35" @@ -283,12 +408,48 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "strsim" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.52", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.52" @@ -306,18 +467,105 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be9d479371ac7a8e00f077b47e26db313447fa59ca276ad73c4716975f3895d4" +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + [[package]] name = "utf8parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.52", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -480,3 +728,12 @@ name = "windows_x86_64_msvc" version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] diff --git a/Cargo.toml b/Cargo.toml index 55b7613..69d1122 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,8 @@ rayon = "1.9.0" # Parallelism li crossbeam-channel = "0.5.12" # Faster channels (mpmc) mimalloc = { version = "0.1.39", default-features = false } # Faster allocator thin_str = "0.1.0" # Thinner string (only 8 bytes) -memchr = "2.7.1" # Small substring search optimization +memchr = "2.7.1" # Small substring search optimization +profi = { version = "*", default-features = false, features = ["rayon", "attributes"]}# Multithreaded fine-grained profiler [target.'cfg(target_os = "linux")'.dependencies] rustix = { version = "0.38.31", default-features = false, features = ["fs", "alloc"] } @@ -49,7 +50,7 @@ inherits = "release" lto = "thin" [features] -perf = [] # Enable performance measurements +perf = ["profi/enable"] # Enable performance measurements # Config for 'cargo dist' [workspace.metadata.dist] diff --git a/src/main.rs b/src/main.rs index 82fcbb5..808ae76 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ mod structs; static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; fn main() -> std::io::Result<()> { + profi::print_on_exit!(stderr); let search = structs::Cli::run(); let buffers = search.search(); diff --git a/src/print.rs b/src/print.rs index 3ab7aa5..9d0b339 100644 --- a/src/print.rs +++ b/src/print.rs @@ -4,6 +4,8 @@ use std::io::Write; impl Search { pub fn print_results(self, buffers: Buffers) -> std::io::Result<()> { + profi::prof!(print_results); + if self.output == Output::SuperSimple { return Ok(()); } @@ -19,7 +21,10 @@ impl Search { return Ok(()); } - rayon::join(|| co.par_sort(), || ex.par_sort()); + { + profi::prof!(sort); + rayon::join(|| co.par_sort(), || ex.par_sort()); + } if self.output == Output::Normal { writeln!(stdout, "Contains:")?; diff --git a/src/search.rs b/src/search.rs index 73e3e2c..5effff6 100644 --- a/src/search.rs +++ b/src/search.rs @@ -7,6 +7,7 @@ type Receiver = crossbeam_channel::Receiver; type Sender = crossbeam_channel::Sender; impl Search { + #[profi::profile] pub fn search(&self) -> Buffers { let (sender, receiver) = crossbeam_channel::bounded(8); @@ -52,6 +53,7 @@ impl Search { } fn search_dir(path: impl AsRef, search: &Search, sender: Sender) { + profi::prof!(search_dir); let path = path.as_ref(); let Ok(read) = std::fs::read_dir(path) else { if search.verbose { @@ -61,7 +63,9 @@ fn search_dir(path: impl AsRef, search: &Search, sender: Sender) { }; rayon::scope(|s| { + profi::prof!(inspect_entries); for entry in read.flatten() { + profi::prof!(inspect_entry); let Some((result, is_dir)) = is_result(entry, search) else { continue; }; @@ -72,13 +76,15 @@ fn search_dir(path: impl AsRef, search: &Search, sender: Sender) { s.spawn(|_| search_dir(path, search, sender.clone())); } } - }) + }); } fn is_result( entry: std::fs::DirEntry, search: &Search, ) -> Option<(Option, Option>)> { + profi::prof!(); + // Get entry name let path = entry.path(); diff --git a/src/structs.rs b/src/structs.rs index c153aba..93e1037 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -240,6 +240,8 @@ pub struct Cli { impl Cli { pub fn run() -> Search { + profi::prof!(cli); + let cli = Self::parse(); let mut search_in_dirs = cli.search_in_dirs; From 4dbe18217a720c6e419ade2370a21b191ce31fbe Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Fri, 17 May 2024 00:13:18 +0200 Subject: [PATCH 06/14] Add flake.nix --- .envrc | 1 + .gitignore | 2 + Cargo.toml | 2 +- flake.lock | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 34 ++++++++++++++++ 5 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 .envrc create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..8392d15 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake \ No newline at end of file diff --git a/.gitignore b/.gitignore index 1ce86e7..0df22f3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ callgrind.out.* gecko_profile.json main_*.rs.bak benchmarks/* +.direnv/ + !benchmarks/run \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 69d1122..9f9c304 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ crossbeam-channel = "0.5.12" # Faster channel mimalloc = { version = "0.1.39", default-features = false } # Faster allocator thin_str = "0.1.0" # Thinner string (only 8 bytes) memchr = "2.7.1" # Small substring search optimization -profi = { version = "*", default-features = false, features = ["rayon", "attributes"]}# Multithreaded fine-grained profiler +profi = { version = "*", default-features = false, features = ["rayon", "attributes"]} # Multithreaded fine-grained profiler [target.'cfg(target_os = "linux")'.dependencies] rustix = { version = "0.38.31", default-features = false, features = ["fs", "alloc"] } diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..1cf1c89 --- /dev/null +++ b/flake.lock @@ -0,0 +1,114 @@ +{ + "nodes": { + "fenix": { + "inputs": { + "nixpkgs": "nixpkgs", + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1715754333, + "narHash": "sha256-u3B+RvDD/kPxMS0Dkm+x+BlzfCqghT3kdev+1UYKvis=", + "owner": "nix-community", + "repo": "fenix", + "rev": "795a549e443c9690a74a042408600f13091e8b51", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1715534503, + "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2057814051972fa1453ddfb0d98badbea9b83c06", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1715774670, + "narHash": "sha256-iJYnKMtLi5u6hZhJm94cRNSDG5Rz6ZzIkGbhPFtDRm0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b3fcfcfabd01b947a1e4f36622bbffa3985bdac6", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "fenix": "fenix", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs_2" + } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1715714902, + "narHash": "sha256-JnvpKHfDip0xq+ThdXFnNkYsV0Z0Q7ukFuW+W30vGhw=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "c0732c9f0f91bdc31d8da320be16d1db06c848d8", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..969500e --- /dev/null +++ b/flake.nix @@ -0,0 +1,34 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + fenix.url = "github:nix-community/fenix"; + flake-utils.url = "github:numtide/flake-utils"; + }; + outputs = { self, nixpkgs, flake-utils, ... }@inputs: flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ inputs.fenix.overlays.default ]; + }; + in + { + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ + sccache + lld + mold + rust-analyzer-nightly + + fenix.complete.rustc + fenix.complete.cargo + fenix.complete.clippy + fenix.complete.rustfmt + fenix.complete.miri + fenix.complete.rust-src + fenix.complete.rustc-codegen-cranelift-preview + fenix.complete.llvm-tools-preview + ]; + RUST_SRC_PATH = "${pkgs.fenix.complete.rust-src}/lib/rustlib/src/rust/library"; + }; + }); +} \ No newline at end of file From 0290f9a90ede934e3d2feefe9741bbc64380143f Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Fri, 17 May 2024 00:15:05 +0200 Subject: [PATCH 07/14] feat: remove "hardcoded_ignore", as it affected performance for a very small subset of directories; use memchr for improved substring search; --- Cargo.toml | 2 +- src/print.rs | 9 +++++--- src/search.rs | 58 +++++++++++++++++++++++++++++++++----------------- src/structs.rs | 14 ++++++++---- 4 files changed, 55 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9f9c304..30008fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ rayon = "1.9.0" # Parallelism li crossbeam-channel = "0.5.12" # Faster channels (mpmc) mimalloc = { version = "0.1.39", default-features = false } # Faster allocator thin_str = "0.1.0" # Thinner string (only 8 bytes) -memchr = "2.7.1" # Small substring search optimization +memchr = { version = "2.7.1", features = ["std", "alloc"] } # Small substring search optimization profi = { version = "*", default-features = false, features = ["rayon", "attributes"]} # Multithreaded fine-grained profiler [target.'cfg(target_os = "linux")'.dependencies] diff --git a/src/print.rs b/src/print.rs index 9d0b339..06c3e3e 100644 --- a/src/print.rs +++ b/src/print.rs @@ -3,6 +3,7 @@ use rayon::prelude::ParallelSliceMut; use std::io::Write; impl Search { + #[profi::profile] pub fn print_results(self, buffers: Buffers) -> std::io::Result<()> { profi::prof!(print_results); @@ -20,12 +21,12 @@ impl Search { } return Ok(()); } - + { profi::prof!(sort); rayon::join(|| co.par_sort(), || ex.par_sort()); } - + if self.output == Output::Normal { writeln!(stdout, "Contains:")?; } @@ -38,11 +39,12 @@ impl Search { for path in ex.into_iter() { writeln!(stdout, "{path}")?; } - + Ok(()) } } +#[profi::profile] pub fn print_with_highlight( stdout: &mut impl std::io::Write, fname: &str, @@ -93,6 +95,7 @@ pub fn print_with_highlight( ) } +#[profi::profile] pub fn format_with_highlight( fname: &str, sname: &str, diff --git a/src/search.rs b/src/search.rs index 5effff6..08c6f3c 100644 --- a/src/search.rs +++ b/src/search.rs @@ -1,5 +1,6 @@ use crate::{ - searchresult::SearchResult, structs::{Buffers, FileType, Output, Search} + searchresult::SearchResult, + structs::{Buffers, FileType, Output, Search}, }; use std::path::Path; @@ -52,20 +53,21 @@ impl Search { } } +#[profi::profile] fn search_dir(path: impl AsRef, search: &Search, sender: Sender) { - profi::prof!(search_dir); let path = path.as_ref(); + let Ok(read) = std::fs::read_dir(path) else { if search.verbose { eprintln!("Could not read {:?}", path); } return; }; - + rayon::scope(|s| { - profi::prof!(inspect_entries); + profi::prof!("search_dir::inspect_entries"); for entry in read.flatten() { - profi::prof!(inspect_entry); + profi::prof!("search_dir::inspect_entry"); let Some((result, is_dir)) = is_result(entry, search) else { continue; }; @@ -79,25 +81,27 @@ fn search_dir(path: impl AsRef, search: &Search, sender: Sender) { }); } +#[profi::profile] fn is_result( entry: std::fs::DirEntry, search: &Search, ) -> Option<(Option, Option>)> { - profi::prof!(); - // Get entry name let path = entry.path(); - - if search.explicit_ignore.binary_search(&path).is_ok() { - return None; + + { + profi::prof!("is_result::explicit_ignore"); + if search.explicit_ignore.binary_search(&path).is_ok() { + return None; + } } - let hardcoded = || { +/* let hardcoded = || { + profi::prof!("is_result::hardcoded_ignore"); search .hardcoded_ignore - .binary_search_by(|p| std::path::Path::new(p).cmp(&path)) - .is_ok() - }; + .contains(unsafe { std::mem::transmute::<&Path, &str>(path.as_path()) }) + }; */ let is_hidden = || { #[cfg(unix)] @@ -110,7 +114,7 @@ fn is_result( } }; - if !search.hidden && (is_hidden() || hardcoded()) { + if !search.hidden && (is_hidden() /* || hardcoded() */) { return None; } @@ -130,19 +134,33 @@ fn is_result( fname.to_ascii_lowercase().into() }; - let starts = || search.starts.is_empty() || sname.starts_with(&search.starts); - let ends = || search.ends.is_empty() || sname.ends_with(&search.ends); + let starts = || { + profi::prof!("is_result::starts_with"); + search.starts.is_empty() || sname.starts_with(&search.starts) + }; + let ends = || { + profi::prof!("is_result::ends_with"); + search.ends.is_empty() || sname.ends_with(&search.ends) + }; if ftype && starts() && ends() { + let (equals, contains) = { + profi::prof!("is_result::contains"); + if search.finder.find(sname.as_bytes()).is_none() { + (false, false) + } else { + (sname.len() == search.name.len(), true) + } + }; // If file name is equal to search name, write it to the "Exact" buffer - if sname == search.name { + if equals { return Some(( Some(SearchResult::exact(path.to_string_lossy().into_owned())), is_dir.then_some(path.into_boxed_path()), )); } // If file name contains the search name, write it to the "Contains" buffer - else if !search.exact && sname.contains(&search.name) { + else if !search.exact && contains { let s = if search.output == Output::Normal { crate::print::format_with_highlight(&fname, &sname, &path, search) } else { @@ -159,7 +177,7 @@ fn is_result( fn receive_paths(receiver: Receiver, search: &Search) -> Buffers { use std::io::Write; - + // -f if search.first { let Ok(path) = receiver.recv() else { diff --git a/src/structs.rs b/src/structs.rs index 93e1037..49d6758 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -38,10 +38,13 @@ pub struct Search { pub ftype: FileType, /// Directories the user has stated to ignore. pub explicit_ignore: Vec, - /// Directories hard-coded to be ignored. - pub hardcoded_ignore: [&'static str; 19], + // /// Directories hard-coded to be ignored. + // pub hardcoded_ignore: phf::Set<&'static str>, /// Directories specified by the user to be searched in. pub dirs: Vec, + + /// Memchr Finder + pub finder: memchr::memmem::Finder<'static> } impl Search { @@ -67,6 +70,7 @@ impl Search { 1 => Output::Simple, _ => Output::SuperSimple, }; + let finder = memchr::memmem::Finder::new(name.as_bytes()).into_owned(); Search { first, @@ -82,7 +86,7 @@ impl Search { ends, ftype, explicit_ignore, - hardcoded_ignore: sorted([ +/* hardcoded_ignore: phf::phf_set! { "/proc", "/root", "/boot", @@ -102,8 +106,10 @@ impl Search { "/etc/pacman.d", "/etc/sudoers.d", "/etc/audit", - ]), + }, */ dirs: search_in_dirs, + + finder } } } From f30a7000ac8885be8890d7b8f6030505f2f951ec Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Fri, 17 May 2024 00:44:52 +0200 Subject: [PATCH 08/14] adding more profi measurements --- src/main.rs | 2 +- src/search.rs | 74 ++++++++++++++++++++++++++++++++++++-------------- src/structs.rs | 10 +++---- 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/src/main.rs b/src/main.rs index 808ae76..d1db19b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; fn main() -> std::io::Result<()> { profi::print_on_exit!(stderr); let search = structs::Cli::run(); - + let buffers = search.search(); search.print_results(buffers)?; diff --git a/src/search.rs b/src/search.rs index 08c6f3c..7b37cef 100644 --- a/src/search.rs +++ b/src/search.rs @@ -57,11 +57,15 @@ impl Search { fn search_dir(path: impl AsRef, search: &Search, sender: Sender) { let path = path.as_ref(); - let Ok(read) = std::fs::read_dir(path) else { - if search.verbose { - eprintln!("Could not read {:?}", path); - } - return; + let read ={ + profi::prof!("search_dir::read_dir"); + let Ok(read) = std::fs::read_dir(path) else { + if search.verbose { + eprintln!("Could not read {:?}", path); + } + return; + }; + read }; rayon::scope(|s| { @@ -72,9 +76,11 @@ fn search_dir(path: impl AsRef, search: &Search, sender: Sender) { continue; }; if let Some(result) = result { + profi::prof!("search_dir::send_result"); sender.send(result).unwrap(); } if let Some(path) = is_dir { + profi::prof!("search_dir::spawn_search_dir"); s.spawn(|_| search_dir(path, search, sender.clone())); } } @@ -87,8 +93,11 @@ fn is_result( search: &Search, ) -> Option<(Option, Option>)> { // Get entry name - let path = entry.path(); - + let path = { + profi::prof!("is_result::entry.path"); + entry.path() + }; + { profi::prof!("is_result::explicit_ignore"); if search.explicit_ignore.binary_search(&path).is_ok() { @@ -96,7 +105,7 @@ fn is_result( } } -/* let hardcoded = || { + /* let hardcoded = || { profi::prof!("is_result::hardcoded_ignore"); search .hardcoded_ignore @@ -106,6 +115,7 @@ fn is_result( let is_hidden = || { #[cfg(unix)] { + profi::prof!("is_result::is_hidden"); is_hidden(&path) } #[cfg(windows)] @@ -114,35 +124,53 @@ fn is_result( } }; - if !search.hidden && (is_hidden() /* || hardcoded() */) { - return None; + { + profi::prof!("is_result::hidden_check"); + if !search.hidden && (is_hidden()/* || hardcoded() */) { + return None; + } } // Read type of file and check if it should be added to search results - let is_dir = matches!(entry.file_type(), Ok(ftype) if ftype.is_dir()); - let ftype = match search.ftype { - FileType::Dir => is_dir, - FileType::File => !is_dir, - FileType::All => true, + let is_dir = { + profi::prof!("is_result::is_dir"); + matches!(entry.file_type(), Ok(ftype) if ftype.is_dir()) + }; + let ftype = { + profi::prof!("is_result::get_ftype"); + match search.ftype { + FileType::Dir => is_dir, + FileType::File => !is_dir, + FileType::All => true, + } + }; + + let Some(fname) = file_name(&path) else { + profi::prof!("is_result::return_invalid_file_name"); + return Some((None, is_dir.then_some(path.into_boxed_path()))) + }; + let fname = { + profi::prof!("is_result::fname.to_string_lossy"); + fname.to_string_lossy() }; - - let fname = file_name(&path).unwrap(); - let fname = fname.to_string_lossy(); let sname: std::borrow::Cow = if search.case_sensitive { + profi::prof!("is_result::sname"); fname.as_ref().into() } else { + profi::prof!("is_result::to_ascii_lowercase"); fname.to_ascii_lowercase().into() }; let starts = || { profi::prof!("is_result::starts_with"); - search.starts.is_empty() || sname.starts_with(&search.starts) + search.starts.is_empty() || sname.starts_with(&search.starts) }; let ends = || { profi::prof!("is_result::ends_with"); - search.ends.is_empty() || sname.ends_with(&search.ends) + search.ends.is_empty() || sname.ends_with(&search.ends) }; - + + profi::prof!("is_result::substring_checks"); if ftype && starts() && ends() { let (equals, contains) = { profi::prof!("is_result::contains"); @@ -154,6 +182,7 @@ fn is_result( }; // If file name is equal to search name, write it to the "Exact" buffer if equals { + profi::prof!("is_result::return_exact"); return Some(( Some(SearchResult::exact(path.to_string_lossy().into_owned())), is_dir.then_some(path.into_boxed_path()), @@ -166,12 +195,14 @@ fn is_result( } else { path.to_string_lossy().into_owned() }; + profi::prof!("is_result::return_contains"); return Some(( Some(SearchResult::contains(s)), is_dir.then_some(path.into_boxed_path()), )); } } + profi::prof!("is_result::return_not_found"); Some((None, is_dir.then_some(path.into_boxed_path()))) } @@ -263,6 +294,7 @@ pub(crate) fn is_hidden(entry: &std::fs::DirEntry) -> bool { /// /// If the path terminates in ., .., or consists solely of a root of prefix, /// file_name will return None. +#[profi::profile] #[cfg(unix)] #[inline(always)] pub(crate) fn file_name + ?Sized>(path: &P) -> Option<&std::ffi::OsStr> { diff --git a/src/structs.rs b/src/structs.rs index 49d6758..3057af7 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -42,9 +42,9 @@ pub struct Search { // pub hardcoded_ignore: phf::Set<&'static str>, /// Directories specified by the user to be searched in. pub dirs: Vec, - + /// Memchr Finder - pub finder: memchr::memmem::Finder<'static> + pub finder: memchr::memmem::Finder<'static>, } impl Search { @@ -86,7 +86,7 @@ impl Search { ends, ftype, explicit_ignore, -/* hardcoded_ignore: phf::phf_set! { + /* hardcoded_ignore: phf::phf_set! { "/proc", "/root", "/boot", @@ -108,8 +108,8 @@ impl Search { "/etc/audit", }, */ dirs: search_in_dirs, - - finder + + finder, } } } From 64dde049fbc6e3bee7c62c71dd679e4496faea26 Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Wed, 22 May 2024 10:04:53 +0200 Subject: [PATCH 09/14] Make benchmarks more generic --- Cargo.lock | 8 ++++---- Cargo.toml | 9 +++++++-- benchmarks/run | 4 ++-- src/search.rs | 11 ++--------- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 978b33e..6b39943 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -345,9 +345,9 @@ dependencies = [ [[package]] name = "profi" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459e6eeefd402b40e5b412c466000bd2bedb30452f8baccb5a658abcea660a4c" +checksum = "41a7771fea2a42f1d0df39c3c9a742284b56166670393884fca87eb56d43efc0" dependencies = [ "beef", "comfy-table", @@ -359,9 +359,9 @@ dependencies = [ [[package]] name = "profi-attributes" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5de21eb23fff8887286dceb38007da2692d6ec8b330dcb23ddeeb0c84838274" +checksum = "725c1a2cf15516eb45afb27f7d86889132299f5756e245043c046c7a34126cab" dependencies = [ "proc-macro-crate", ] diff --git a/Cargo.toml b/Cargo.toml index 30008fa..7d81039 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,13 @@ rayon = "1.9.0" # Parallelism li crossbeam-channel = "0.5.12" # Faster channels (mpmc) mimalloc = { version = "0.1.39", default-features = false } # Faster allocator thin_str = "0.1.0" # Thinner string (only 8 bytes) -memchr = { version = "2.7.1", features = ["std", "alloc"] } # Small substring search optimization -profi = { version = "*", default-features = false, features = ["rayon", "attributes"]} # Multithreaded fine-grained profiler +memchr = { version = "2.7.1", features = ["std", "alloc"] } # Small substring search optimization + +# Multithreaded fine-grained profiler +[dependencies.profi] +version = "0.1.2" +features = ["rayon", "attributes"] +default-features = false [target.'cfg(target_os = "linux")'.dependencies] rustix = { version = "0.38.31", default-features = false, features = ["fs", "alloc"] } diff --git a/benchmarks/run b/benchmarks/run index b695245..f126190 100644 --- a/benchmarks/run +++ b/benchmarks/run @@ -29,7 +29,7 @@ sub bench { /// Search multiple files in ~/ cmd 2() { $build; - HUNT="../target/release/hunt-pariter --hidden SomeFile $HOME"; + HUNT="hunt --hidden SomeFile $HOME"; HUNT2="$hunt --hidden SomeFile $HOME"; FD="$fd SomeFile $HOME"; # FIND="find $HOME -name SomeFile -print"; @@ -43,7 +43,7 @@ sub bench { /// Search multiple files in / cmd 3() { $build; - HUNT="../target/release/hunt-iter --hidden SomeFile /"; + HUNT="hunt --hidden SomeFile /"; HUNT2="$hunt --hidden SomeFile /"; FD="$fd SomeFile /"; hyperfine -N --warmup 1 --ignore-failure \ diff --git a/src/search.rs b/src/search.rs index 7b37cef..6376295 100644 --- a/src/search.rs +++ b/src/search.rs @@ -104,14 +104,7 @@ fn is_result( return None; } } - - /* let hardcoded = || { - profi::prof!("is_result::hardcoded_ignore"); - search - .hardcoded_ignore - .contains(unsafe { std::mem::transmute::<&Path, &str>(path.as_path()) }) - }; */ - + let is_hidden = || { #[cfg(unix)] { @@ -126,7 +119,7 @@ fn is_result( { profi::prof!("is_result::hidden_check"); - if !search.hidden && (is_hidden()/* || hardcoded() */) { + if !search.hidden && is_hidden() { return None; } } From 14d259219c2359188450d694a42b2b07d94c0c49 Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Wed, 22 May 2024 10:07:15 +0200 Subject: [PATCH 10/14] update version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b39943..bbfcf2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -227,7 +227,7 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hunt" -version = "2.3.0" +version = "2.4.0" dependencies = [ "clap", "colored", diff --git a/Cargo.toml b/Cargo.toml index 7d81039..3fcc6e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ repository = "https://github.com/LyonSyonII/hunt-rs" keywords = ["algorithms", "filesystem"] readme = "README.md" license = "MIT" -version = "2.3.0" +version = "2.4.0" authors = ["Liam G "] edition = "2021" From 4a929401b8b475c59fbeb71db0c1c4b6fc86f675 Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Wed, 22 May 2024 10:22:54 +0200 Subject: [PATCH 11/14] update flake --- flake.lock | 24 ++++++++++++------------ flake.nix | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/flake.lock b/flake.lock index 1cf1c89..3d9a87e 100644 --- a/flake.lock +++ b/flake.lock @@ -6,11 +6,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1715754333, - "narHash": "sha256-u3B+RvDD/kPxMS0Dkm+x+BlzfCqghT3kdev+1UYKvis=", + "lastModified": 1716359173, + "narHash": "sha256-pYcjP6Gy7i6jPWrjiWAVV0BCQp+DdmGaI/k65lBb/kM=", "owner": "nix-community", "repo": "fenix", - "rev": "795a549e443c9690a74a042408600f13091e8b51", + "rev": "b6fc5035b28e36a98370d0eac44f4ef3fd323df6", "type": "github" }, "original": { @@ -39,11 +39,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1715534503, - "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=", + "lastModified": 1716293225, + "narHash": "sha256-pU9ViBVE3XYb70xZx+jK6SEVphvt7xMTbm6yDIF4xPs=", "owner": "nixos", "repo": "nixpkgs", - "rev": "2057814051972fa1453ddfb0d98badbea9b83c06", + "rev": "3eaeaeb6b1e08a016380c279f8846e0bd8808916", "type": "github" }, "original": { @@ -55,11 +55,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1715774670, - "narHash": "sha256-iJYnKMtLi5u6hZhJm94cRNSDG5Rz6ZzIkGbhPFtDRm0=", + "lastModified": 1716312448, + "narHash": "sha256-PH3w5av8d+TdwCkiWN4UPBTxrD9MpxIQPDVWctlomVo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b3fcfcfabd01b947a1e4f36622bbffa3985bdac6", + "rev": "e381a1288138aceda0ac63db32c7be545b446921", "type": "github" }, "original": { @@ -79,11 +79,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1715714902, - "narHash": "sha256-JnvpKHfDip0xq+ThdXFnNkYsV0Z0Q7ukFuW+W30vGhw=", + "lastModified": 1716107283, + "narHash": "sha256-NJgrwLiLGHDrCia5AeIvZUHUY7xYGVryee0/9D3Ir1I=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "c0732c9f0f91bdc31d8da320be16d1db06c848d8", + "rev": "21ec8f523812b88418b2bfc64240c62b3dd967bd", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 969500e..464af03 100644 --- a/flake.nix +++ b/flake.nix @@ -29,6 +29,7 @@ fenix.complete.llvm-tools-preview ]; RUST_SRC_PATH = "${pkgs.fenix.complete.rust-src}/lib/rustlib/src/rust/library"; + RUSTFLAGS="-Zcodegen-backend=llvm"; }; }); } \ No newline at end of file From 8a938d114f429abfb42846a687a8360344bb0fed Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Wed, 22 May 2024 11:02:52 +0200 Subject: [PATCH 12/14] feat: add --select and --multiselect options to show an interactable selection screen --- Cargo.lock | 432 +++++++++++++++++++++++++++++++++++++------------ Cargo.toml | 1 + src/print.rs | 30 ++++ src/structs.rs | 127 +++------------ 4 files changed, 387 insertions(+), 203 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bbfcf2b..9dbc2db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,52 +4,59 @@ version = 3 [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", ] +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + [[package]] name = "beef" version = "0.5.2" @@ -58,21 +65,33 @@ checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" [[package]] name = "bitflags" -version = "2.4.2" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" [[package]] name = "cfg-if" @@ -82,9 +101,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.2" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -104,14 +123,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.65", ] [[package]] @@ -122,9 +141,9 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "colored" @@ -138,9 +157,9 @@ dependencies = [ [[package]] name = "comfy-table" -version = "7.1.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" +checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" dependencies = [ "strum", "strum_macros", @@ -149,9 +168,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] @@ -177,9 +196,34 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crossterm" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +dependencies = [ + "bitflags 1.3.2", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] [[package]] name = "ctor" @@ -191,11 +235,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + [[package]] name = "either" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "equivalent" @@ -205,19 +255,37 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", ] +[[package]] +name = "fuzzy-matcher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" +dependencies = [ + "thread_local", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -225,6 +293,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hunt" version = "2.4.0" @@ -232,6 +306,7 @@ dependencies = [ "clap", "colored", "crossbeam-channel", + "inquire", "memchr", "mimalloc", "profi", @@ -251,6 +326,29 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inquire" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" +dependencies = [ + "bitflags 2.5.0", + "crossterm", + "dyn-clone", + "fuzzy-matcher", + "fxhash", + "newline-converter", + "once_cell", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "js-sys" version = "0.3.69" @@ -268,15 +366,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libmimalloc-sys" -version = "0.1.35" +version = "0.1.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3979b5c37ece694f1f5e51e7ecc871fdb0f517ed04ee45f88d15d6d553cb9664" +checksum = "0e7bb23d733dfcc8af652a78b7bf232f0e967710d044732185e561e47c0336b6" dependencies = [ "cc", "libc", @@ -284,9 +382,19 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] [[package]] name = "log" @@ -296,15 +404,15 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mimalloc" -version = "0.1.39" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa01922b5ea280a911e323e4d2fd24b7fe5cc4042e0d2cda3c40775cdc4bdc9c" +checksum = "e9186d86b79b52f4a77af65604b51225e8db1d6ee7e3f41aec1e40829c71a176" dependencies = [ "libmimalloc-sys", ] @@ -319,12 +427,56 @@ dependencies = [ "web-time", ] +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "newline-converter" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "parking_lot" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.5", +] + [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -336,9 +488,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" dependencies = [ "unicode-ident", ] @@ -368,18 +520,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "rayon" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -395,13 +547,22 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -410,33 +571,75 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.25.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", - "syn 2.0.52", + "syn 2.0.65", ] [[package]] @@ -452,9 +655,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.52" +version = "2.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" dependencies = [ "proc-macro2", "quote", @@ -467,11 +670,21 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be9d479371ac7a8e00f077b47e26db313447fa59ca276ad73c4716975f3895d4" +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" [[package]] name = "toml_edit" @@ -490,11 +703,17 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" [[package]] name = "utf8parse" @@ -502,6 +721,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.92" @@ -523,7 +748,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.65", "wasm-bindgen-shared", ] @@ -545,7 +770,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.65", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -584,11 +809,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -612,7 +837,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -632,17 +857,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -653,9 +879,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -665,9 +891,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -677,9 +903,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -689,9 +921,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -701,9 +933,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -713,9 +945,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -725,9 +957,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" diff --git a/Cargo.toml b/Cargo.toml index 3fcc6e0..83824fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ crossbeam-channel = "0.5.12" # Faster channel mimalloc = { version = "0.1.39", default-features = false } # Faster allocator thin_str = "0.1.0" # Thinner string (only 8 bytes) memchr = { version = "2.7.1", features = ["std", "alloc"] } # Small substring search optimization +inquire = { version = "0.7.5" } # Multiselect CLI interface # Multithreaded fine-grained profiler [dependencies.profi] diff --git a/src/print.rs b/src/print.rs index 06c3e3e..a37ef58 100644 --- a/src/print.rs +++ b/src/print.rs @@ -26,6 +26,13 @@ impl Search { profi::prof!(sort); rayon::join(|| co.par_sort(), || ex.par_sort()); } + + if self.select { + return select((ex, co), stdout); + } + if self.multiselect { + return multiselect((ex, co), stdout); + } if self.output == Output::Normal { writeln!(stdout, "Contains:")?; @@ -44,6 +51,29 @@ impl Search { } } +pub fn select((ex, co): Buffers, mut stdout: impl std::io::Write) -> std::io::Result<()> { + let v = ex.into_iter().chain(co).collect(); + let selected = inquire::Select::new("Select a file:", v).prompt(); + if let Ok(selected) = selected { + write!(stdout, "{selected}")?; + } + Ok(()) +} + +pub fn multiselect((ex, co): Buffers, mut stdout: impl std::io::Write) -> std::io::Result<()> { + let v = ex.into_iter().chain(co).collect(); + let mut selected = inquire::MultiSelect::new("Select files:", v) + .prompt().unwrap_or_default().into_iter(); + + if let Some(f) = selected.next() { + write!(stdout, "{f}")?; + } + for f in selected { + write!(stdout, " {f}")?; + } + Ok(()) +} + #[profi::profile] pub fn print_with_highlight( stdout: &mut impl std::io::Write, diff --git a/src/structs.rs b/src/structs.rs index 3057af7..6aa72ac 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -22,6 +22,10 @@ pub struct Search { pub verbose: bool, /// If hidden directories must be traversed and hidden files counted as matches. pub hidden: bool, + /// If the select interface will be shown. + pub select: bool, + /// If the multiselect interface will be shown. + pub multiselect: bool, /// Type of the output. /// /// Simple makes it not to be highlighted and removes the "Exact:" and "Contains:" distinctions. @@ -57,6 +61,8 @@ impl Search { limit: bool, verbose: bool, hidden: bool, + select: bool, + multiselect: bool, output: u8, name: String, starts: String, @@ -71,7 +77,7 @@ impl Search { _ => Output::SuperSimple, }; let finder = memchr::memmem::Finder::new(name.as_bytes()).into_owned(); - + Search { first, exact, @@ -80,33 +86,14 @@ impl Search { limit, verbose, hidden, + select, + multiselect, output, name, starts, ends, ftype, explicit_ignore, - /* hardcoded_ignore: phf::phf_set! { - "/proc", - "/root", - "/boot", - "/dev", - "/lib", - "/lib64", - "/lost+found", - "/run", - "/sbin", - "/sys", - "/tmp", - "/var/tmp", - "/var/lib", - "/var/log", - "/var/db", - "/var/cache", - "/etc/pacman.d", - "/etc/sudoers.d", - "/etc/audit", - }, */ dirs: search_in_dirs, finder, @@ -208,6 +195,18 @@ pub struct Cli { #[arg(short = 'H', long)] hidden: bool, + /// When the search is finished, choose one file between the results + /// + /// The selected file will be printed as if -ss was used + #[arg(long, conflicts_with_all(["simple", "multiselect", "first"]))] + select: bool, + + /// When the search is finished, choose between the results + /// + /// The selected files will be printed one after the other, separated by spaces + #[arg(long, conflicts_with_all(["simple", "select", "first"]))] + multiselect: bool, + /// Only files that start with this will be found #[arg(short = 'S', long = "starts")] starts_with: Option, @@ -290,6 +289,8 @@ impl Cli { !search_in_dirs.is_empty(), cli.verbose, cli.hidden, + cli.select, + cli.multiselect, cli.simple, name, starts, @@ -299,84 +300,4 @@ impl Cli { search_in_dirs, ) } -} - -const fn sorted(mut array: [&'static str; N]) -> [&'static str; N] { - let mut i = 0; - while i < array.len() { - let mut j = 0; - while j < array.len() { - if lt(array[i], array[j]) { - let tmp = array[i]; - array[i] = array[j]; - array[j] = tmp; - } - - j += 1; - } - - i += 1; - } - array -} - -const fn lt(lhs: &str, rhs: &str) -> bool { - let lhs = lhs.as_bytes(); - let rhs = rhs.as_bytes(); - - let smallest = if lhs.len() < rhs.len() { - lhs.len() - } else { - rhs.len() - }; - - let mut i = 0; - while i < smallest { - let lhs = lhs[i]; - let rhs = rhs[i]; - - if lhs < rhs { - return true; - } - if lhs > rhs { - return false; - } - - i += 1; - } - lhs.len() == smallest -} - -#[test] -fn const_sorted() { - fn check(mut array: [&'static str; N]) { - let sorted = sorted(array); - array.sort_unstable(); - assert_eq!(sorted, array) - } - - check(["b", "c", "a", "d"]); - check(["b", "c", "a", "d", "aa"]); - check([ - "/proc", - "/root", - "/booty", - "/boot", - "/dev", - "/lib", - "/lib64", - "/lost+found", - "/run", - "/sbin", - "/sys", - "/tmp", - "/var/tmp", - "/var/lib", - "/var/log", - "/var/db", - "/var/cache", - "/etc/pacman.d", - "/etc/sudoers.d", - "/etc/audit", - ]) -} +} \ No newline at end of file From cd88eac6e76794242ca1ef41d09a974d2cf5f6f4 Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Wed, 22 May 2024 11:11:29 +0200 Subject: [PATCH 13/14] doc: update documentation to newest features --- README.md | 99 ++++++++++++++++++++++++++++---------------------- src/structs.rs | 2 +- 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index ba5b087..5c3d560 100644 --- a/README.md +++ b/README.md @@ -18,69 +18,82 @@ Check the [Benchmarks](#benchmarks) for a comparison with other tools. ## Usage hunt [OPTIONS] [NAME] [SEARCH_IN_DIRS]... -By default, searches are case-insensitive, unless \ contains an uppercase letter or the -C flag is set. +By default, searches are case-insensitive, unless `[NAME]` contains an uppercase letter or the `--case-sensitive` flag is set. ### Options + -f, --first + Stop when first occurrence is found + + -e, --exact + Only search for exactly matching occurrences, any file only containing the query will be skipped + + e.g. if query is "SomeFile", "I'mSomeFile" will be skipped, as its name contains more letters than the search + -c, --canonicalize - If enabled, all paths will be canonicalized. + If enabled, all paths will be canonicalized + -C, --case-sensitive - If enabled, the search will be case-sensitive + If enabled, the search will be case-sensitive + + Note that case-sensitivity will be activated automatically when the search query contains an uppercase letter - Note that case-sensitivity will be activated automatically when the search query - contains an uppercase letter. + -v, --verbose + Print verbose output + + It'll show all errors found: e.g. "Could not read /proc/81261/map_files" - -e, --exact Only search for exactly matching occurrences, any file only - containing the query will be skipped + -s, --simple... + Prints without formatting (without "Contains:" and "Exact:") - e.g. if query is "SomeFile", "I'mSomeFile" will be skipped, - as its name contains more letters than the search + -ss Output is not sorted - -f, --first Stop when first occurrence is found + -H, --hidden + If enabled, it searches inside hidden directories + + If not enabled, hidden directories will be skipped - -H, --hidden If enabled, it searches inside hidden and ignored directories. + --select + When the search is finished, choose one file between the results + + The selected file will be printed as if -ss was used - The list of ignored directories is: - "/proc", "/root", "/boot", "/dev", "/lib", "/lib64", - "/lost+found", "/run", "/sbin", "/sys", "/tmp", "/var/tmp", - "/var/lib", "/var/log", "/var/db", "/var/cache", - "/etc/pacman.d", "/etc/sudoers.d" and "/etc/audit" + --multiselect + When the search is finished, choose between the results + + The selected files will be printed one after the other, separated by spaces - -i, --ignore - Search ignores this directories. The format is: - -i dir1,dir2,dir3,... (without spaces) + -S, --starts + Only files that start with this will be found - -S, --starts - Only files that start with this will be found - - -E, --ends - Only files that end with this will be found + -E, --ends + Only files that end with this will be found - -t, --type - Specifies the type of the file - 'f' -> file - 'd' -> directory + -t, --type + Specifies the type of the file + + 'f' -> file | 'd' -> directory - -v, --verbose Print verbose output - It'll show all errors found: e.g. "Could not read /proc/81261/map_files" - - -s, --simple Prints without formatting (without "Contains:" and "Exact:") - Useful for pairing it with other commands like xargs - - -ss Same as -s, but without sorting the output + -i, --ignore + Ignores this directories. The format is: + + -i dir1,dir2,dir3,... + -h, --help + Print help (see a summary with '-h') - -h --help Print help information + -V, --version + Print version -If the --first flag is set, the order in which the file will be searched is [current_dir, home_dir, root]. -If you're already in one of these directories, "current_dir" will be skipped. +If the `--first` flag is set, the order in which the file will be searched is `[current_dir, home_dir, root]`. +If you're already in one of these directories, `current_dir` will be skipped. -If the --hidden flag is **not** set, hidden files/directories will be skipped, as well as: /proc, /root, /boot, /dev, /lib, /lib64, /lost+found, /run, /sbin, /sys, /tmp, /var/tmp, /var/lib, /var/log, /var/db, /var/cache, /etc/pacman.d, /etc/sudoers.d and /etc/audit +If the `--hidden` flag is **not** set, hidden files/directories will be skipped. ### Args - Name of the file/folder to search + [NAME] Name of the file/folder to search By default, searches are case-insensitive, unless the query contains an uppercase letter. - ... + [SEARCH_IN_DIRS]... Directories where you want to search If provided, hunt will only search there @@ -216,7 +229,7 @@ For the curious, it scored a time of 486.8 ms, only 1.32 times faster than Hunt. #### Hunt ``` -Benchmark 1: hunt -h SomeFile / +Benchmark 1: hunt -H SomeFile / Time (mean ± σ): 633.6 ms ± 25.1 ms [User: 2876.7 ms, System: 2507.5 ms] Range (min … max): 589.4 ms … 671.2 ms 10 runs ``` @@ -238,7 +251,7 @@ Benchmark 3: find / -name "*SomeFile*" #### Summary ``` -'hunt -h SomeFile /' ran +'hunt -H SomeFile /' ran 2.29 ± 0.09 times faster than 'fd -HI -c never SomeFile /' 5.48 ± 0.31 times faster than 'find / -name "*SomeFile*"' ``` diff --git a/src/structs.rs b/src/structs.rs index 6aa72ac..435ec7f 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -191,7 +191,7 @@ pub struct Cli { /// If enabled, it searches inside hidden directories /// - /// If not enabled, hidden directories (starting with '.') and "/proc", "/root", "/boot", "/dev", "/lib", "/lib64", "/lost+found", "/run", "/sbin", "/sys", "/tmp", "/var/tmp", "/var/lib", "/var/log", "/var/db", "/var/cache", "/etc/pacman.d", "/etc/sudoers.d" and "/etc/audit" will be skipped + /// If not enabled, hidden directories will be skipped #[arg(short = 'H', long)] hidden: bool, From e712f2dae1b027c870e7cf148617b9086bbfd247 Mon Sep 17 00:00:00 2001 From: lyonsyonii Date: Wed, 22 May 2024 11:21:35 +0200 Subject: [PATCH 14/14] add changelog --- CHANGELOG.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec03a41..54db315 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,23 @@ All notable changes to this project will be documented in this file. -## [2.3.0] +## \[2.4.0] + +### 🚀 Features + +- Add `--select` and `--multiselect` options for an interactive file select screen. + - Useful for chaining `hunt` with other commands. +- Remove implicit ignore list, as it affected performance globally for a very small gain in specific queries. +- More optimized substring search with [memchr](https://crates.io/crates/memchr). + +## \[2.3.0] ### 🚀 Features - Multiple small optimizations for up to 25% performance improvement - Parallelism is now at directory level instead of file level -## [2.2.0] +## \[2.2.0] ### 🚀 Features @@ -21,7 +30,7 @@ All notable changes to this project will be documented in this file. - [fix: fixed freeze when reading from current directory](https://github.com/LyonSyonII/hunt-rs/commit/f54de3d8963020d2c9266b380d09e736b7bb49f0) - [fix: Output is no longer highlighted when -s or -ss is provided](https://github.com/LyonSyonII/hunt-rs/commit/bf9aecbd7d6c49578232d19640ad9e99136a22ae) -## [2.1.0] +## \[2.1.0] ### 🚀 Features @@ -33,7 +42,7 @@ All notable changes to this project will be documented in this file. - Avoid allocation in case of case_sensitivity - Fixed canonicalization -## [2.0.0] +## \[2.0.0] ### Breaking changes - Updated to clap 4.3.0. - Changed `case_sensitive` flag from `-c` to `-C`.