@@ -17,11 +17,23 @@ async fn tempfile(dir: &path::Path) -> Result<(afs::File, path::PathBuf)> {
17
17
Ok ( ( tmp, tmppath) )
18
18
}
19
19
20
+ #[ derive( Debug , Clone ) ]
21
+ pub ( crate ) struct Options {
22
+ pub ( crate ) path : path:: PathBuf ,
23
+ pub ( crate ) dir_depth : u8 ,
24
+ // TODO: implement below option
25
+ pub ( crate ) save_last_access : bool ,
26
+
27
+ // read and write buffer sizes
28
+ pub ( crate ) rbuff_sz : usize ,
29
+ pub ( crate ) wbuff_sz : usize ,
30
+ }
31
+
20
32
/// The main component of `forceps`, acts as the API for interacting with the on-disk API.
21
33
///
22
34
/// This structure exposes `read`, `write`, and misc metadata operations. `read` and `write` are
23
35
/// both async, whereas all metadata operations are sync. To create this structure, use the
24
- /// [`CacheBuilder`].
36
+ /// [`CacheBuilder`](crate::CacheBuilder) .
25
37
///
26
38
/// # Examples
27
39
///
@@ -39,48 +51,33 @@ async fn tempfile(dir: &path::Path) -> Result<(afs::File, path::PathBuf)> {
39
51
#[ derive( Debug ) ]
40
52
pub struct Cache {
41
53
meta : MetaDb ,
42
- path : path:: PathBuf ,
43
- }
44
-
45
- /// A builder for the [`Cache`] object. Exposes APIs for configuring the initial setup of the
46
- /// database.
47
- ///
48
- /// # Examples
49
- ///
50
- /// ```rust
51
- /// use forceps::CacheBuilder;
52
- ///
53
- /// let builder = CacheBuilder::new("./cache");
54
- /// ```
55
- #[ derive( Debug , Clone ) ]
56
- pub struct CacheBuilder {
57
- path : path:: PathBuf ,
54
+ opts : Options ,
58
55
}
59
56
60
57
impl Cache {
61
58
/// Creates a new Cache instance based on the CacheBuilder
62
- async fn new ( builder : CacheBuilder ) -> Result < Self > {
59
+ pub ( crate ) async fn create ( opts : Options ) -> Result < Self > {
63
60
// create the base directory for the cache
64
- afs:: create_dir_all ( & builder . path )
61
+ afs:: create_dir_all ( & opts . path )
65
62
. await
66
63
. map_err ( ForcepError :: Io ) ?;
67
64
68
- let mut meta_path = builder . path . clone ( ) ;
65
+ let mut meta_path = opts . path . clone ( ) ;
69
66
meta_path. push ( "index" ) ;
70
67
Ok ( Self {
71
68
meta : MetaDb :: new ( & meta_path) ?,
72
- path : builder . path ,
69
+ opts ,
73
70
} )
74
71
}
75
72
76
73
/// Creates a PathBuf based on the key provided
77
74
fn path_from_key ( & self , key : & [ u8 ] ) -> path:: PathBuf {
78
75
let hex = hex:: encode ( key) ;
79
- let mut buf = self . path . clone ( ) ;
76
+ let mut buf = self . opts . path . clone ( ) ;
80
77
81
78
// push segments of key as paths to the PathBuf. If the hex isn't long enough, then push
82
79
// "__" instead.
83
- for n in ( 0 ..4usize ) . step_by ( 2 ) {
80
+ for n in ( 0 ..self . opts . dir_depth ) . map ( |x| x as usize * 2 ) {
84
81
let n_end = n + 2 ;
85
82
buf. push ( if n_end >= hex. len ( ) {
86
83
"__"
@@ -136,7 +133,7 @@ impl Cache {
136
133
let mut buf = Vec :: with_capacity ( size_guess as usize ) ;
137
134
138
135
// read the entire file to the buffer
139
- tokio:: io:: BufReader :: new ( file)
136
+ tokio:: io:: BufReader :: with_capacity ( self . opts . rbuff_sz , file)
140
137
. read_to_end ( & mut buf)
141
138
. await
142
139
. map_err ( ForcepError :: Io ) ?;
@@ -170,10 +167,10 @@ impl Cache {
170
167
let key = key. as_ref ( ) ;
171
168
let value = value. as_ref ( ) ;
172
169
173
- let ( tmp, tmp_path) = tempfile ( & self . path ) . await ?;
170
+ let ( tmp, tmp_path) = tempfile ( & self . opts . path ) . await ?;
174
171
// write all data to a temporary file
175
172
{
176
- let mut writer = tokio:: io:: BufWriter :: new ( tmp) ;
173
+ let mut writer = tokio:: io:: BufWriter :: with_capacity ( self . opts . wbuff_sz , tmp) ;
177
174
writer. write_all ( value) . await . map_err ( ForcepError :: Io ) ?;
178
175
writer. flush ( ) . await . map_err ( ForcepError :: Io ) ?;
179
176
}
@@ -217,7 +214,7 @@ impl Cache {
217
214
let key = key. as_ref ( ) ;
218
215
219
216
let cur_path = self . path_from_key ( key) ;
220
- let tmp_path = crate :: tmp:: tmppath_in ( & self . path ) ;
217
+ let tmp_path = crate :: tmp:: tmppath_in ( & self . opts . path ) ;
221
218
222
219
// move then delete the file
223
220
//
@@ -306,71 +303,10 @@ impl Cache {
306
303
}
307
304
}
308
305
309
- impl CacheBuilder {
310
- /// Creates a new [`CacheBuilder`], which can be used to customize and create a [`Cache`]
311
- /// instance.
312
- ///
313
- /// The `path` supplied is the base directory of the cache instance.
314
- ///
315
- /// # Examples
316
- ///
317
- /// ```rust
318
- /// use forceps::CacheBuilder;
319
- ///
320
- /// let builder = CacheBuilder::new("./cache");
321
- /// // Use other methods for configuration
322
- /// ```
323
- pub fn new < P : AsRef < path:: Path > > ( path : P ) -> Self {
324
- CacheBuilder {
325
- path : path. as_ref ( ) . to_owned ( ) ,
326
- }
327
- }
328
-
329
- /// Builds the new [`Cache`] instance using the configured options of the builder.
330
- ///
331
- /// # Examples
332
- ///
333
- /// ```rust
334
- /// # #[tokio::main(flavor = "current_thread")]
335
- /// # async fn main() {
336
- /// use forceps::CacheBuilder;
337
- ///
338
- /// let cache = CacheBuilder::new("./cache")
339
- /// .build()
340
- /// .await
341
- /// .unwrap();
342
- /// # }
343
- /// ```
344
- pub async fn build ( self ) -> Result < Cache > {
345
- Cache :: new ( self ) . await
346
- }
347
- }
348
-
349
- impl Default for CacheBuilder {
350
- /// Creates a [`CacheBuilder`] with the directory set to `./cache`.
351
- ///
352
- /// # Examples
353
- ///
354
- /// ```rust
355
- /// # #[tokio::main(flavor = "current_thread")]
356
- /// # async fn main() {
357
- /// use forceps::CacheBuilder;
358
- ///
359
- /// let cache = CacheBuilder::default()
360
- /// .build()
361
- /// .await
362
- /// .unwrap();
363
- /// # }
364
- /// ```
365
- fn default ( ) -> Self {
366
- const DIR : & str = "./cache" ;
367
- Self :: new ( DIR )
368
- }
369
- }
370
-
371
306
#[ cfg( test) ]
372
307
mod test {
373
308
use super :: * ;
309
+ use crate :: CacheBuilder ;
374
310
375
311
async fn default_cache ( ) -> Cache {
376
312
CacheBuilder :: default ( ) . build ( ) . await . unwrap ( )
0 commit comments