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:
parent
a37c4a6dc6
commit
8a5a2eed2a
4 changed files with 28 additions and 34 deletions
|
@ -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,
|
||||||
|
|
|
@ -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.",
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue