mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
ls: Lazily obtain FileType, eagerly obtain Metadata when Metadata is available (#8753)
Improves the ls perf by +10% in some cases
This commit is contained in:
Generated
+1
@@ -3608,6 +3608,7 @@ dependencies = [
|
||||
"clap",
|
||||
"codspeed-divan-compat",
|
||||
"fluent",
|
||||
"fnv",
|
||||
"glob",
|
||||
"hostname",
|
||||
"lscolors",
|
||||
|
||||
@@ -24,6 +24,7 @@ ansi-width = { workspace = true }
|
||||
clap = { workspace = true, features = ["env"] }
|
||||
glob = { workspace = true }
|
||||
hostname = { workspace = true }
|
||||
fnv = { workspace = true }
|
||||
lscolors = { workspace = true }
|
||||
selinux = { workspace = true, optional = true }
|
||||
terminal_size = { workspace = true }
|
||||
|
||||
+15
-22
@@ -3,11 +3,9 @@
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
use super::PathData;
|
||||
use super::get_metadata_with_deref_opt;
|
||||
use lscolors::{Indicator, LsColors, Style};
|
||||
use lscolors::{Colorable, Indicator, LsColors, Style};
|
||||
use std::ffi::OsString;
|
||||
use std::fs::{DirEntry, Metadata};
|
||||
use std::io::{BufWriter, Stdout};
|
||||
use std::fs::Metadata;
|
||||
|
||||
/// We need this struct to be able to store the previous style.
|
||||
/// This because we need to check the previous value in case we don't need
|
||||
@@ -135,25 +133,22 @@ impl<'a> StyleManager<'a> {
|
||||
self.apply_style(style, name, wrap)
|
||||
}
|
||||
|
||||
pub(crate) fn apply_style_based_on_dir_entry(
|
||||
pub(crate) fn apply_style_based_on_colorable<T: Colorable>(
|
||||
&mut self,
|
||||
dir_entry: &DirEntry,
|
||||
path: &T,
|
||||
name: OsString,
|
||||
wrap: bool,
|
||||
) -> OsString {
|
||||
let style = self.colors.style_for(dir_entry);
|
||||
let style = self.colors.style_for(path);
|
||||
self.apply_style(style, name, wrap)
|
||||
}
|
||||
}
|
||||
|
||||
/// Colors the provided name based on the style determined for the given path
|
||||
/// This function is quite long because it tries to leverage [`DirEntry`] to avoid
|
||||
/// unnecessary calls to stat and manages the symlink errors
|
||||
pub(crate) fn color_name(
|
||||
name: OsString,
|
||||
path: &PathData,
|
||||
style_manager: &mut StyleManager,
|
||||
out: &mut BufWriter<Stdout>,
|
||||
target_symlink: Option<&PathData>,
|
||||
wrap: bool,
|
||||
) -> OsString {
|
||||
@@ -179,23 +174,21 @@ pub(crate) fn color_name(
|
||||
|
||||
if !path.must_dereference {
|
||||
// If we need to dereference (follow) a symlink, we will need to get the metadata
|
||||
if let Some(de) = &path.de {
|
||||
// There is a DirEntry, we don't need to get the metadata for the color
|
||||
return style_manager.apply_style_based_on_dir_entry(de, name, wrap);
|
||||
}
|
||||
// There is a DirEntry, we don't need to get the metadata for the color
|
||||
return style_manager.apply_style_based_on_colorable(path, name, wrap);
|
||||
}
|
||||
|
||||
if let Some(target) = target_symlink {
|
||||
// use the optional target_symlink
|
||||
// Use fn get_metadata_with_deref_opt instead of get_metadata() here because ls
|
||||
// Use fn symlink_metadata directly instead of get_metadata() here because ls
|
||||
// should not exit with an err, if we are unable to obtain the target_metadata
|
||||
let md_res = get_metadata_with_deref_opt(&target.p_buf, path.must_dereference);
|
||||
let md = md_res.or_else(|_| path.p_buf.symlink_metadata());
|
||||
style_manager.apply_style_based_on_metadata(path, md.ok().as_ref(), name, wrap)
|
||||
style_manager.apply_style_based_on_colorable(target, name, wrap)
|
||||
} else {
|
||||
let md_option = path.get_metadata(out);
|
||||
let symlink_metadata = path.p_buf.symlink_metadata().ok();
|
||||
let md = md_option.or(symlink_metadata.as_ref());
|
||||
style_manager.apply_style_based_on_metadata(path, md, name, wrap)
|
||||
let md_option: Option<Metadata> = path
|
||||
.metadata()
|
||||
.cloned()
|
||||
.or_else(|| path.p_buf.symlink_metadata().ok());
|
||||
|
||||
style_manager.apply_style_based_on_metadata(path, md_option.as_ref(), name, wrap)
|
||||
}
|
||||
}
|
||||
|
||||
+227
-191
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user