1
1
use criterion:: { criterion_group, criterion_main, Criterion } ;
2
2
use rand:: { Rng , RngCore } ;
3
- use std:: sync:: Arc ;
3
+ use std:: {
4
+ collections:: BTreeMap ,
5
+ sync:: { Arc , RwLock } ,
6
+ } ;
4
7
use value_log:: {
5
- BlobCache , Compressor , Config , IndexReader , IndexWriter , MockIndex , MockIndexWriter , ValueLog ,
8
+ BlobCache , Compressor , Config , IndexReader , IndexWriter , UserKey , UserValue , ValueHandle ,
9
+ ValueLog , ValueLogId ,
6
10
} ;
7
11
12
+ type MockIndexInner = RwLock < BTreeMap < UserKey , ( ValueHandle , u32 ) > > ;
13
+
14
+ /// Mock in-memory index
15
+ #[ allow( clippy:: module_name_repetitions) ]
16
+ #[ derive( Clone , Default ) ]
17
+ pub struct MockIndex ( Arc < MockIndexInner > ) ;
18
+
19
+ impl std:: ops:: Deref for MockIndex {
20
+ type Target = MockIndexInner ;
21
+
22
+ fn deref ( & self ) -> & Self :: Target {
23
+ & self . 0
24
+ }
25
+ }
26
+
27
+ impl MockIndex {
28
+ /// Remove item
29
+ pub fn remove ( & self , key : & [ u8 ] ) {
30
+ self . 0 . write ( ) . expect ( "lock is poisoned" ) . remove ( key) ;
31
+ }
32
+ }
33
+
34
+ impl IndexReader for MockIndex {
35
+ fn get ( & self , key : & [ u8 ] ) -> std:: io:: Result < Option < ValueHandle > > {
36
+ Ok ( self
37
+ . read ( )
38
+ . expect ( "lock is poisoned" )
39
+ . get ( key)
40
+ . map ( |( vhandle, _) | vhandle)
41
+ . cloned ( ) )
42
+ }
43
+ }
44
+
45
+ /// Used for tests only
46
+ #[ allow( clippy:: module_name_repetitions) ]
47
+ pub struct MockIndexWriter ( pub MockIndex ) ;
48
+
49
+ impl IndexWriter for MockIndexWriter {
50
+ fn insert_indirect (
51
+ & mut self ,
52
+ key : & [ u8 ] ,
53
+ value : ValueHandle ,
54
+ size : u32 ,
55
+ ) -> std:: io:: Result < ( ) > {
56
+ self . 0
57
+ . write ( )
58
+ . expect ( "lock is poisoned" )
59
+ . insert ( key. into ( ) , ( value, size) ) ;
60
+ Ok ( ( ) )
61
+ }
62
+
63
+ fn finish ( & mut self ) -> std:: io:: Result < ( ) > {
64
+ Ok ( ( ) )
65
+ }
66
+ }
67
+
8
68
#[ derive( Clone , Default ) ]
9
69
struct NoCompressor ;
10
70
@@ -18,6 +78,17 @@ impl Compressor for NoCompressor {
18
78
}
19
79
}
20
80
81
+ #[ derive( Clone ) ]
82
+ struct NoCacher ;
83
+
84
+ impl BlobCache for NoCacher {
85
+ fn get ( & self , _: ValueLogId , _: & ValueHandle ) -> Option < UserValue > {
86
+ None
87
+ }
88
+
89
+ fn insert ( & self , _: ValueLogId , _: & ValueHandle , _: UserValue ) { }
90
+ }
91
+
21
92
fn prefetch ( c : & mut Criterion ) {
22
93
let mut group = c. benchmark_group ( "prefetch range" ) ;
23
94
@@ -30,11 +101,11 @@ fn prefetch(c: &mut Criterion) {
30
101
let folder = tempfile:: tempdir ( ) . unwrap ( ) ;
31
102
let vl_path = folder. path ( ) ;
32
103
33
- let value_log = ValueLog :: open ( vl_path, Config :: < NoCompressor > :: default ( ) ) . unwrap ( ) ;
104
+ let value_log = ValueLog :: open ( vl_path, Config :: < _ , NoCompressor > :: new ( NoCacher ) ) . unwrap ( ) ;
34
105
35
106
let mut writer = value_log. get_writer ( ) . unwrap ( ) ;
36
107
37
- let mut rng = rand:: thread_rng ( ) ;
108
+ let mut rng: rand :: prelude :: ThreadRng = rand:: rng ( ) ;
38
109
39
110
for key in ( 0u64 ..2_000_000 ) . map ( u64:: to_be_bytes) {
40
111
let mut data = vec ! [ 0u8 ; item_size] ;
@@ -51,11 +122,11 @@ fn prefetch(c: &mut Criterion) {
51
122
52
123
value_log. register_writer ( writer) . unwrap ( ) ;
53
124
54
- let mut rng = rand:: thread_rng ( ) ;
125
+ let mut rng = rand:: rng ( ) ;
55
126
56
127
group. bench_function ( format ! ( "{range_size}x{item_size}B - no prefetch" ) , |b| {
57
128
b. iter ( || {
58
- let start = rng. gen_range ( 0u64 ..1_999_000 ) ;
129
+ let start = rng. random_range ( 0u64 ..1_999_000 ) ;
59
130
60
131
for x in start..( start + range_size) {
61
132
let vhandle = index. get ( & x. to_be_bytes ( ) ) . unwrap ( ) . unwrap ( ) ;
@@ -67,7 +138,7 @@ fn prefetch(c: &mut Criterion) {
67
138
68
139
group. bench_function ( format ! ( "{range_size}x{item_size}B - with prefetch" ) , |b| {
69
140
b. iter ( || {
70
- let start = rng. gen_range ( 0u64 ..1_999_000 ) ;
141
+ let start = rng. random_range ( 0u64 ..1_999_000 ) ;
71
142
72
143
{
73
144
let vhandle = index. get ( & start. to_be_bytes ( ) ) . unwrap ( ) . unwrap ( ) ;
@@ -113,65 +184,11 @@ fn load_value(c: &mut Criterion) {
113
184
let folder = tempfile:: tempdir ( ) . unwrap ( ) ;
114
185
let vl_path = folder. path ( ) ;
115
186
116
- let value_log = ValueLog :: open (
117
- vl_path,
118
- Config :: < NoCompressor > :: default ( )
119
- . blob_cache ( Arc :: new ( BlobCache :: with_capacity_bytes ( 0 ) ) ) ,
120
- )
121
- . unwrap ( ) ;
122
-
123
- let mut writer = value_log. get_writer ( ) . unwrap ( ) ;
124
-
125
- let mut rng = rand:: thread_rng ( ) ;
126
-
127
- for size in sizes {
128
- let key = size. to_string ( ) ;
129
-
130
- let mut data = vec ! [ 0u8 ; size] ;
131
- rng. fill_bytes ( & mut data) ;
132
-
133
- index_writer
134
- . insert_indirect (
135
- key. as_bytes ( ) ,
136
- writer. get_next_value_handle ( ) ,
137
- data. len ( ) as u32 ,
138
- )
139
- . unwrap ( ) ;
140
-
141
- writer. write ( key. as_bytes ( ) , & data) . unwrap ( ) ;
142
- }
143
-
144
- value_log. register_writer ( writer) . unwrap ( ) ;
145
-
146
- for size in sizes {
147
- let key = size. to_string ( ) ;
148
- let vhandle = index. get ( key. as_bytes ( ) ) . unwrap ( ) . unwrap ( ) ;
149
-
150
- group. bench_function ( format ! ( "{size} bytes (uncached)" ) , |b| {
151
- b. iter ( || {
152
- value_log. get ( & vhandle) . unwrap ( ) . unwrap ( ) ;
153
- } )
154
- } ) ;
155
- }
156
- }
157
-
158
- {
159
- let index = MockIndex :: default ( ) ;
160
- let mut index_writer = MockIndexWriter ( index. clone ( ) ) ;
161
-
162
- let folder = tempfile:: tempdir ( ) . unwrap ( ) ;
163
- let vl_path = folder. path ( ) ;
164
-
165
- let value_log = ValueLog :: open (
166
- vl_path,
167
- Config :: < NoCompressor > :: default ( )
168
- . blob_cache ( Arc :: new ( BlobCache :: with_capacity_bytes ( 64 * 1_024 * 1_024 ) ) ) ,
169
- )
170
- . unwrap ( ) ;
187
+ let value_log = ValueLog :: open ( vl_path, Config :: < _ , NoCompressor > :: new ( NoCacher ) ) . unwrap ( ) ;
171
188
172
189
let mut writer = value_log. get_writer ( ) . unwrap ( ) ;
173
190
174
- let mut rng = rand:: thread_rng ( ) ;
191
+ let mut rng = rand:: rng ( ) ;
175
192
176
193
for size in sizes {
177
194
let key = size. to_string ( ) ;
@@ -196,10 +213,7 @@ fn load_value(c: &mut Criterion) {
196
213
let key = size. to_string ( ) ;
197
214
let vhandle = index. get ( key. as_bytes ( ) ) . unwrap ( ) . unwrap ( ) ;
198
215
199
- // NOTE: Warm up cache
200
- value_log. get ( & vhandle) . unwrap ( ) . unwrap ( ) ;
201
-
202
- group. bench_function ( format ! ( "{size} bytes (cached)" ) , |b| {
216
+ group. bench_function ( format ! ( "{size} bytes" ) , |b| {
203
217
b. iter ( || {
204
218
value_log. get ( & vhandle) . unwrap ( ) . unwrap ( ) ;
205
219
} )
0 commit comments