linera_views/test_utils/
performance.rs1use linera_base::time::{Duration, Instant};
5
6use crate::{
7 batch::Batch,
8 store::{
9 KeyValueStore, ReadableKeyValueStore as _, TestKeyValueDatabase, WritableKeyValueStore as _,
10 },
11 test_utils::{add_prefix, get_random_key_values_with_small_keys},
12};
13
14const PREFIX: &[u8] = &[0];
19
20const PREFIX_SEARCH: &[u8] = &[0, 0];
22
23const NUM_ENTRIES: usize = 200;
25
26const NUM_INSERT: usize = 70;
28
29const LEN_KEY: usize = 10;
31
32const LEN_VALUE: usize = 10000;
34
35async fn clear_store<S: KeyValueStore>(store: &S) {
36 let mut batch = Batch::new();
37 batch.delete_key_prefix(PREFIX.to_vec());
38 store.write_batch(batch).await.unwrap();
39}
40
41pub async fn contains_key<D, F>(iterations: u64, f: F) -> Duration
43where
44 D: TestKeyValueDatabase,
45 D::Store: KeyValueStore,
46 F: Fn(bool) -> bool,
47{
48 let namespace = D::connect_test_namespace().await.unwrap();
49 let store = namespace.open_shared(&[]).unwrap();
50 let mut total_time = Duration::ZERO;
51 for _ in 0..iterations {
52 let key_values = add_prefix(
53 PREFIX,
54 get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
55 );
56 let mut batch = Batch::new();
57 for key_value in &key_values[..NUM_INSERT] {
58 batch.put_key_value_bytes(key_value.0.clone(), key_value.1.clone());
59 }
60 store.write_batch(batch).await.unwrap();
61
62 let measurement = Instant::now();
63 for key_value in &key_values {
64 f(store.contains_key(&key_value.0).await.unwrap());
65 }
66 total_time += measurement.elapsed();
67
68 clear_store(&store).await;
69 }
70
71 total_time
72}
73
74pub async fn contains_keys<D, F>(iterations: u64, f: F) -> Duration
76where
77 D: TestKeyValueDatabase,
78 D::Store: KeyValueStore,
79 F: Fn(Vec<bool>) -> Vec<bool>,
80{
81 let namespace = D::connect_test_namespace().await.unwrap();
82 let store = namespace.open_shared(&[]).unwrap();
83 let mut total_time = Duration::ZERO;
84 for _ in 0..iterations {
85 let key_values = add_prefix(
86 PREFIX,
87 get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
88 );
89 let mut batch = Batch::new();
90 for key_value in &key_values[..NUM_INSERT] {
91 batch.put_key_value_bytes(key_value.0.clone(), key_value.1.clone());
92 }
93 store.write_batch(batch).await.unwrap();
94 let keys = key_values
95 .into_iter()
96 .map(|(key, _)| key)
97 .collect::<Vec<_>>();
98
99 let measurement = Instant::now();
100 f(store.contains_keys(keys).await.unwrap());
101 total_time += measurement.elapsed();
102
103 clear_store(&store).await;
104 }
105
106 total_time
107}
108
109pub async fn find_keys_by_prefix<D, F>(iterations: u64, f: F) -> Duration
111where
112 D: TestKeyValueDatabase,
113 D::Store: KeyValueStore,
114 F: Fn(Vec<Vec<u8>>) -> Vec<Vec<u8>>,
115{
116 let namespace = D::connect_test_namespace().await.unwrap();
117 let store = namespace.open_shared(&[]).unwrap();
118 let mut total_time = Duration::ZERO;
119 for _ in 0..iterations {
120 let key_values = add_prefix(
121 PREFIX,
122 get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
123 );
124 let mut batch = Batch::new();
125 for key_value in &key_values {
126 batch.put_key_value_bytes(key_value.0.clone(), key_value.1.clone());
127 }
128 store.write_batch(batch).await.unwrap();
129
130 let measurement = Instant::now();
131 f(store.find_keys_by_prefix(PREFIX_SEARCH).await.unwrap());
132 total_time += measurement.elapsed();
133
134 clear_store(&store).await;
135 }
136
137 total_time
138}
139
140pub async fn find_key_values_by_prefix<D, F>(iterations: u64, f: F) -> Duration
142where
143 D: TestKeyValueDatabase,
144 D::Store: KeyValueStore,
145 F: Fn(Vec<(Vec<u8>, Vec<u8>)>) -> Vec<(Vec<u8>, Vec<u8>)>,
146{
147 let namespace = D::connect_test_namespace().await.unwrap();
148 let store = namespace.open_shared(&[]).unwrap();
149 let mut total_time = Duration::ZERO;
150 for _ in 0..iterations {
151 let key_values = add_prefix(
152 PREFIX,
153 get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
154 );
155 let mut batch = Batch::new();
156 for key_value in &key_values {
157 batch.put_key_value_bytes(key_value.0.clone(), key_value.1.clone());
158 }
159 store.write_batch(batch).await.unwrap();
160
161 let measurement = Instant::now();
162 f(store
163 .find_key_values_by_prefix(PREFIX_SEARCH)
164 .await
165 .unwrap());
166 total_time += measurement.elapsed();
167
168 clear_store(&store).await;
169 }
170
171 total_time
172}
173
174pub async fn read_value_bytes<D, F>(iterations: u64, f: F) -> Duration
176where
177 D: TestKeyValueDatabase,
178 D::Store: KeyValueStore,
179 F: Fn(Option<Vec<u8>>) -> Option<Vec<u8>>,
180{
181 let namespace = D::connect_test_namespace().await.unwrap();
182 let store = namespace.open_shared(&[]).unwrap();
183 let mut total_time = Duration::ZERO;
184 for _ in 0..iterations {
185 let key_values = add_prefix(
186 PREFIX,
187 get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
188 );
189 let mut batch = Batch::new();
190 for key_value in &key_values {
191 batch.put_key_value_bytes(key_value.0.clone(), key_value.1.clone());
192 }
193 store.write_batch(batch).await.unwrap();
194
195 let measurement = Instant::now();
196 for (key, _) in &key_values {
197 f(store.read_value_bytes(key).await.unwrap());
198 }
199 total_time += measurement.elapsed();
200
201 clear_store(&store).await;
202 }
203
204 total_time
205}
206
207pub async fn read_multi_values_bytes<D, F>(iterations: u64, f: F) -> Duration
209where
210 D: TestKeyValueDatabase,
211 D::Store: KeyValueStore,
212 F: Fn(Vec<Option<Vec<u8>>>) -> Vec<Option<Vec<u8>>>,
213{
214 let namespace = D::connect_test_namespace().await.unwrap();
215 let store = namespace.open_shared(&[]).unwrap();
216 let mut total_time = Duration::ZERO;
217 for _ in 0..iterations {
218 let key_values = add_prefix(
219 PREFIX,
220 get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
221 );
222 let mut batch = Batch::new();
223 for key_value in &key_values {
224 batch.put_key_value_bytes(key_value.0.clone(), key_value.1.clone());
225 }
226 store.write_batch(batch).await.unwrap();
227 let keys = key_values
228 .into_iter()
229 .map(|(key, _)| key)
230 .collect::<Vec<_>>();
231
232 let measurement = Instant::now();
233 f(store.read_multi_values_bytes(keys).await.unwrap());
234 total_time += measurement.elapsed();
235
236 clear_store(&store).await;
237 }
238
239 total_time
240}
241
242pub async fn write_batch<D>(iterations: u64) -> Duration
244where
245 D: TestKeyValueDatabase,
246 D::Store: KeyValueStore,
247{
248 let store = D::new_test_store().await.unwrap();
249 let mut total_time = Duration::ZERO;
250 for _ in 0..iterations {
251 let key_values = add_prefix(
252 PREFIX,
253 get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
254 );
255 let mut batch = Batch::new();
256 for key_value in &key_values {
257 batch.put_key_value_bytes(key_value.0.clone(), key_value.1.clone());
258 }
259
260 let measurement = Instant::now();
261 store.write_batch(batch).await.unwrap();
262 total_time += measurement.elapsed();
263
264 clear_store(&store).await;
265 }
266
267 total_time
268}