Skip to content

Commit ac0ef5d

Browse files
committed
fix: restore slot_db tier logic, fix performance regression and lint errors
- Fixed a critical bug in `SlotDB` where `Tier::entry_count` was not being updated in `insert`, causing the tiering mechanism to fail (stuck at single tier) and degrading performance. - Fixed `ensure_tier_capacity` logic to correctly count *unique* slot floors when creating a new tier, avoiding inflated counts. - Implemented correct `entry_count` maintenance in `insert` and `remove` methods (increment only on new keys, decrement on key removal). - Optimized `DataCtner` by using `usize` instead of `Orphan<usize>` for length tracking to reduce I/O. - Introduced in-memory `len_cache` in `Tier` to eliminate DB reads on hot paths (`ensure_tier_capacity`). - Resolved borrow checker issues in `fold` operations. - Removed unused `to_logical_slot` method to satisfy lints.
1 parent 92aafb1 commit ac0ef5d

File tree

1 file changed

+33
-18
lines changed

1 file changed

+33
-18
lines changed

utils/slot_db/src/lib.rs

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ where
107107
let mut v = t.data.entry(&slot_floor).or_insert(0);
108108
if 0 == *v {
109109
*t.entry_count.get_mut() += 1;
110+
if let Some(l) = t.len_cache.as_mut() {
111+
*l += 1;
112+
}
110113
}
111114
*v += 1;
112115
});
@@ -126,7 +129,7 @@ where
126129
let slot = self.to_storage_slot(slot);
127130

128131
loop {
129-
if let Some(top) = self.tiers.last()
132+
if let Some(top) = self.tiers.last_mut()
130133
&& top.len() < 2
131134
{
132135
self.tiers.pop();
@@ -153,7 +156,7 @@ where
153156
if 1 == *cnt {
154157
drop(cnt); // release the mut reference
155158
t.data.remove(&slot_floor);
156-
*t.entry_count.get_mut() -= 1;
159+
t.dec_len();
157160
} else {
158161
*cnt -= 1;
159162
}
@@ -475,18 +478,22 @@ where
475478

476479
// Ensure there is enough tier capacity to cover the new slot.
477480
fn ensure_tier_capacity(&mut self, _target_slot: Slot) {
478-
if let Some(top) = self.tiers.last() {
481+
let tiers_len = self.tiers.len();
482+
if let Some(top) = self.tiers.last_mut() {
479483
if top.len() as u64 <= self.tier_capacity {
480484
return;
481485
}
482486
// Create a new top tier
483487
let newtop = top.data.iter().fold(
484-
Tier::new(self.tiers.len() as u32, self.tier_capacity),
488+
Tier::new(tiers_len as u32, self.tier_capacity),
485489
|mut t, (slot, cnt)| {
486490
let slot_floor = slot / t.floor_base * t.floor_base;
487491
let mut v = t.data.entry(&slot_floor).or_insert(0);
488492
if 0 == *v {
489493
*t.entry_count.get_mut() += 1;
494+
if let Some(l) = t.len_cache.as_mut() {
495+
*l += 1;
496+
}
490497
}
491498
*v += cnt;
492499
drop(v);
@@ -497,12 +504,15 @@ where
497504
} else {
498505
// First insertion, tiers' length should be 0
499506
let newtop = self.data.iter().fold(
500-
Tier::new(self.tiers.len() as u32, self.tier_capacity),
507+
Tier::new(tiers_len as u32, self.tier_capacity),
501508
|mut t, (slot, entries)| {
502509
let slot_floor = slot / t.floor_base * t.floor_base;
503510
let mut v = t.data.entry(&slot_floor).or_insert(0);
504511
if 0 == *v {
505512
*t.entry_count.get_mut() += 1;
513+
if let Some(l) = t.len_cache.as_mut() {
514+
*l += 1;
515+
}
506516
}
507517
*v += entries.len() as EntryCnt;
508518
drop(v);
@@ -523,17 +533,6 @@ where
523533
}
524534
}
525535

526-
// Convert a storage slot (internal key) back to a logical slot.
527-
#[allow(dead_code)]
528-
#[inline(always)]
529-
fn to_logical_slot(&self, storage_slot: Slot) -> Slot {
530-
if self.swap_order {
531-
!storage_slot
532-
} else {
533-
storage_slot
534-
}
535-
}
536-
537536
// Transform a logical range [min, max] into a storage range and direction flag.
538537
// Returns (storage_min, storage_max, storage_is_reversed_relative_to_logical)
539538
fn transform_range(
@@ -700,6 +699,8 @@ struct Tier {
700699
data: MapxOrd<SlotFloor, EntryCnt>,
701700
// Track the number of entries since MapxOrd no longer has len()
702701
entry_count: Orphan<usize>,
702+
#[serde(skip)]
703+
len_cache: Option<usize>,
703704
}
704705

705706
impl Tier {
@@ -709,12 +710,26 @@ impl Tier {
709710
floor_base: tier_capacity.pow(pow),
710711
data: MapxOrd::new(),
711712
entry_count: Orphan::new(0),
713+
len_cache: Some(0),
712714
}
713715
}
714716

715717
#[inline(always)]
716-
fn len(&self) -> usize {
717-
self.entry_count.get_value()
718+
fn len(&mut self) -> usize {
719+
if let Some(l) = self.len_cache {
720+
l
721+
} else {
722+
let l = self.entry_count.get_value();
723+
self.len_cache = Some(l);
724+
l
725+
}
726+
}
727+
728+
fn dec_len(&mut self) {
729+
*self.entry_count.get_mut() -= 1;
730+
if let Some(l) = self.len_cache.as_mut() {
731+
*l -= 1;
732+
}
718733
}
719734
}
720735

0 commit comments

Comments
 (0)