11//! Memory-mapped file.
22
3- use core:: fmt;
43use std:: {
54 path:: Path ,
6- sync:: {
7- atomic:: { AtomicU64 , Ordering } ,
8- Arc ,
9- } ,
5+ sync:: { Arc , RwLock } ,
106} ;
117
128use fmmap:: { MmapFile , MmapFileExt } ;
139use once_cell:: sync:: Lazy ;
14- use serde:: { ser :: SerializeStruct , Serialize , Serializer } ;
10+ use serde:: Serialize ;
1511
1612/// Memory-mapped file.
1713pub struct MemoryMapFile {
@@ -20,111 +16,94 @@ pub struct MemoryMapFile {
2016 /// The size of the memory-mapped file.
2117 size : u64 ,
2218}
19+
2320/// Global statistic for memory-mapped files.
24- static MEMMAP_FILE_STATS : Lazy < MemMapFileStat > = Lazy :: new ( MemMapFileStat :: default) ;
21+ static MEMMAP_FILE_STATS : Lazy < Arc < RwLock < MemMapFileStat > > > =
22+ Lazy :: new ( || Arc :: new ( RwLock :: new ( MemMapFileStat :: default ( ) ) ) ) ;
2523
2624/// Memory-mapped file statistic.
2725#[ derive( Debug , Default , Clone , Serialize ) ]
28- pub struct MemMapFileStat ( Arc < MemMapFileStatInner > ) ;
29-
30- /// Internal structure to hold stats.
31- struct MemMapFileStatInner {
26+ pub struct MemMapFileStat {
3227 /// A counter for the number of memory-mapped files.
33- file_count : AtomicU64 ,
28+ file_count : u64 ,
3429 /// The total size of memory-mapped files.
35- total_size : AtomicU64 ,
30+ total_size : u64 ,
3631 /// The amount of time that memory-mapped files have been dropped.
37- drop_count : AtomicU64 ,
32+ drop_count : u64 ,
3833 /// The total size of memory-mapped files that have been dropped.
39- drop_size : AtomicU64 ,
34+ drop_size : u64 ,
4035 /// A count of errors encountered.
41- error_count : AtomicU64 ,
36+ error_count : u64 ,
4237}
4338
4439impl MemMapFileStat {
4540 /// Get the statistic file count.
4641 #[ must_use]
4742 pub fn file_count ( & self ) -> u64 {
48- self . 0 . file_count . load ( Ordering :: SeqCst )
43+ self . file_count
4944 }
5045
5146 /// Get the statistic total size.
5247 #[ must_use]
5348 pub fn total_size ( & self ) -> u64 {
54- self . 0 . total_size . load ( Ordering :: SeqCst )
49+ self . total_size
5550 }
5651
5752 /// Get the statistic drop count.
5853 #[ must_use]
5954 pub fn drop_count ( & self ) -> u64 {
60- self . 0 . drop_count . load ( Ordering :: SeqCst )
55+ self . drop_count
6156 }
6257
6358 /// Get the statistic drop size.
6459 #[ must_use]
6560 pub fn drop_size ( & self ) -> u64 {
66- self . 0 . drop_size . load ( Ordering :: SeqCst )
61+ self . drop_size
6762 }
6863
6964 /// Get the statistic error count.
7065 #[ must_use]
7166 pub fn error_count ( & self ) -> u64 {
72- self . 0 . error_count . load ( Ordering :: SeqCst )
67+ self . error_count
7368 }
7469}
7570
7671impl MemoryMapFile {
77- /// Get the memory-mapped file.
78- pub fn file ( & self ) -> & MmapFile {
79- & self . file
80- }
81-
8272 /// Get the memory-mapped file as a slice.
83- pub fn file_as_slice ( & self ) -> & [ u8 ] {
84- self . file ( ) . as_slice ( )
85- }
86-
87- /// Get the size of the memory-mapped file.
88- pub fn size ( & self ) -> u64 {
89- self . size
73+ pub fn as_slice ( & self ) -> & [ u8 ] {
74+ self . file . as_slice ( )
9075 }
9176
9277 /// Get the global memory-mapped file statistics.
93- #[ must_use]
94- pub fn stat ( ) -> & ' static MemMapFileStat {
95- & MEMMAP_FILE_STATS
78+ pub fn stat ( ) -> Option < MemMapFileStat > {
79+ if let Ok ( stat) = MEMMAP_FILE_STATS . read ( ) {
80+ Some ( stat. clone ( ) )
81+ } else {
82+ None
83+ }
9684 }
9785
9886 /// Update the global stats when a file is created.
9987 fn update_create_stat ( & self ) {
100- MEMMAP_FILE_STATS
101- . 0
102- . file_count
103- . fetch_add ( 1 , Ordering :: SeqCst ) ;
104- MEMMAP_FILE_STATS
105- . 0
106- . total_size
107- . fetch_add ( self . size , Ordering :: SeqCst ) ;
88+ if let Ok ( mut stat) = MEMMAP_FILE_STATS . write ( ) {
89+ stat. file_count += 1 ;
90+ stat. total_size += self . size ;
91+ }
10892 }
10993
11094 /// Update the global stats when a file is dropped.
11195 fn update_drop_stat ( & self ) {
112- MEMMAP_FILE_STATS
113- . 0
114- . drop_count
115- . fetch_add ( 1 , Ordering :: SeqCst ) ;
116- MEMMAP_FILE_STATS
117- . 0
118- . drop_size
119- . fetch_add ( self . size , Ordering :: SeqCst ) ;
96+ if let Ok ( mut stat) = MEMMAP_FILE_STATS . write ( ) {
97+ stat. drop_count += 1 ;
98+ stat. drop_size += self . size ;
99+ }
120100 }
121101
122102 /// Update the global error count when an error occurs.
123103 pub fn update_err_stat ( ) {
124- MEMMAP_FILE_STATS
125- . 0
126- . error_count
127- . fetch_add ( 1 , Ordering :: SeqCst ) ;
104+ if let Ok ( mut stat) = MEMMAP_FILE_STATS . write ( ) {
105+ stat. error_count += 1 ;
106+ }
128107 }
129108}
130109
@@ -153,41 +132,3 @@ impl TryFrom<&Path> for MemoryMapFile {
153132 }
154133 }
155134}
156-
157- impl Default for MemMapFileStatInner {
158- fn default ( ) -> Self {
159- Self {
160- file_count : AtomicU64 :: new ( 0 ) ,
161- total_size : AtomicU64 :: new ( 0 ) ,
162- drop_count : AtomicU64 :: new ( 0 ) ,
163- drop_size : AtomicU64 :: new ( 0 ) ,
164- error_count : AtomicU64 :: new ( 0 ) ,
165- }
166- }
167- }
168-
169- impl fmt:: Debug for MemMapFileStatInner {
170- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
171- f. debug_struct ( "MemMapFileStat" )
172- . field ( "file_count" , & self . file_count . load ( Ordering :: SeqCst ) )
173- . field ( "total_size" , & self . total_size . load ( Ordering :: SeqCst ) )
174- . field ( "drop_count" , & self . drop_count . load ( Ordering :: SeqCst ) )
175- . field ( "drop_size" , & self . drop_size . load ( Ordering :: SeqCst ) )
176- . field ( "error_count" , & self . error_count . load ( Ordering :: SeqCst ) )
177- . finish ( )
178- }
179- }
180-
181- impl Serialize for MemMapFileStatInner {
182- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
183- where S : Serializer {
184- let mut state = serializer. serialize_struct ( "MemMapFileStat" , 5 ) ?;
185-
186- state. serialize_field ( "file_count" , & self . file_count . load ( Ordering :: SeqCst ) ) ?;
187- state. serialize_field ( "total_size" , & self . total_size . load ( Ordering :: SeqCst ) ) ?;
188- state. serialize_field ( "drop_count" , & self . drop_count . load ( Ordering :: SeqCst ) ) ?;
189- state. serialize_field ( "drop_size" , & self . drop_size . load ( Ordering :: SeqCst ) ) ?;
190- state. serialize_field ( "error_count" , & self . error_count . load ( Ordering :: SeqCst ) ) ?;
191- state. end ( )
192- }
193- }
0 commit comments