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
@@ -346,7 +345,7 @@ impl Namespace {
346345}
347346
348347/// Process ID and its information
349- #[ derive( Debug , Clone , Default , PartialEq , Eq ) ]
348+ #[ derive( Debug , Clone , Default ) ]
350349pub struct ProcessInformation {
351350 pub pid : usize ,
352351 pub cmdline : String ,
@@ -355,13 +354,13 @@ pub struct ProcessInformation {
355354 inner_stat : String ,
356355
357356 /// Processed `/proc/self/status` file
358- cached_status : Option < Rc < HashMap < String , String > > > ,
357+ status : OnceLock < HashMap < String , String > > ,
359358 /// Processed `/proc/self/stat` file
360- cached_stat : Option < Rc < Vec < String > > > ,
359+ stat : OnceLock < Vec < String > > ,
361360
362361 cached_start_time : Option < u64 > ,
363362
364- cached_thread_ids : Option < Rc < Vec < usize > > > ,
363+ thread_ids : OnceLock < Vec < usize > > ,
365364}
366365
367366impl ProcessInformation {
@@ -429,34 +428,19 @@ impl ProcessInformation {
429428 }
430429
431430 /// Collect information from `/proc/<pid>/status` file
432- pub fn status ( & mut self ) -> Rc < HashMap < String , String > > {
433- if let Some ( c) = & self . cached_status {
434- return Rc :: clone ( c) ;
435- }
436-
437- let result = self
438- . inner_status
439- . lines ( )
440- . filter_map ( |it| it. split_once ( ':' ) )
441- . map ( |it| ( it. 0 . to_string ( ) , it. 1 . trim_start ( ) . to_string ( ) ) )
442- . collect :: < HashMap < _ , _ > > ( ) ;
443-
444- let result = Rc :: new ( result) ;
445- self . cached_status = Some ( Rc :: clone ( & result) ) ;
446- Rc :: clone ( & result)
431+ pub fn status ( & self ) -> & HashMap < String , String > {
432+ self . status . get_or_init ( || {
433+ self . inner_status
434+ . lines ( )
435+ . filter_map ( |it| it. split_once ( ':' ) )
436+ . map ( |it| ( it. 0 . to_string ( ) , it. 1 . trim_start ( ) . to_string ( ) ) )
437+ . collect :: < HashMap < _ , _ > > ( )
438+ } )
447439 }
448440
449441 /// Collect information from `/proc/<pid>/stat` file
450- pub fn stat ( & mut self ) -> Rc < Vec < String > > {
451- if let Some ( c) = & self . cached_stat {
452- return Rc :: clone ( c) ;
453- }
454-
455- let result: Vec < _ > = stat_split ( & self . inner_stat ) ;
456-
457- let result = Rc :: new ( result) ;
458- self . cached_stat = Some ( Rc :: clone ( & result) ) ;
459- Rc :: clone ( & result)
442+ pub fn stat ( & self ) -> & Vec < String > {
443+ self . stat . get_or_init ( || stat_split ( & self . inner_stat ) )
460444 }
461445
462446 pub fn name ( & mut self ) -> Result < String , io:: Error > {
@@ -642,13 +626,9 @@ impl ProcessInformation {
642626 Teletype :: Unknown
643627 }
644628
645- pub fn thread_ids ( & mut self ) -> Rc < Vec < usize > > {
646- if let Some ( c) = & self . cached_thread_ids {
647- return Rc :: clone ( c) ;
648- }
649-
650- let tids_dir = format ! ( "/proc/{}/task" , self . pid) ;
651- let result = Rc :: new (
629+ pub fn thread_ids ( & mut self ) -> & [ usize ] {
630+ self . thread_ids . get_or_init ( || {
631+ let tids_dir = format ! ( "/proc/{}/task" , self . pid) ;
652632 WalkDir :: new ( tids_dir)
653633 . min_depth ( 1 )
654634 . max_depth ( 1 )
@@ -660,11 +640,8 @@ impl ProcessInformation {
660640 . file_name ( )
661641 . map ( |it| it. to_str ( ) . unwrap ( ) . parse :: < usize > ( ) . unwrap ( ) )
662642 } )
663- . collect :: < Vec < _ > > ( ) ,
664- ) ;
665-
666- self . cached_thread_ids = Some ( Rc :: clone ( & result) ) ;
667- Rc :: clone ( & result)
643+ . collect :: < Vec < _ > > ( )
644+ } )
668645 }
669646
670647 pub fn env_vars ( & self ) -> Result < HashMap < String , String > , io:: Error > {
0 commit comments