Skip to content

Commit 3897cf4

Browse files
committed
tuning Safety&Performance
1 parent fc1e87e commit 3897cf4

File tree

7 files changed

+103
-46
lines changed

7 files changed

+103
-46
lines changed

core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "vsdb_core"
3-
version = "6.0.1"
3+
version = "6.1.0"
44
authors = ["[email protected]"]
55
edition = "2024"
66
description = "A std-collection-like database"

core/src/basic/mapx_raw/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,26 @@ impl MapxRaw {
252252
self.inner.range(bounds)
253253
}
254254

255+
/// Returns a detached iterator over a range of entries in the map.
256+
///
257+
/// This iterator is not tied to the lifetime of `&self`, allowing for concurrent
258+
/// modification of the map during iteration (though the iterator will see a snapshot).
259+
///
260+
/// # Arguments
261+
///
262+
/// * `bounds` - The range of keys to iterate over.
263+
///
264+
/// # Returns
265+
///
266+
/// A `MapxRawIter` that iterates over the key-value pairs in the specified range.
267+
#[inline(always)]
268+
pub fn range_detached<'a, R: RangeBounds<Cow<'a, [u8]>>>(
269+
&self,
270+
bounds: R,
271+
) -> MapxRawIter<'a> {
272+
self.inner.range_detached(bounds)
273+
}
274+
255275
/// Returns a mutable iterator over the map's entries.
256276
///
257277
/// # Returns

core/src/common/engines/mod.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use serde::{Deserialize, Serialize, de};
3232
use std::{
3333
borrow::Cow,
3434
fmt,
35-
mem::transmute,
35+
marker::PhantomData,
3636
ops::{Deref, DerefMut, RangeBounds},
3737
result::Result as StdResult,
3838
sync::LazyLock,
@@ -218,7 +218,7 @@ impl Mapx {
218218
pub(crate) fn iter(&self) -> MapxIter<'_> {
219219
MapxIter {
220220
db_iter: VSDB.db.iter(self.prefix.to_bytes()),
221-
_hdr: self,
221+
_marker: PhantomData,
222222
}
223223
}
224224

@@ -237,7 +237,18 @@ impl Mapx {
237237
) -> MapxIter<'a> {
238238
MapxIter {
239239
db_iter: VSDB.db.range(self.prefix.to_bytes(), bounds),
240-
_hdr: self,
240+
_marker: PhantomData,
241+
}
242+
}
243+
244+
#[inline(always)]
245+
pub(crate) fn range_detached<'a, R: RangeBounds<Cow<'a, [u8]>>>(
246+
&self,
247+
bounds: R,
248+
) -> MapxIter<'a> {
249+
MapxIter {
250+
db_iter: VSDB.db.range(self.prefix.to_bytes(), bounds),
251+
_marker: PhantomData,
241252
}
242253
}
243254

@@ -412,12 +423,12 @@ impl<'de> Deserialize<'de> for Mapx {
412423

413424
pub struct MapxIter<'a> {
414425
db_iter: EngineIter,
415-
_hdr: &'a Mapx,
426+
_marker: PhantomData<&'a ()>,
416427
}
417428

418429
impl fmt::Debug for MapxIter<'_> {
419430
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
420-
f.debug_tuple("MapxIter").field(&self._hdr).finish()
431+
f.debug_tuple("MapxIter").finish()
421432
}
422433
}
423434

