@@ -6,6 +6,7 @@ use std::collections::HashMap;
6
6
use std:: fs;
7
7
use std:: io:: { BufReader , Read , Write } ;
8
8
use std:: path:: { Path , PathBuf } ;
9
+ use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
9
10
use std:: sync:: { Arc , Mutex , RwLock } ;
10
11
11
12
#[ cfg( not( target_os = "windows" ) ) ]
@@ -33,14 +34,16 @@ fn path_to_windows_str<T: AsRef<OsStr>>(path: T) -> Vec<u16> {
33
34
/// A [`KVStore`] implementation that writes to and reads from the file system.
34
35
pub struct FilesystemStore {
35
36
data_dir : PathBuf ,
37
+ tmp_file_counter : AtomicUsize ,
36
38
locks : Mutex < HashMap < ( String , String ) , Arc < RwLock < ( ) > > > > ,
37
39
}
38
40
39
41
impl FilesystemStore {
40
42
/// Constructs a new [`FilesystemStore`].
41
43
pub fn new ( data_dir : PathBuf ) -> Self {
42
44
let locks = Mutex :: new ( HashMap :: new ( ) ) ;
43
- Self { data_dir, locks }
45
+ let tmp_file_counter = AtomicUsize :: new ( 0 ) ;
46
+ Self { data_dir, tmp_file_counter, locks }
44
47
}
45
48
46
49
/// Returns the data directory.
@@ -119,7 +122,8 @@ impl KVStore for FilesystemStore {
119
122
// The way to atomically write a file on Unix platforms is:
120
123
// open(tmpname), write(tmpfile), fsync(tmpfile), close(tmpfile), rename(), fsync(dir)
121
124
let mut tmp_file_path = dest_file_path. clone ( ) ;
122
- tmp_file_path. set_extension ( "tmp" ) ;
125
+ let tmp_file_ext = format ! ( "{}.tmp" , self . tmp_file_counter. fetch_add( 1 , Ordering :: AcqRel ) ) ;
126
+ tmp_file_path. set_extension ( tmp_file_ext) ;
123
127
124
128
{
125
129
let mut tmp_file = fs:: File :: create ( & tmp_file_path) ?;
0 commit comments