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