66use regex:: Regex ;
77use std:: fs:: read_link;
88use std:: hash:: Hash ;
9- use std:: sync:: LazyLock ;
9+ use std:: sync:: { LazyLock , OnceLock } ;
1010use std:: {
1111 collections:: HashMap ,
1212 fmt:: { self , Display , Formatter } ,
1313 fs, io,
1414 path:: PathBuf ,
15- rc:: Rc ,
1615} ;
1716use walkdir:: { DirEntry , WalkDir } ;
1817
@@ -319,7 +318,7 @@ impl Namespace {
319318}
320319
321320/// Process ID and its information
322- #[ derive( Debug , Clone , Default , PartialEq , Eq ) ]
321+ #[ derive( Debug , Clone , Default ) ]
323322pub struct ProcessInformation {
324323 pub pid : usize ,
325324 pub cmdline : String ,
@@ -328,13 +327,13 @@ pub struct ProcessInformation {
328327 inner_stat : String ,
329328
330329 /// Processed `/proc/self/status` file
331- cached_status : Option < Rc < HashMap < String , String > > > ,
330+ status : OnceLock < HashMap < String , String > > ,
332331 /// Processed `/proc/self/stat` file
333- cached_stat : Option < Rc < Vec < String > > > ,
332+ stat : OnceLock < Vec < String > > ,
334333
335334 cached_start_time : Option < u64 > ,
336335
337- cached_thread_ids : Option < Rc < Vec < usize > > > ,
336+ thread_ids : OnceLock < Vec < usize > > ,
338337}
339338
340339impl ProcessInformation {
@@ -402,34 +401,19 @@ impl ProcessInformation {
402401 }
403402
404403 /// Collect information from `/proc/<pid>/status` file
405- pub fn status ( & mut self ) -> Rc < HashMap < String , String > > {
406- if let Some ( c) = & self . cached_status {
407- return Rc :: clone ( c) ;
408- }
409-
410- let result = self
411- . inner_status
412- . lines ( )
413- . filter_map ( |it| it. split_once ( ':' ) )
414- . map ( |it| ( it. 0 . to_string ( ) , it. 1 . trim_start ( ) . to_string ( ) ) )
415- . collect :: < HashMap < _ , _ > > ( ) ;
416-
417- let result = Rc :: new ( result) ;
418- self . cached_status = Some ( Rc :: clone ( & result) ) ;
419- Rc :: clone ( & result)
404+ pub fn status ( & self ) -> & HashMap < String , String > {
405+ self . status . get_or_init ( || {
406+ self . inner_status
407+ . lines ( )
408+ . filter_map ( |it| it. split_once ( ':' ) )
409+ . map ( |it| ( it. 0 . to_string ( ) , it. 1 . trim_start ( ) . to_string ( ) ) )
410+ . collect :: < HashMap < _ , _ > > ( )
411+ } )
420412 }
421413
422414 /// Collect information from `/proc/<pid>/stat` file
423- pub fn stat ( & mut self ) -> Rc < Vec < String > > {
424- if let Some ( c) = & self . cached_stat {
425- return Rc :: clone ( c) ;
426- }
427-
428- let result: Vec < _ > = stat_split ( & self . inner_stat ) ;
429-
430- let result = Rc :: new ( result) ;
431- self . cached_stat = Some ( Rc :: clone ( & result) ) ;
432- Rc :: clone ( & result)
415+ pub fn stat ( & self ) -> & Vec < String > {
416+ self . stat . get_or_init ( || stat_split ( & self . inner_stat ) )
433417 }
434418
435419 pub fn name ( & mut self ) -> Result < String , io:: Error > {
@@ -615,13 +599,9 @@ impl ProcessInformation {
615599 Teletype :: Unknown
616600 }
617601
618- pub fn thread_ids ( & mut self ) -> Rc < Vec < usize > > {
619- if let Some ( c) = & self . cached_thread_ids {
620- return Rc :: clone ( c) ;
621- }
622-
623- let tids_dir = format ! ( "/proc/{}/task" , self . pid) ;
624- let result = Rc :: new (
602+ pub fn thread_ids ( & mut self ) -> & [ usize ] {
603+ self . thread_ids . get_or_init ( || {
604+ let tids_dir = format ! ( "/proc/{}/task" , self . pid) ;
625605 WalkDir :: new ( tids_dir)
626606 . min_depth ( 1 )
627607 . max_depth ( 1 )
@@ -633,11 +613,8 @@ impl ProcessInformation {
633613 . file_name ( )
634614 . map ( |it| it. to_str ( ) . unwrap ( ) . parse :: < usize > ( ) . unwrap ( ) )
635615 } )
636- . collect :: < Vec < _ > > ( ) ,
637- ) ;
638-
639- self . cached_thread_ids = Some ( Rc :: clone ( & result) ) ;
640- Rc :: clone ( & result)
616+ . collect :: < Vec < _ > > ( )
617+ } )
641618 }
642619
643620 pub fn env_vars ( & self ) -> Result < HashMap < String , String > , io:: Error > {
0 commit comments