mirror of
https://github.com/Llewellynvdm/exa.git
synced 2025-01-23 21:58:27 +00:00
Cache user and group names
I checked strace and it was reading /etc/passwd every time it needed to look up a user or group. Now it only does it once per.
This commit is contained in:
parent
5c0d2d07d0
commit
b5a1b24bda
5
exa.rs
5
exa.rs
@ -7,6 +7,7 @@ use std::os;
|
||||
use file::File;
|
||||
use dir::Dir;
|
||||
use options::Options;
|
||||
use unix::Unix;
|
||||
|
||||
pub mod colours;
|
||||
pub mod column;
|
||||
@ -61,8 +62,10 @@ fn exa(options: &Options, string: String) {
|
||||
// width of each column based on the length of the results and
|
||||
// padding the fields during output.
|
||||
|
||||
let mut cache = Unix::empty_cache();
|
||||
|
||||
let table: Vec<Vec<String>> = files.iter()
|
||||
.map(|f| options.columns.iter().map(|c| f.display(c)).collect())
|
||||
.map(|f| options.columns.iter().map(|c| f.display(c, &mut cache)).collect())
|
||||
.collect();
|
||||
|
||||
// Each column needs to have its invisible colour-formatting
|
||||
|
8
file.rs
8
file.rs
@ -4,7 +4,7 @@ use std::io;
|
||||
|
||||
use column::{Column, Permissions, FileName, FileSize, User, Group};
|
||||
use format::{format_metric_bytes, format_IEC_bytes};
|
||||
use unix::{get_user_name, get_group_name};
|
||||
use unix::Unix;
|
||||
use sort::SortPart;
|
||||
use dir::Dir;
|
||||
use filetype::HasType;
|
||||
@ -89,7 +89,7 @@ impl<'a> File<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display(&self, column: &Column) -> String {
|
||||
pub fn display(&self, column: &Column, unix: &mut Unix) -> String {
|
||||
match *column {
|
||||
Permissions => self.permissions_string(),
|
||||
FileName => self.file_name(),
|
||||
@ -99,10 +99,10 @@ impl<'a> File<'a> {
|
||||
// usually means it was deleted but its files weren't.
|
||||
User(uid) => {
|
||||
let style = if uid == self.stat.unstable.uid { Yellow.bold() } else { Plain };
|
||||
let string = get_user_name(self.stat.unstable.uid as i32).unwrap_or(self.stat.unstable.uid.to_str());
|
||||
let string = unix.get_user_name(self.stat.unstable.uid as i32).unwrap_or(self.stat.unstable.uid.to_str());
|
||||
return style.paint(string.as_slice());
|
||||
},
|
||||
Group => get_group_name(self.stat.unstable.gid as u32).unwrap_or(self.stat.unstable.gid.to_str()),
|
||||
Group => unix.get_group_name(self.stat.unstable.gid as u32).unwrap_or(self.stat.unstable.gid.to_str()),
|
||||
}
|
||||
}
|
||||
|
||||
|
48
unix.rs
48
unix.rs
@ -1,5 +1,6 @@
|
||||
use std::str::raw::from_c_str;
|
||||
use std::ptr::read;
|
||||
use std::collections::hashmap::HashMap;
|
||||
|
||||
mod c {
|
||||
#![allow(non_camel_case_types)]
|
||||
@ -34,24 +35,41 @@ mod c {
|
||||
pub fn getuid() -> libc::c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_user_name(uid: i32) -> Option<String> {
|
||||
let pw = unsafe { c::getpwuid(uid) };
|
||||
if pw.is_not_null() {
|
||||
return unsafe { Some(from_c_str(read(pw).pw_name)) };
|
||||
}
|
||||
else {
|
||||
return None;
|
||||
}
|
||||
pub struct Unix {
|
||||
user_names: HashMap<i32, Option<String>>,
|
||||
group_names: HashMap<u32, Option<String>>,
|
||||
}
|
||||
|
||||
pub fn get_group_name(gid: u32) -> Option<String> {
|
||||
let gr = unsafe { c::getgrgid(gid) };
|
||||
if gr.is_not_null() {
|
||||
return unsafe { Some(from_c_str(read(gr).gr_name)) };
|
||||
impl Unix {
|
||||
pub fn empty_cache() -> Unix {
|
||||
Unix {
|
||||
user_names: HashMap::new(),
|
||||
group_names: HashMap::new(),
|
||||
}
|
||||
}
|
||||
else {
|
||||
return None;
|
||||
|
||||
pub fn get_user_name<'a> (&'a mut self, uid: i32) -> Option<String> {
|
||||
self.user_names.find_or_insert_with(uid, |&u| {
|
||||
let pw = unsafe { c::getpwuid(u) };
|
||||
if pw.is_not_null() {
|
||||
return unsafe { Some(from_c_str(read(pw).pw_name)) };
|
||||
}
|
||||
else {
|
||||
return None;
|
||||
}
|
||||
}).clone()
|
||||
}
|
||||
|
||||
pub fn get_group_name<'a>(&'a mut self, gid: u32) -> Option<String> {
|
||||
self.group_names.find_or_insert_with(gid, |&gid| {
|
||||
let gr = unsafe { c::getgrgid(gid) };
|
||||
if gr.is_not_null() {
|
||||
return unsafe { Some(from_c_str(read(gr).gr_name)) };
|
||||
}
|
||||
else {
|
||||
return None;
|
||||
}
|
||||
}).clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user