@@ -24,7 +24,9 @@ use crate::manifest::version_edit::{FileMetaData, VersionEdit};
2424use crate :: manifest:: version_set:: VersionSet ;
2525use crate :: memtable:: MemTable ;
2626use crate :: memtable:: skiplist:: MemTableCursorIter ;
27- use crate :: options:: { CompactionFilter , CompactionFilterDecision , DbOptions , ReadOptions , WriteOptions } ;
27+ use crate :: options:: {
28+ CompactionFilter , CompactionFilterDecision , DbOptions , ReadOptions , WriteOptions ,
29+ } ;
2830use crate :: rate_limiter:: RateLimiter ;
2931use crate :: sst:: table_builder:: { TableBuildOptions , TableBuilder } ;
3032use crate :: sst:: table_reader:: TableIterator ;
@@ -1582,25 +1584,35 @@ impl DB {
15821584 /// **Note:** The key remains readable via `get()` until compaction
15831585 /// physically removes it. Use regular `delete()` if immediate
15841586 /// invisibility is required.
1587+ ///
1588+ /// **Warning:** Dead keys are held in memory only and are **not**
1589+ /// persisted to WAL or SST. If the process crashes or restarts
1590+ /// before compaction removes them, the registrations are lost and
1591+ /// the keys will remain in the database permanently unless
1592+ /// re-registered.
15851593 pub fn lazy_delete ( & self , key : & [ u8 ] ) {
15861594 let mut set = self . dead_keys . write ( ) . unwrap ( ) ;
15871595 set. insert ( key. to_vec ( ) ) ;
15881596 }
15891597
15901598 /// Batch version of [`lazy_delete`](Self::lazy_delete).
15911599 ///
1592- /// If the number of accumulated dead keys exceeds
1600+ /// Dead keys are **not** persisted — see [`lazy_delete`](Self::lazy_delete)
1601+ /// for durability caveats.
1602+ ///
1603+ /// If the number of accumulated dead keys newly crosses
15931604 /// `lazy_delete_compaction_threshold`, a background compaction is
15941605 /// automatically signalled.
1595- pub fn lazy_delete_batch ( & self , keys : & [ Vec < u8 > ] ) {
1606+ pub fn lazy_delete_batch ( & self , keys : impl IntoIterator < Item = impl AsRef < [ u8 ] > > ) {
15961607 let threshold = self . options . lazy_delete_compaction_threshold ;
15971608 let mut set = self . dead_keys . write ( ) . unwrap ( ) ;
1609+ let prev_len = set. len ( ) ;
15981610 for k in keys {
1599- set. insert ( k. clone ( ) ) ;
1611+ set. insert ( k. as_ref ( ) . to_vec ( ) ) ;
16001612 }
16011613 let len = set. len ( ) ;
16021614 drop ( set) ;
1603- if threshold > 0 && len >= threshold {
1615+ if threshold > 0 && len >= threshold && prev_len < threshold {
16041616 self . signal_compaction ( ) ;
16051617 }
16061618 }
@@ -1610,8 +1622,13 @@ impl DB {
16101622 self . dead_keys . read ( ) . unwrap ( ) . len ( )
16111623 }
16121624
1613- /// Clear all dead keys. Call after compaction has processed all levels
1614- /// to reclaim memory used by the dead-keys set.
1625+ /// Clear all dead keys to reclaim memory used by the dead-keys set.
1626+ ///
1627+ /// **Caution:** Only call this after a full compaction
1628+ /// ([`compact_range(None, None)`](Self::compact_range)) has
1629+ /// finished. Any dead keys that have not yet been visited by
1630+ /// compaction will be silently abandoned — those keys will remain
1631+ /// in the database and will not be removed unless re-registered.
16151632 pub fn clear_dead_keys ( & self ) {
16161633 self . dead_keys . write ( ) . unwrap ( ) . clear ( ) ;
16171634 }
0 commit comments