@@ -66,19 +66,43 @@ use error::ErrorKind;
6666/// half finished snapshot file. Deleting the inputs after the rename means that
6767/// the worst case is that we have some leftover incremental files which will
6868/// be deleted on the next compaction.
69+ #[ derive( Debug ) ]
6970pub struct FsStore {
7071 root : std:: path:: PathBuf ,
72+ tmpdir : std:: path:: PathBuf ,
7173}
7274
7375impl FsStore {
74- /// Create an [`FsStore`] from a [`std::path::PathBuf`]
76+ /// Creates a new [`FsStore`] from a [`Path`].
7577 ///
7678 /// This will attempt to create the root directory and throw an error if
7779 /// it does not exist.
7880 pub fn open < P : AsRef < Path > > ( root : P ) -> Result < Self , std:: io:: Error > {
79- std:: fs:: create_dir_all ( root. as_ref ( ) ) ?;
81+ let root = root. as_ref ( ) ;
82+ std:: fs:: create_dir_all ( root) ?;
8083 Ok ( Self {
81- root : root. as_ref ( ) . into ( ) ,
84+ root : root. into ( ) ,
85+ tmpdir : root. into ( ) ,
86+ } )
87+ }
88+
89+ /// Overrides the tmpdir directory used for temporary files.
90+ ///
91+ /// The default is to use the root directory passed to [`FsStore::open`].
92+ ///
93+ /// The tmpdir used must be on the same mount point as the root directory,
94+ /// otherwise the store will throw an error on writing data.
95+ ///
96+ /// # Errors
97+ ///
98+ /// This will attempt to create the tmpdir directory and throw an error if
99+ /// it does not exist.
100+ pub fn with_tmpdir < P : AsRef < Path > > ( self , tmpdir : P ) -> Result < Self , std:: io:: Error > {
101+ let tmpdir = tmpdir. as_ref ( ) ;
102+ std:: fs:: create_dir_all ( tmpdir) ?;
103+ Ok ( Self {
104+ tmpdir : tmpdir. into ( ) ,
105+ ..self
82106 } )
83107 }
84108
@@ -151,7 +175,7 @@ impl FsStore {
151175 } ) ?;
152176
153177 let chunk_name = SavedChunkName :: new_incremental ( changes) ;
154- write_chunk ( & self . root , & paths, changes, chunk_name) ?;
178+ write_chunk ( & self . root , & paths, changes, chunk_name, & self . tmpdir ) ?;
155179
156180 Ok ( ( ) )
157181 }
@@ -171,7 +195,7 @@ impl FsStore {
171195 // Write the snapshot
172196 let output_chunk_name = SavedChunkName :: new_snapshot ( doc. get_heads ( ) ) ;
173197 let chunk = doc. save ( ) ;
174- write_chunk ( & self . root , & paths, & chunk, output_chunk_name) ?;
198+ write_chunk ( & self . root , & paths, & chunk, output_chunk_name, & self . tmpdir ) ?;
175199
176200 // Remove all the old data
177201 for incremental in chunks. incrementals . keys ( ) {
@@ -191,10 +215,11 @@ fn write_chunk(
191215 paths : & DocIdPaths ,
192216 chunk : & [ u8 ] ,
193217 name : SavedChunkName ,
218+ tmpdir : & Path ,
194219) -> Result < ( ) , Error > {
195220 // Write to a temp file and then rename to avoid partial writes
196221 let temp_dir =
197- tempfile:: TempDir :: new_in ( root ) . map_err ( |e| Error ( ErrorKind :: CreateTempFile ( e) ) ) ?;
222+ tempfile:: TempDir :: new_in ( tmpdir ) . map_err ( |e| Error ( ErrorKind :: CreateTempFile ( e) ) ) ?;
198223 let temp_save_path = temp_dir. path ( ) . join ( name. filename ( ) ) ;
199224 let mut temp_save_file =
200225 File :: create ( & temp_save_path) . map_err ( |e| Error ( ErrorKind :: CreateTempFile ( e) ) ) ?;
0 commit comments