1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Merge pull request #7702 from nyurik/iters

feat: optimize iter matching
This commit is contained in:
Yuri Astrakhan 2025-04-15 13:54:58 -04:00 committed by GitHub
parent a37c4a6dc6
commit 8a5a2eed2a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 28 additions and 34 deletions

View file

@ -53,22 +53,20 @@ struct Options {
/// ///
/// The `spec` must be of the form `[USER][:[GROUP]]`, otherwise an /// The `spec` must be of the form `[USER][:[GROUP]]`, otherwise an
/// error is returned. /// error is returned.
fn parse_userspec(spec: &str) -> UResult<UserSpec> { fn parse_userspec(spec: &str) -> UserSpec {
match &spec.splitn(2, ':').collect::<Vec<&str>>()[..] { match spec.split_once(':') {
// "" // ""
[""] => Ok(UserSpec::NeitherGroupNorUser), None if spec.is_empty() => UserSpec::NeitherGroupNorUser,
// "usr" // "usr"
[usr] => Ok(UserSpec::UserOnly(usr.to_string())), None => UserSpec::UserOnly(spec.to_string()),
// ":" // ":"
["", ""] => Ok(UserSpec::NeitherGroupNorUser), Some(("", "")) => UserSpec::NeitherGroupNorUser,
// ":grp" // ":grp"
["", grp] => Ok(UserSpec::GroupOnly(grp.to_string())), Some(("", grp)) => UserSpec::GroupOnly(grp.to_string()),
// "usr:" // "usr:"
[usr, ""] => Ok(UserSpec::UserOnly(usr.to_string())), Some((usr, "")) => UserSpec::UserOnly(usr.to_string()),
// "usr:grp" // "usr:grp"
[usr, grp] => Ok(UserSpec::UserAndGroup(usr.to_string(), grp.to_string())), Some((usr, grp)) => UserSpec::UserAndGroup(usr.to_string(), grp.to_string()),
// everything else
_ => Err(ChrootError::InvalidUserspec(spec.to_string()).into()),
} }
} }
@ -144,10 +142,9 @@ impl Options {
} }
}; };
let skip_chdir = matches.get_flag(options::SKIP_CHDIR); let skip_chdir = matches.get_flag(options::SKIP_CHDIR);
let userspec = match matches.get_one::<String>(options::USERSPEC) { let userspec = matches
None => None, .get_one::<String>(options::USERSPEC)
Some(s) => Some(parse_userspec(s)?), .map(|s| parse_userspec(s));
};
Ok(Self { Ok(Self {
newroot, newroot,
skip_chdir, skip_chdir,

View file

@ -34,10 +34,6 @@ pub enum ChrootError {
#[error("invalid group list: {list}", list = .0.quote())] #[error("invalid group list: {list}", list = .0.quote())]
InvalidGroupList(String), InvalidGroupList(String),
/// The given user and group specification was invalid.
#[error("invalid userspec: {spec}", spec = .0.quote())]
InvalidUserspec(String),
/// The new root directory was not given. /// The new root directory was not given.
#[error( #[error(
"Missing operand: NEWROOT\nTry '{0} --help' for more information.", "Missing operand: NEWROOT\nTry '{0} --help' for more information.",

View file

@ -3,7 +3,7 @@
// For the full copyright and license information, please view the LICENSE // For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code. // file that was distributed with this source code.
// spell-checker:ignore (ToDO) NPROCESSORS nprocs numstr threadstr sysconf // spell-checker:ignore (ToDO) NPROCESSORS nprocs numstr sysconf
use clap::{Arg, ArgAction, Command}; use clap::{Arg, ArgAction, Command};
use std::{env, thread}; use std::{env, thread};
@ -47,7 +47,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
// Uses the OpenMP variable to limit the number of threads // Uses the OpenMP variable to limit the number of threads
// If the parsing fails, returns the max size (so, no impact) // If the parsing fails, returns the max size (so, no impact)
// If OMP_THREAD_LIMIT=0, rejects the value // If OMP_THREAD_LIMIT=0, rejects the value
Ok(threadstr) => match threadstr.parse() { Ok(threads) => match threads.parse() {
Ok(0) | Err(_) => usize::MAX, Ok(0) | Err(_) => usize::MAX,
Ok(n) => n, Ok(n) => n,
}, },
@ -63,14 +63,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
match env::var("OMP_NUM_THREADS") { match env::var("OMP_NUM_THREADS") {
// Uses the OpenMP variable to force the number of threads // Uses the OpenMP variable to force the number of threads
// If the parsing fails, returns the number of CPU // If the parsing fails, returns the number of CPU
Ok(threadstr) => { Ok(threads) => {
// In some cases, OMP_NUM_THREADS can be "x,y,z" // In some cases, OMP_NUM_THREADS can be "x,y,z"
// In this case, only take the first one (like GNU) // In this case, only take the first one (like GNU)
// If OMP_NUM_THREADS=0, rejects the value // If OMP_NUM_THREADS=0, rejects the value
let thread: Vec<&str> = threadstr.split_terminator(',').collect(); match threads.split_terminator(',').next() {
match &thread[..] { None => available_parallelism(),
[] => available_parallelism(), Some(s) => match s.parse() {
[s, ..] => match s.parse() {
Ok(0) | Err(_) => available_parallelism(), Ok(0) | Err(_) => available_parallelism(),
Ok(n) => n, Ok(n) => n,
}, },

View file

@ -108,7 +108,7 @@ impl NumberType {
/// # Errors /// # Errors
/// ///
/// If the string is not one of the valid number types, /// If the string is not one of the valid number types,
/// if `K` is not a nonnegative integer, /// if `K` is not a non-negative integer,
/// or if `K` is 0, /// or if `K` is 0,
/// or if `N` is not a positive integer, /// or if `N` is not a positive integer,
/// or if `K` is greater than `N` /// or if `K` is greater than `N`
@ -117,9 +117,9 @@ impl NumberType {
fn is_invalid_chunk(chunk_number: u64, num_chunks: u64) -> bool { fn is_invalid_chunk(chunk_number: u64, num_chunks: u64) -> bool {
chunk_number > num_chunks || chunk_number == 0 chunk_number > num_chunks || chunk_number == 0
} }
let parts: Vec<&str> = s.split('/').collect(); let mut parts = s.splitn(4, '/');
match &parts[..] { match (parts.next(), parts.next(), parts.next(), parts.next()) {
[n_str] => { (Some(n_str), None, None, None) => {
let num_chunks = parse_size_u64(n_str) let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?; .map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
if num_chunks > 0 { if num_chunks > 0 {
@ -128,7 +128,9 @@ impl NumberType {
Err(NumberTypeError::NumberOfChunks(s.to_string())) Err(NumberTypeError::NumberOfChunks(s.to_string()))
} }
} }
[k_str, n_str] if !k_str.starts_with('l') && !k_str.starts_with('r') => { (Some(k_str), Some(n_str), None, None)
if !k_str.starts_with('l') && !k_str.starts_with('r') =>
{
let num_chunks = parse_size_u64(n_str) let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?; .map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
let chunk_number = parse_size_u64(k_str) let chunk_number = parse_size_u64(k_str)
@ -138,12 +140,12 @@ impl NumberType {
} }
Ok(Self::KthBytes(chunk_number, num_chunks)) Ok(Self::KthBytes(chunk_number, num_chunks))
} }
["l", n_str] => { (Some("l"), Some(n_str), None, None) => {
let num_chunks = parse_size_u64(n_str) let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?; .map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
Ok(Self::Lines(num_chunks)) Ok(Self::Lines(num_chunks))
} }
["l", k_str, n_str] => { (Some("l"), Some(k_str), Some(n_str), None) => {
let num_chunks = parse_size_u64(n_str) let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?; .map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
let chunk_number = parse_size_u64(k_str) let chunk_number = parse_size_u64(k_str)
@ -153,12 +155,12 @@ impl NumberType {
} }
Ok(Self::KthLines(chunk_number, num_chunks)) Ok(Self::KthLines(chunk_number, num_chunks))
} }
["r", n_str] => { (Some("r"), Some(n_str), None, None) => {
let num_chunks = parse_size_u64(n_str) let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?; .map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
Ok(Self::RoundRobin(num_chunks)) Ok(Self::RoundRobin(num_chunks))
} }
["r", k_str, n_str] => { (Some("r"), Some(k_str), Some(n_str), None) => {
let num_chunks = parse_size_u64(n_str) let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?; .map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
let chunk_number = parse_size_u64(k_str) let chunk_number = parse_size_u64(k_str)