@@ -452,9 +463,10 @@ impl<'a> Iterator for MapxIterMut<'a> {
452463
let (k, v) = self.db_iter.next()?;
453464

454465
let vmut = ValueIterMut {
466+
prefix: self.hdr.prefix.to_bytes(),
455467
key: k.clone(),
456468
value: v,
457-
iter_mut: unsafe { transmute::<&'_ mut Self, &'a mut Self>(self) },
469+
_marker: PhantomData,
458470
};
459471

460472
Some((k, vmut))
@@ -466,9 +478,10 @@ impl<'a> DoubleEndedIterator for MapxIterMut<'a> {
466478
let (k, v) = self.db_iter.next_back()?;
467479

468480
let vmut = ValueIterMut {
481+
prefix: self.hdr.prefix.to_bytes(),
469482
key: k.clone(),
470483
value: v,
471-
iter_mut: unsafe { transmute::<&'_ mut Self, &'a mut Self>(self) },
484+
_marker: PhantomData,
472485
};
473486

474487
Some((k, vmut))
@@ -477,14 +490,15 @@ impl<'a> DoubleEndedIterator for MapxIterMut<'a> {
477490

478491
#[derive(Debug)]
479492
pub struct ValueIterMut<'a> {
493+
prefix: PreBytes,
480494
key: RawKey,
481495
value: RawValue,
482-
iter_mut: &'a mut MapxIterMut<'a>,
496+
_marker: PhantomData<&'a mut ()>,
483497
}
484498

485499
impl Drop for ValueIterMut<'_> {
486500
fn drop(&mut self) {
487-
self.iter_mut.hdr.insert(&self.key[..], &self.value[..]);
501+
VSDB.db.insert(self.prefix, &self.key, &self.value);
488502
}
489503
}
490504

core/src/common/engines/parity_backend.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -297,23 +297,27 @@ impl Iterator for ParityIter {
297297
type Item = (RawKey, RawValue);
298298
fn next(&mut self) -> Option<Self::Item> {
299299
match self.inner.next().unwrap() {
300-
Some((ik, iv)) => {
300+
Some((mut ik, iv)) => {
301301
if !ik.starts_with(&self.prefix) {
302302
return None;
303303
}
304-
let k = &ik[PREFIX_SIZE..];
305304
match self.range.1.as_ref() {
306-
Bound::Unbounded => Some((k.to_vec(), iv)),
305+
Bound::Unbounded => {
306+
ik.drain(..PREFIX_SIZE);
307+
Some((ik, iv))
308+
}
307309
Bound::Excluded(u) => {
308-
if &u[PREFIX_SIZE..] > k {
309-
Some((k.to_vec(), iv))
310+
if u[..] > ik[..] {
311+
ik.drain(..PREFIX_SIZE);
312+
Some((ik, iv))
310313
} else {
311314
None
312315
}
313316
}
314317
Bound::Included(u) => {
315-
if &u[PREFIX_SIZE..] >= k {
316-
Some((k.to_vec(), iv))
318+
if u[..] >= ik[..] {
319+
ik.drain(..PREFIX_SIZE);
320+
Some((ik, iv))
317321
} else {
318322
None
319323
}
@@ -328,23 +332,27 @@ impl Iterator for ParityIter {
328332
impl DoubleEndedIterator for ParityIter {
329333
fn next_back(&mut self) -> Option<Self::Item> {
330334
match self.inner_rev.prev().unwrap() {
331-
Some((ik, iv)) => {
335+
Some((mut ik, iv)) => {
332336
if !ik.starts_with(&self.prefix) {
333337
return None;
334338
}
335-
let k = &ik[PREFIX_SIZE..];
336339
match self.range.0.as_ref() {
337-
Bound::Unbounded => Some((k.to_vec(), iv)),
340+
Bound::Unbounded => {
341+
ik.drain(..PREFIX_SIZE);
342+
Some((ik, iv))
343+
}
338344
Bound::Excluded(l) => {
339-
if &l[PREFIX_SIZE..] < k {
340-
Some((k.to_vec(), iv))
345+
if l[..] < ik[..] {
346+
ik.drain(..PREFIX_SIZE);
347+
Some((ik, iv))
341348
} else {
342349
None
343350
}
344351
}
345352
Bound::Included(l) => {
346-
if &l[PREFIX_SIZE..] <= k {
347-
Some((k.to_vec(), iv))
353+
if l[..] <= ik[..] {
354+
ik.drain(..PREFIX_SIZE);
355+
Some((ik, iv))
348356
} else {
349357
None
350358
}

core/src/common/engines/rocks_backend.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ static HDR: LazyLock<(DB, Vec<String>)> = LazyLock::new(|| rocksdb_open().unwrap
3131

3232
pub struct RocksEngine {
3333
meta: &'static DB,
34-
areas: Vec<&'static str>,
34+
cfs: Vec<&'static ColumnFamily>,
3535
prefix_allocator: PreAllocator,
3636
max_keylen: AtomicUsize,
3737
}
3838

3939
impl RocksEngine {
4040
#[inline(always)]
4141
fn cf_hdr(&self, area_idx: usize) -> &ColumnFamily {
42-
self.meta.cf_handle(self.areas[area_idx]).unwrap()
42+
self.cfs[area_idx]
4343
}
4444

4545
#[inline(always)]
@@ -93,9 +93,14 @@ impl Engine for RocksEngine {
9393
usize
9494
));
9595

96+
let cfs = areas
97+
.iter()
98+
.map(|name| meta.cf_handle(name).unwrap())
99+
.collect();
100+
96101
Ok(RocksEngine {
97102
meta,
98-
areas,
103+
cfs,
99104
prefix_allocator,
100105
// length of the raw key, exclude the meta prefix
101106
max_keylen,
@@ -280,19 +285,21 @@ pub struct RocksIter {
280285
impl Iterator for RocksIter {
281286
type Item = (RawKey, RawValue);
282287
fn next(&mut self) -> Option<Self::Item> {
283-
self.inner
284-
.next()
285-
.map(|v| v.unwrap())
286-
.map(|(ik, iv)| (ik[PREFIX_SIZE..].to_vec(), iv.into_vec()))
288+
self.inner.next().map(|v| v.unwrap()).map(|(ik, iv)| {
289+
let mut k = ik.into_vec();
290+
k.drain(..PREFIX_SIZE);
291+
(k, iv.into_vec())
292+
})
287293
}
288294
}
289295

290296
impl DoubleEndedIterator for RocksIter {
291297
fn next_back(&mut self) -> Option<Self::Item> {
292-
self.inner_rev
293-
.next()
294-
.map(|v| v.unwrap())
295-
.map(|(ik, iv)| (ik[PREFIX_SIZE..].to_vec(), iv.into_vec()))
298+
self.inner_rev.next().map(|v| v.unwrap()).map(|(ik, iv)| {
299+
let mut k = ik.into_vec();
300+
k.drain(..PREFIX_SIZE);
301+
(k, iv.into_vec())
302+
})
296303
}
297304
}
298305

wrappers/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "vsdb"
3-
version = "6.0.0"
3+
version = "6.1.0"
44
authors = ["[email protected]"]
55
edition = "2024"
66
description = "A std-collection-like database"

wrappers/src/basic/vecx/mod.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,19 @@ impl<T: ValueEnDe> Vecx<T> {
160160
let idx = idx as u64;
161161
match (self.len() as u64).cmp(&idx) {
162162
Ordering::Greater => {
163-
let shadow = unsafe { self.inner.shadow() };
164-
shadow
165-
.range(
163+
self.inner
164+
.inner
165+
.range_detached(
166166
Cow::Borrowed(&idx.to_be_bytes()[..])
167167
..Cow::Borrowed(&(self.len() as u64).to_be_bytes()[..]),
168168
)
169169
.for_each(|(i, iv)| {
170-
self.inner
171-
.insert((crate::parse_int!(i, u64) + 1).to_be_bytes(), &iv);
170+
unsafe {
171+
self.inner.insert_encoded_value(
172+
(crate::parse_int!(i, u64) + 1).to_be_bytes(),
173+
iv,
174+
)
175+
};
172176
});
173177
self.inner.insert(idx.to_be_bytes(), v);
174178
}
@@ -199,12 +203,16 @@ impl<T: ValueEnDe> Vecx<T> {
199203
if !self.is_empty() && idx < self.len() as u64 {
200204
let last_idx = self.len() as u64 - 1;
201205
let ret = self.inner.remove(idx.to_be_bytes()).unwrap();
202-
let shadow = unsafe { self.inner.shadow() };
203-
shadow
204-
.range(Cow::Borrowed(&(1 + idx).to_be_bytes()[..])..)
206+
self.inner
207+
.inner
208+
.range_detached(Cow::Borrowed(&(1 + idx).to_be_bytes()[..])..)
205209
.for_each(|(i, v)| {
206-
self.inner
207-
.insert((crate::parse_int!(i, u64) - 1).to_be_bytes(), &v);
210+
unsafe {
211+
self.inner.insert_encoded_value(
212+
(crate::parse_int!(i, u64) - 1).to_be_bytes(),
213+
v,
214+
)
215+
};
208216
});
209217
self.inner.remove(last_idx.to_be_bytes());
210218
return ret;

0 commit comments

Comments
 (0)