Skip to content

Commit fc03851

Browse files
authored
refactor: remove read-timeouts (#5)
* refactor: remove read-timeouts * fix: remove some leftovers from timeouts and branching in the mutex path * chore: impl Send for RoTxUnsync * chore: NB * chore: bump version * fix: docs * fix: last lints and stuff * doc: final tweak
1 parent 7d17d15 commit fc03851

24 files changed

Lines changed: 1778 additions & 3129 deletions

Cargo.toml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "signet-libmdbx"
33
description = "Idiomatic and safe MDBX wrapper"
4-
version = "0.5.0"
4+
version = "0.6.0"
55
edition = "2024"
66
rust-version = "1.92"
77
license = "MIT OR Apache-2.0"
@@ -40,13 +40,6 @@ smallvec = "1.15.1"
4040
thiserror = "2.0.18"
4141
tracing = "0.1.44"
4242

43-
dashmap = { version = "6.1.0", features = ["inline"], optional = true }
44-
45-
[features]
46-
default = []
47-
return-borrowed = []
48-
read-tx-timeouts = ["dep:dashmap"]
49-
5043
[dev-dependencies]
5144
criterion = "0.8.1"
5245
proptest = "1"

benches/cursor.rs

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
mod utils;
33

44
use criterion::{Criterion, criterion_group, criterion_main};
5-
use signet_libmdbx::{Cursor, ObjectLength, ReadResult, TransactionKind, ffi::*, tx::TxPtrAccess};
5+
use signet_libmdbx::{Cursor, ObjectLength, ReadResult, TransactionKind, ffi::*};
66
use std::{hint::black_box, ptr};
77
use utils::*;
88

@@ -34,9 +34,7 @@ fn bench_get_seq_iter(c: &mut Criterion) {
3434
count += 1;
3535
}
3636

37-
fn iterate<K: TransactionKind, A: TxPtrAccess>(
38-
cursor: &mut Cursor<K, A>,
39-
) -> ReadResult<()> {
37+
fn iterate<K: TransactionKind>(cursor: &mut Cursor<K>) -> ReadResult<()> {
4038
let mut i = 0;
4139
for result in cursor.iter::<ObjectLength, ObjectLength>() {
4240
let (key_len, data_len) = result?;
@@ -107,7 +105,7 @@ fn bench_get_seq_for_loop(c: &mut Criterion) {
107105
fn bench_get_seq_iter_single_thread(c: &mut Criterion) {
108106
let n = 100;
109107
let (_dir, env) = setup_bench_db(n);
110-
let mut txn = create_ro_unsync(&env);
108+
let txn = create_ro_unsync(&env);
111109
let db = txn.open_db(None).unwrap();
112110
// Note: setup_bench_db creates a named database which adds metadata to the
113111
// main database, so actual item count is n + 1
@@ -131,9 +129,7 @@ fn bench_get_seq_iter_single_thread(c: &mut Criterion) {
131129
count += 1;
132130
}
133131

134-
fn iterate<K: TransactionKind, A: TxPtrAccess>(
135-
cursor: &mut Cursor<K, A>,
136-
) -> ReadResult<()> {
132+
fn iterate<K: TransactionKind>(cursor: &mut Cursor<K>) -> ReadResult<()> {
137133
let mut i = 0;
138134
for result in cursor.iter::<ObjectLength, ObjectLength>() {
139135
let (key_len, data_len) = result?;
@@ -154,7 +150,7 @@ fn bench_get_seq_iter_single_thread(c: &mut Criterion) {
154150
fn bench_get_seq_cursor_single_thread(c: &mut Criterion) {
155151
let n = 100;
156152
let (_dir, env) = setup_bench_db(n);
157-
let mut txn = create_ro_unsync(&env);
153+
let txn = create_ro_unsync(&env);
158154
let db = txn.open_db(None).unwrap();
159155
// Note: setup_bench_db creates a named database which adds metadata to the
160156
// main database, so actual item count is n + 1
@@ -177,7 +173,7 @@ fn bench_get_seq_cursor_single_thread(c: &mut Criterion) {
177173
fn bench_get_seq_for_loop_single_thread(c: &mut Criterion) {
178174
let n = 100;
179175
let (_dir, env) = setup_bench_db(n);
180-
let mut txn = create_ro_unsync(&env);
176+
let txn = create_ro_unsync(&env);
181177
let db = txn.open_db(None).unwrap();
182178
// Note: setup_bench_db creates a named database which adds metadata to the
183179
// main database, so actual item count is n + 1
@@ -205,9 +201,6 @@ fn bench_get_seq_raw(c: &mut Criterion) {
205201
let n = 100;
206202
let (_dir, env) = setup_bench_db(n);
207203

208-
let dbi = create_ro_sync(&env).open_db(None).unwrap().dbi();
209-
let txn = create_ro_sync(&env);
210-
211204
let mut key = MDBX_val { iov_len: 0, iov_base: ptr::null_mut() };
212205
let mut data = MDBX_val { iov_len: 0, iov_base: ptr::null_mut() };
213206
let mut cursor: *mut MDBX_cursor = ptr::null_mut();
@@ -216,23 +209,36 @@ fn bench_get_seq_raw(c: &mut Criterion) {
216209
// main database, so actual item count is n + 1
217210
let actual_items = n + 1;
218211

212+
let txn = unsafe {
213+
let mut txn: *mut MDBX_txn = ptr::null_mut();
214+
env.with_raw_env_ptr(|env_ptr| {
215+
txn = create_ro_raw(env_ptr);
216+
});
217+
txn
218+
};
219+
220+
let mut dbi: MDBX_dbi = 0;
221+
unsafe {
222+
match mdbx_dbi_open(txn, ptr::null(), 0, &mut dbi) {
223+
MDBX_SUCCESS | MDBX_RESULT_TRUE => {}
224+
err => panic!("mdbx_dbi_open failed: {}", err),
225+
}
226+
};
227+
219228
c.bench_function("cursor::traverse::raw", |b| {
220229
b.iter(|| unsafe {
221-
txn.txn_execute(|txn| {
222-
mdbx_cursor_open(txn, dbi, &raw mut cursor);
223-
let mut i = 0;
224-
let mut count = 0u32;
230+
mdbx_cursor_open(txn, dbi, &raw mut cursor);
231+
let mut i = 0;
232+
let mut count = 0u32;
225233

226-
while mdbx_cursor_get(cursor, &raw mut key, &raw mut data, MDBX_NEXT) == 0 {
227-
i += key.iov_len + data.iov_len;
228-
count += 1;
229-
}
234+
while mdbx_cursor_get(cursor, &raw mut key, &raw mut data, MDBX_NEXT) == 0 {
235+
i += key.iov_len + data.iov_len;
236+
count += 1;
237+
}
230238

231-
black_box(i);
232-
assert_eq!(count, actual_items);
233-
mdbx_cursor_close(cursor);
234-
})
235-
.unwrap();
239+
black_box(i);
240+
assert_eq!(count, actual_items);
241+
mdbx_cursor_close(cursor);
236242
})
237243
});
238244
}

benches/db_open.rs

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,62 +9,90 @@ use std::{hint::black_box, ptr};
99
/// Benchmark mdbx_dbi_flags_ex in isolation (on already-open DBI)
1010
fn bench_dbi_flags_ex_only(c: &mut Criterion) {
1111
let (_dir, env) = setup_bench_db(10);
12-
let txn = env.begin_ro_txn().unwrap();
13-
let db = txn.open_db(None).unwrap();
14-
let dbi = db.dbi();
12+
13+
let txn = unsafe {
14+
let mut txn: *mut MDBX_txn = ptr::null_mut();
15+
env.with_raw_env_ptr(|env_ptr| {
16+
txn = create_ro_raw(env_ptr);
17+
});
18+
txn
19+
};
20+
21+
let mut dbi: MDBX_dbi = 0;
22+
let flags = 0;
23+
match unsafe { mdbx_dbi_open(txn, ptr::null(), flags, &mut dbi) } {
24+
MDBX_SUCCESS | MDBX_RESULT_TRUE => {}
25+
err => panic!("mdbx_dbi_open failed: {}", err),
26+
};
1527

1628
c.bench_function("db_cache::ffi::flags", |b| {
1729
b.iter(|| {
18-
txn.txn_execute(|txn_ptr| unsafe {
19-
let mut flags: u32 = 0;
20-
let mut state: u32 = 0;
21-
black_box(mdbx_dbi_flags_ex(txn_ptr.cast_const(), dbi, &mut flags, &mut state));
22-
})
23-
.unwrap();
30+
let mut flags: u32 = 0;
31+
let mut state: u32 = 0;
32+
black_box(unsafe { mdbx_dbi_flags_ex(txn.cast_const(), dbi, &mut flags, &mut state) });
2433
})
2534
});
2635
}
2736

2837
/// Baseline: just mdbx_dbi_open without flags_ex
2938
fn bench_dbi_open_only(c: &mut Criterion) {
3039
let (_dir, env) = setup_bench_db(10);
31-
let txn = env.begin_ro_txn().unwrap();
40+
41+
let txn = unsafe {
42+
let mut txn: *mut MDBX_txn = ptr::null_mut();
43+
env.with_raw_env_ptr(|env_ptr| {
44+
txn = create_ro_raw(env_ptr);
45+
});
46+
txn
47+
};
3248

3349
c.bench_function("db_cache::ffi::open", |b| {
3450
b.iter(|| {
35-
txn.txn_execute(|txn_ptr| unsafe {
36-
let mut dbi: MDBX_dbi = 0;
37-
black_box(mdbx_dbi_open(txn_ptr, ptr::null(), 0, &mut dbi));
38-
})
39-
.unwrap();
51+
let mut dbi: MDBX_dbi = 0;
52+
let flags = 0;
53+
black_box(match unsafe { mdbx_dbi_open(txn, ptr::null(), flags, &mut dbi) } {
54+
MDBX_SUCCESS => false,
55+
MDBX_RESULT_TRUE => true,
56+
_ => panic!(),
57+
});
4058
})
4159
});
4260
}
4361

4462
/// Full open path: mdbx_dbi_open + mdbx_dbi_flags_ex
4563
fn bench_dbi_open_with_flags_ex(c: &mut Criterion) {
4664
let (_dir, env) = setup_bench_db(10);
47-
let txn = env.begin_ro_txn().unwrap();
65+
66+
let txn = unsafe {
67+
let mut txn: *mut MDBX_txn = ptr::null_mut();
68+
env.with_raw_env_ptr(|env_ptr| {
69+
txn = create_ro_raw(env_ptr);
70+
});
71+
txn
72+
};
4873

4974
c.bench_function("db_cache::ffi::open_plus_flags", |b| {
5075
b.iter(|| {
51-
txn.txn_execute(|txn_ptr| unsafe {
52-
let mut dbi: MDBX_dbi = 0;
53-
mdbx_dbi_open(txn_ptr, ptr::null(), 0, &mut dbi);
54-
let mut flags: u32 = 0;
55-
let mut state: u32 = 0;
56-
black_box(mdbx_dbi_flags_ex(txn_ptr.cast_const(), dbi, &mut flags, &mut state));
57-
})
58-
.unwrap();
59-
})
76+
let mut dbi: MDBX_dbi = 0;
77+
let flags = 0;
78+
black_box(match unsafe { mdbx_dbi_open(txn, ptr::null(), flags, &mut dbi) } {
79+
MDBX_SUCCESS => false,
80+
MDBX_RESULT_TRUE => true,
81+
_ => panic!(),
82+
});
83+
let mut flags: u32 = 0;
84+
let mut state: u32 = 0;
85+
black_box(unsafe { mdbx_dbi_flags_ex(txn.cast_const(), dbi, &mut flags, &mut state) });
86+
});
6087
});
6188
}
6289

6390
/// Benchmark cached DB opens (cache hits after first call)
6491
fn bench_open_db_cached(c: &mut Criterion) {
6592
let (_dir, env) = setup_bench_db(10);
66-
let txn = env.begin_ro_txn().unwrap();
93+
6794
// Prime the cache
95+
let txn = env.begin_ro_unsync().unwrap();
6896
let _ = txn.open_db(None).unwrap();
6997

7098
c.bench_function("db_cache::unnamed::hit", |b| {
@@ -75,7 +103,7 @@ fn bench_open_db_cached(c: &mut Criterion) {
75103
/// Benchmark uncached DB opens (always FFI call)
76104
fn bench_open_db_no_cache(c: &mut Criterion) {
77105
let (_dir, env) = setup_bench_db(10);
78-
let txn = env.begin_ro_txn().unwrap();
106+
let txn = env.begin_ro_unsync().unwrap();
79107

80108
c.bench_function("db_cache::unnamed::disabled", |b| {
81109
b.iter(|| black_box(txn.open_db_no_cache(None).unwrap()))
@@ -85,7 +113,7 @@ fn bench_open_db_no_cache(c: &mut Criterion) {
85113
/// Benchmark cached DB opens (cache hits after first call)
86114
fn bench_open_db_cached_named(c: &mut Criterion) {
87115
let (_dir, env) = setup_bench_db(10);
88-
let txn = env.begin_ro_txn().unwrap();
116+
let txn = env.begin_ro_unsync().unwrap();
89117
// Prime the cache
90118
let _ = txn.open_db(Some(NAMED_DB)).unwrap();
91119

@@ -97,7 +125,7 @@ fn bench_open_db_cached_named(c: &mut Criterion) {
97125
/// Benchmark uncached DB opens (always FFI call)
98126
fn bench_open_db_no_cache_named(c: &mut Criterion) {
99127
let (_dir, env) = setup_bench_db(10);
100-
let txn = env.begin_ro_txn().unwrap();
128+
let txn = env.begin_ro_unsync().unwrap();
101129

102130
c.bench_function("db_cache::named::disabled", |b| {
103131
b.iter(|| black_box(txn.open_db_no_cache(Some(NAMED_DB)).unwrap()))

0 commit comments

Comments
 (0)