Skip to content

Commit 6976d9c

Browse files
authored
Some code cleanups (#4066)
## Motivation Found some small code cleanups to do while working on the ScyllaDb code ## Proposal Clean up the code a bit ## Test Plan CI ## Release Plan - Nothing to do / These changes follow the usual release cycle.
1 parent 04f4740 commit 6976d9c

File tree

4 files changed

+98
-97
lines changed

4 files changed

+98
-97
lines changed

linera-views/src/common.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,8 @@ impl DeletionSet {
7474
pub(crate) fn get_upper_bound_option(key_prefix: &[u8]) -> Option<Vec<u8>> {
7575
let len = key_prefix.len();
7676
for i in (0..len).rev() {
77-
let val = key_prefix[i];
78-
if val < u8::MAX {
79-
let mut upper_bound = key_prefix[0..i + 1].to_vec();
77+
if key_prefix[i] < u8::MAX {
78+
let mut upper_bound = key_prefix[0..=i].to_vec();
8079
upper_bound[i] += 1;
8180
return Some(upper_bound);
8281
}

linera-views/src/random.rs

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,52 @@
11
// Copyright (c) Zefchain Labs, Inc.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use rand::{Rng, SeedableRng};
4+
#[cfg(target_arch = "wasm32")]
5+
use std::sync::{Mutex, MutexGuard, OnceLock};
6+
7+
use rand::{rngs::SmallRng, Rng, SeedableRng};
58

69
// The following seed is chosen to have equal numbers of 1s and 0s, as advised by
710
// https://docs.rs/rand/latest/rand/rngs/struct.SmallRng.html
811
// Specifically, it's "01" × 32 in binary
912
const RNG_SEED: u64 = 6148914691236517205;
1013

1114
/// A deterministic RNG.
12-
pub type DeterministicRng = rand::rngs::SmallRng;
15+
pub type DeterministicRng = SmallRng;
1316

1417
/// A RNG that is non-deterministic if the platform supports it.
15-
pub struct NonDeterministicRng(
16-
#[cfg(target_arch = "wasm32")] std::sync::MutexGuard<'static, DeterministicRng>,
17-
#[cfg(not(target_arch = "wasm32"))] rand::rngs::ThreadRng,
18-
);
19-
20-
impl NonDeterministicRng {
21-
/// Access the internal RNG.
22-
pub fn rng_mut(&mut self) -> &mut impl Rng {
23-
#[cfg(target_arch = "wasm32")]
24-
{
25-
&mut *self.0
26-
}
27-
#[cfg(not(target_arch = "wasm32"))]
28-
{
29-
&mut self.0
30-
}
31-
}
32-
}
18+
#[cfg(not(target_arch = "wasm32"))]
19+
pub type NonDeterministicRng = rand::rngs::ThreadRng;
20+
/// A RNG that is non-deterministic if the platform supports it.
21+
#[cfg(target_arch = "wasm32")]
22+
pub type NonDeterministicRng = MutexGuard<'static, DeterministicRng>;
3323

3424
/// Returns a deterministic RNG for testing.
3525
pub fn make_deterministic_rng() -> DeterministicRng {
36-
rand::rngs::SmallRng::seed_from_u64(RNG_SEED)
26+
SmallRng::seed_from_u64(RNG_SEED)
3727
}
3828

3929
/// Returns a non-deterministic RNG where supported.
4030
pub fn make_nondeterministic_rng() -> NonDeterministicRng {
4131
#[cfg(target_arch = "wasm32")]
4232
{
43-
use std::sync::{Mutex, OnceLock};
44-
45-
use rand::rngs::SmallRng;
46-
4733
static RNG: OnceLock<Mutex<SmallRng>> = OnceLock::new();
48-
NonDeterministicRng(
49-
RNG.get_or_init(|| Mutex::new(make_deterministic_rng()))
50-
.lock()
51-
.expect("failed to lock RNG mutex"),
52-
)
34+
RNG.get_or_init(|| Mutex::new(make_deterministic_rng()))
35+
.lock()
36+
.expect("failed to lock RNG mutex")
5337
}
5438

5539
#[cfg(not(target_arch = "wasm32"))]
5640
{
57-
NonDeterministicRng(rand::thread_rng())
41+
rand::thread_rng()
5842
}
5943
}
6044

6145
/// Get a random alphanumeric string that can be used for all tests.
6246
pub fn generate_random_alphanumeric_string(length: usize, charset: &[u8]) -> String {
6347
(0..length)
6448
.map(|_| {
65-
let random_index = make_nondeterministic_rng()
66-
.rng_mut()
67-
.gen_range(0..charset.len());
49+
let random_index = make_nondeterministic_rng().gen_range(0..charset.len());
6850
charset[random_index] as char
6951
})
7052
.collect()

linera-views/src/test_utils/mod.rs

Lines changed: 72 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,38 @@ use crate::{
2222
},
2323
};
2424

25+
/// The size of the small value used for tests.
26+
pub const SMALL_BYTE_UPPER_LIMIT: u8 = 3;
27+
2528
/// Returns a random key prefix used for tests
2629
pub fn get_random_key_prefix() -> Vec<u8> {
2730
let mut key_prefix = vec![0];
28-
let value: usize = make_nondeterministic_rng().rng_mut().gen();
31+
let value: usize = make_nondeterministic_rng().gen();
2932
bcs::serialize_into(&mut key_prefix, &value).unwrap();
3033
key_prefix
3134
}
3235

33-
/// Takes a random number generator, a `key_prefix` and extends it by n random bytes.
34-
pub fn get_random_byte_vector<R: Rng>(rng: &mut R, key_prefix: &[u8], n: usize) -> Vec<u8> {
36+
fn get_random_byte_vector_with_byte_upper_limit<R: Rng>(
37+
rng: &mut R,
38+
key_prefix: &[u8],
39+
n: usize,
40+
byte_upper_limit: u8,
41+
) -> Vec<u8> {
3542
let mut v = key_prefix.to_vec();
3643
for _ in 0..n {
37-
let val = rng.gen_range(0..256) as u8;
44+
let val = rng.gen_range(0..=byte_upper_limit);
3845
v.push(val);
3946
}
4047
v
4148
}
4249

43-
/// Appends a small value to a key making collisions likely.
44-
pub fn get_small_key_space<R: Rng>(rng: &mut R, key_prefix: &[u8], n: usize) -> Vec<u8> {
45-
let mut key = key_prefix.to_vec();
46-
for _ in 0..n {
47-
let byte = rng.gen_range(0..4) as u8;
48-
key.push(byte);
49-
}
50-
key
50+
fn get_small_key_space<R: Rng>(rng: &mut R, key_prefix: &[u8], n: usize) -> Vec<u8> {
51+
get_random_byte_vector_with_byte_upper_limit(rng, key_prefix, n, SMALL_BYTE_UPPER_LIMIT)
52+
}
53+
54+
/// Takes a random number generator, a `key_prefix` and extends it by n random bytes.
55+
pub fn get_random_byte_vector<R: Rng>(rng: &mut R, key_prefix: &[u8], n: usize) -> Vec<u8> {
56+
get_random_byte_vector_with_byte_upper_limit(rng, key_prefix, n, u8::MAX)
5157
}
5258

5359
/// Builds a random k element subset of n
@@ -61,36 +67,43 @@ pub fn get_random_kset<R: Rng>(rng: &mut R, n: usize, k: usize) -> Vec<usize> {
6167
}
6268

6369
/// Takes a random number generator, a `key_prefix` and generates
64-
/// pairs `(key, value)` with key obtained by appending 8 bytes at random to `key_prefix`
65-
/// and value obtained by appending 8 bytes to the trivial vector.
66-
/// We return n such `(key, value)` pairs which are all distinct
70+
/// pairs `(key, value)` with key obtained by appending `len_key` random bytes to `key_prefix`
71+
/// and value obtained by creating a vector with `len_value` random bytes.
72+
/// We return n such `(key, value)` pairs which are all distinct.
6773
pub fn get_random_key_values_prefix<R: Rng>(
6874
rng: &mut R,
6975
key_prefix: Vec<u8>,
7076
len_key: usize,
7177
len_value: usize,
7278
num_entries: usize,
79+
key_byte_upper_limit: u8,
7380
) -> Vec<(Vec<u8>, Vec<u8>)> {
74-
loop {
75-
let mut v_ret = Vec::new();
76-
let mut vector_set = HashSet::new();
77-
for _ in 0..num_entries {
78-
let v1 = get_random_byte_vector(rng, &key_prefix, len_key);
79-
let v2 = get_random_byte_vector(rng, &Vec::new(), len_value);
80-
let v12 = (v1.clone(), v2);
81-
vector_set.insert(v1);
82-
v_ret.push(v12);
83-
}
84-
if vector_set.len() == num_entries {
85-
return v_ret;
86-
}
81+
let mut key_value_pairs = Vec::new();
82+
let mut unique_keys = HashSet::new();
83+
for _ in 0..num_entries {
84+
let key = loop {
85+
let key = get_random_byte_vector_with_byte_upper_limit(
86+
rng,
87+
&key_prefix,
88+
len_key,
89+
key_byte_upper_limit,
90+
);
91+
if !unique_keys.contains(&key) {
92+
unique_keys.insert(key.clone());
93+
break key;
94+
}
95+
};
96+
let value = get_random_byte_vector(rng, &Vec::new(), len_value);
97+
key_value_pairs.push((key, value));
8798
}
99+
100+
key_value_pairs
88101
}
89102

90103
/// Takes a random number generator `rng`, a number n and returns n random `(key, value)`
91104
/// which are all distinct with key and value being of length 8.
92105
pub fn get_random_key_values<R: Rng>(rng: &mut R, num_entries: usize) -> Vec<(Vec<u8>, Vec<u8>)> {
93-
get_random_key_values_prefix(rng, Vec::new(), 8, 8, num_entries)
106+
get_random_key_values_prefix(rng, Vec::new(), 8, 8, num_entries, u8::MAX)
94107
}
95108

96109
type VectorPutDelete = (Vec<(Vec<u8>, Vec<u8>)>, usize);
@@ -101,8 +114,7 @@ pub fn get_random_key_value_operations<R: Rng>(
101114
num_entries: usize,
102115
k: usize,
103116
) -> VectorPutDelete {
104-
let key_value_vector = get_random_key_values_prefix(rng, Vec::new(), 8, 8, num_entries);
105-
(key_value_vector, k)
117+
(get_random_key_values(rng, num_entries), k)
106118
}
107119

108120
/// A random reordering of the puts and deletes.
@@ -234,31 +246,39 @@ pub async fn run_reads<S: RestrictedKeyValueStore>(store: S, key_values: Vec<(Ve
234246
}
235247
}
236248

237-
fn get_random_key_values1(num_entries: usize, len_value: usize) -> Vec<(Vec<u8>, Vec<u8>)> {
249+
/// Generates a list of random key-values with no duplicates
250+
pub fn get_random_key_values_with_sizes(
251+
num_entries: usize,
252+
len_key: usize,
253+
len_value: usize,
254+
) -> Vec<(Vec<u8>, Vec<u8>)> {
238255
let key_prefix = vec![0];
239256
let mut rng = make_deterministic_rng();
240-
get_random_key_values_prefix(&mut rng, key_prefix, 8, len_value, num_entries)
257+
get_random_key_values_prefix(
258+
&mut rng,
259+
key_prefix,
260+
len_key,
261+
len_value,
262+
num_entries,
263+
u8::MAX,
264+
)
241265
}
242266

243-
/// Generates a list of random key-values with no duplicates
244-
pub fn get_random_key_values2(
267+
fn get_random_key_values_with_small_keys(
245268
num_entries: usize,
246269
len_key: usize,
247270
len_value: usize,
248271
) -> Vec<(Vec<u8>, Vec<u8>)> {
249-
let mut rng = make_deterministic_rng();
250272
let key_prefix = vec![0];
251-
let mut key_values = Vec::new();
252-
let mut key_set = HashSet::new();
253-
for _ in 0..num_entries {
254-
let key = get_small_key_space(&mut rng, &key_prefix, len_key);
255-
if !key_set.contains(&key) {
256-
key_set.insert(key.clone());
257-
let value = get_random_byte_vector(&mut rng, &[], len_value);
258-
key_values.push((key, value));
259-
}
260-
}
261-
key_values
273+
let mut rng = make_deterministic_rng();
274+
get_random_key_values_prefix(
275+
&mut rng,
276+
key_prefix,
277+
len_key,
278+
len_value,
279+
num_entries,
280+
SMALL_BYTE_UPPER_LIMIT,
281+
)
262282
}
263283

264284
/// Adds a prefix to a list of key-values
@@ -276,11 +296,11 @@ pub fn add_prefix(prefix: &[u8], key_values: Vec<(Vec<u8>, Vec<u8>)>) -> Vec<(Ve
276296
/// We build a number of scenarios for testing the reads.
277297
pub fn get_random_test_scenarios() -> Vec<Vec<(Vec<u8>, Vec<u8>)>> {
278298
vec![
279-
get_random_key_values1(7, 3),
280-
get_random_key_values1(150, 3),
281-
get_random_key_values1(30, 10),
282-
get_random_key_values2(30, 4, 10),
283-
get_random_key_values2(30, 4, 100),
299+
get_random_key_values_with_sizes(7, 8, 3),
300+
get_random_key_values_with_sizes(150, 8, 3),
301+
get_random_key_values_with_sizes(30, 8, 10),
302+
get_random_key_values_with_small_keys(30, 4, 10),
303+
get_random_key_values_with_small_keys(30, 4, 100),
284304
]
285305
}
286306

linera-views/src/test_utils/performance.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::time::{Duration, Instant};
66
use crate::{
77
batch::Batch,
88
store::{KeyValueStore, TestKeyValueStore},
9-
test_utils::{add_prefix, get_random_key_values2},
9+
test_utils::{add_prefix, get_random_key_values_with_small_keys},
1010
};
1111

1212
// We generate about 2000 keys of length 11 with a key of length 10000
@@ -46,7 +46,7 @@ where
4646
for _ in 0..iterations {
4747
let key_values = add_prefix(
4848
PREFIX,
49-
get_random_key_values2(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
49+
get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
5050
);
5151
let mut batch = Batch::new();
5252
for key_value in &key_values[..NUM_INSERT] {
@@ -76,7 +76,7 @@ where
7676
for _ in 0..iterations {
7777
let key_values = add_prefix(
7878
PREFIX,
79-
get_random_key_values2(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
79+
get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
8080
);
8181
let mut batch = Batch::new();
8282
for key_value in &key_values[..NUM_INSERT] {
@@ -108,7 +108,7 @@ where
108108
for _ in 0..iterations {
109109
let key_values = add_prefix(
110110
PREFIX,
111-
get_random_key_values2(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
111+
get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
112112
);
113113
let mut batch = Batch::new();
114114
for key_value in &key_values {
@@ -136,7 +136,7 @@ where
136136
for _ in 0..iterations {
137137
let key_values = add_prefix(
138138
PREFIX,
139-
get_random_key_values2(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
139+
get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
140140
);
141141
let mut batch = Batch::new();
142142
for key_value in &key_values {
@@ -167,7 +167,7 @@ where
167167
for _ in 0..iterations {
168168
let key_values = add_prefix(
169169
PREFIX,
170-
get_random_key_values2(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
170+
get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
171171
);
172172
let mut batch = Batch::new();
173173
for key_value in &key_values {
@@ -197,7 +197,7 @@ where
197197
for _ in 0..iterations {
198198
let key_values = add_prefix(
199199
PREFIX,
200-
get_random_key_values2(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
200+
get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
201201
);
202202
let mut batch = Batch::new();
203203
for key_value in &key_values {
@@ -226,7 +226,7 @@ pub async fn write_batch<S: TestKeyValueStore>(iterations: u64) -> Duration {
226226
for _ in 0..iterations {
227227
let key_values = add_prefix(
228228
PREFIX,
229-
get_random_key_values2(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
229+
get_random_key_values_with_small_keys(NUM_ENTRIES, LEN_KEY, LEN_VALUE),
230230
);
231231
let mut batch = Batch::new();
232232
for key_value in &key_values {

0 commit comments

Comments
 (0)