@@ -10,15 +10,15 @@ use std::{
10
10
hash:: { Hash , Hasher } ,
11
11
num:: NonZeroUsize ,
12
12
ops:: Range ,
13
- sync:: Arc ,
13
+ sync:: { Arc , Mutex } ,
14
14
} ;
15
15
16
16
use async_trait:: async_trait;
17
17
use bytes:: Bytes ;
18
18
use clru:: { CLruCache , CLruCacheConfig , WeightScale } ;
19
19
use futures:: stream:: BoxStream ;
20
20
use snafu:: { OptionExt , Snafu } ;
21
- use tokio:: { io:: AsyncWrite , sync :: Mutex } ;
21
+ use tokio:: io:: AsyncWrite ;
22
22
use upstream:: { path:: Path , GetResult , ListResult , MultipartId , ObjectMeta , ObjectStore , Result } ;
23
23
24
24
use crate :: ObjectStoreRef ;
@@ -52,26 +52,26 @@ impl Partition {
52
52
}
53
53
54
54
impl Partition {
55
- async fn get ( & self , key : & str ) -> Option < Bytes > {
56
- let mut guard = self . inner . lock ( ) . await ;
55
+ fn get ( & self , key : & str ) -> Option < Bytes > {
56
+ let mut guard = self . inner . lock ( ) . unwrap ( ) ;
57
57
guard. get ( key) . cloned ( )
58
58
}
59
59
60
- async fn peek ( & self , key : & str ) -> Option < Bytes > {
60
+ fn peek ( & self , key : & str ) -> Option < Bytes > {
61
61
// FIXME: actually, here write lock is not necessary.
62
- let guard = self . inner . lock ( ) . await ;
62
+ let guard = self . inner . lock ( ) . unwrap ( ) ;
63
63
guard. peek ( key) . cloned ( )
64
64
}
65
65
66
- async fn insert ( & self , key : String , value : Bytes ) {
67
- let mut guard = self . inner . lock ( ) . await ;
66
+ fn insert ( & self , key : String , value : Bytes ) {
67
+ let mut guard = self . inner . lock ( ) . unwrap ( ) ;
68
68
// don't care error now.
69
69
_ = guard. put_with_weight ( key, value) ;
70
70
}
71
71
72
72
#[ cfg( test) ]
73
- async fn keys ( & self ) -> Vec < String > {
74
- let guard = self . inner . lock ( ) . await ;
73
+ fn keys ( & self ) -> Vec < String > {
74
+ let guard = self . inner . lock ( ) . unwrap ( ) ;
75
75
guard
76
76
. iter ( )
77
77
. map ( |( key, _) | key)
@@ -115,34 +115,31 @@ impl MemCache {
115
115
self . partitions [ hasher. finish ( ) as usize & self . partition_mask ] . clone ( )
116
116
}
117
117
118
- async fn get ( & self , key : & str ) -> Option < Bytes > {
118
+ fn get ( & self , key : & str ) -> Option < Bytes > {
119
119
let partition = self . locate_partition ( key) ;
120
- partition. get ( key) . await
120
+ partition. get ( key)
121
121
}
122
122
123
- async fn peek ( & self , key : & str ) -> Option < Bytes > {
123
+ fn peek ( & self , key : & str ) -> Option < Bytes > {
124
124
let partition = self . locate_partition ( key) ;
125
- partition. peek ( key) . await
125
+ partition. peek ( key)
126
126
}
127
127
128
- async fn insert ( & self , key : String , value : Bytes ) {
128
+ fn insert ( & self , key : String , value : Bytes ) {
129
129
let partition = self . locate_partition ( & key) ;
130
- partition. insert ( key, value) . await ;
130
+ partition. insert ( key, value) ;
131
131
}
132
132
133
+ /// Give a description of the cache state.
133
134
#[ cfg( test) ]
134
- async fn to_string ( & self ) -> String {
135
- futures:: future:: join_all (
136
- self . partitions
137
- . iter ( )
138
- . map ( |part| async { part. keys ( ) . await . join ( "," ) } ) ,
139
- )
140
- . await
141
- . into_iter ( )
142
- . enumerate ( )
143
- . map ( |( part_no, keys) | format ! ( "{part_no}: [{keys}]" ) )
144
- . collect :: < Vec < _ > > ( )
145
- . join ( "\n " )
135
+ fn state_desc ( & self ) -> String {
136
+ self . partitions
137
+ . iter ( )
138
+ . map ( |part| part. keys ( ) . join ( "," ) )
139
+ . enumerate ( )
140
+ . map ( |( part_no, keys) | format ! ( "{part_no}: [{keys}]" ) )
141
+ . collect :: < Vec < _ > > ( )
142
+ . join ( "\n " )
146
143
}
147
144
}
148
145
@@ -195,21 +192,21 @@ impl MemCacheStore {
195
192
// TODO(chenxiang): What if there are some overlapping range in cache?
196
193
// A request with range [5, 10) can also use [0, 20) cache
197
194
let cache_key = Self :: cache_key ( location, & range) ;
198
- if let Some ( bytes) = self . cache . get ( & cache_key) . await {
195
+ if let Some ( bytes) = self . cache . get ( & cache_key) {
199
196
return Ok ( bytes) ;
200
197
}
201
198
202
199
// TODO(chenxiang): What if two threads reach here? It's better to
203
200
// pend one thread, and only let one to fetch data from underlying store.
204
201
let bytes = self . underlying_store . get_range ( location, range) . await ?;
205
- self . cache . insert ( cache_key, bytes. clone ( ) ) . await ;
202
+ self . cache . insert ( cache_key, bytes. clone ( ) ) ;
206
203
207
204
Ok ( bytes)
208
205
}
209
206
210
207
async fn get_range_with_ro_cache ( & self , location : & Path , range : Range < usize > ) -> Result < Bytes > {
211
208
let cache_key = Self :: cache_key ( location, & range) ;
212
- if let Some ( bytes) = self . cache . peek ( & cache_key) . await {
209
+ if let Some ( bytes) = self . cache . peek ( & cache_key) {
213
210
return Ok ( bytes) ;
214
211
}
215
212
@@ -297,7 +294,7 @@ mod test {
297
294
298
295
use super :: * ;
299
296
300
- async fn prepare_store ( bits : usize , mem_cap : usize ) -> MemCacheStore {
297
+ fn prepare_store ( bits : usize , mem_cap : usize ) -> MemCacheStore {
301
298
let local_path = tempdir ( ) . unwrap ( ) ;
302
299
let local_store = Arc :: new ( LocalFileSystem :: new_with_prefix ( local_path. path ( ) ) . unwrap ( ) ) ;
303
300
@@ -309,7 +306,7 @@ mod test {
309
306
#[ tokio:: test]
310
307
async fn test_mem_cache_evict ( ) {
311
308
// single partition
312
- let store = prepare_store ( 0 , 13 ) . await ;
309
+ let store = prepare_store ( 0 , 13 ) ;
313
310
314
311
// write date
315
312
let location = Path :: from ( "1.sst" ) ;
@@ -324,7 +321,6 @@ mod test {
324
321
assert ! ( store
325
322
. cache
326
323
. get( & MemCacheStore :: cache_key( & location, & range0_5) )
327
- . await
328
324
. is_some( ) ) ;
329
325
330
326
// get bytes from [5, 10), insert to cache
@@ -333,12 +329,10 @@ mod test {
333
329
assert ! ( store
334
330
. cache
335
331
. get( & MemCacheStore :: cache_key( & location, & range0_5) )
336
- . await
337
332
. is_some( ) ) ;
338
333
assert ! ( store
339
334
. cache
340
335
. get( & MemCacheStore :: cache_key( & location, & range5_10) )
341
- . await
342
336
. is_some( ) ) ;
343
337
344
338
// get bytes from [10, 15), insert to cache
@@ -351,24 +345,21 @@ mod test {
351
345
assert ! ( store
352
346
. cache
353
347
. get( & MemCacheStore :: cache_key( & location, & range0_5) )
354
- . await
355
348
. is_none( ) ) ;
356
349
assert ! ( store
357
350
. cache
358
351
. get( & MemCacheStore :: cache_key( & location, & range5_10) )
359
- . await
360
352
. is_some( ) ) ;
361
353
assert ! ( store
362
354
. cache
363
355
. get( & MemCacheStore :: cache_key( & location, & range10_15) )
364
- . await
365
356
. is_some( ) ) ;
366
357
}
367
358
368
359
#[ tokio:: test]
369
360
async fn test_mem_cache_partition ( ) {
370
361
// 4 partitions
371
- let store = prepare_store ( 2 , 100 ) . await ;
362
+ let store = prepare_store ( 2 , 100 ) ;
372
363
let location = Path :: from ( "partition.sst" ) ;
373
364
store
374
365
. put ( & location, Bytes :: from_static ( & [ 1 ; 1024 ] ) )
@@ -388,18 +379,16 @@ mod test {
388
379
1: [partition.sst-100-105]
389
380
2: []
390
381
3: [partition.sst-0-5]"# ,
391
- store. cache. as_ref( ) . to_string ( ) . await
382
+ store. cache. as_ref( ) . state_desc ( )
392
383
) ;
393
384
394
385
assert ! ( store
395
386
. cache
396
387
. get( & MemCacheStore :: cache_key( & location, & range0_5) )
397
- . await
398
388
. is_some( ) ) ;
399
389
assert ! ( store
400
390
. cache
401
391
. get( & MemCacheStore :: cache_key( & location, & range100_105) )
402
- . await
403
392
. is_some( ) ) ;
404
393
}
405
394
}
0 commit comments