Skip to content

Commit ac9ae5d

Browse files
authored
Merge pull request #166 from AdaWorldAPI/claude/review-rustynum-pr-80-2zNy5
Fix L1 WAL write-behind + L5 FINGERPRINT constant mismatch
2 parents dd750f8 + bfde7d4 commit ac9ae5d

3 files changed

Lines changed: 28 additions & 24 deletions

File tree

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,5 +276,7 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION");
276276

277277
/// Fingerprint dimensions (16K = 2^14, exact u64 alignment, no partial word)
278278
pub const FINGERPRINT_BITS: usize = 16_384;
279-
pub const FINGERPRINT_U64: usize = 256; // 16384/64, exact
279+
/// Alias for `FINGERPRINT_WORDS` — kept for backwards compatibility.
280+
/// Prefer `storage::bind_space::FINGERPRINT_WORDS` for new code.
281+
pub const FINGERPRINT_U64: usize = crate::storage::bind_space::FINGERPRINT_WORDS;
280282
pub const FINGERPRINT_BYTES: usize = 2048; // 256×8

src/storage/cog_redis.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2744,7 +2744,7 @@ fn fp_to_words(fp: &Fingerprint) -> [u64; 256] {
27442744
fn words_to_fp(words: &[u64; 256]) -> Fingerprint {
27452745
use crate::FINGERPRINT_U64;
27462746
let mut data = [0u64; FINGERPRINT_U64];
2747-
data[..256].copy_from_slice(words);
2747+
data[..FINGERPRINT_U64].copy_from_slice(words);
27482748
Fingerprint::from_raw(data)
27492749
}
27502750

src/storage/hardening.rs

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,21 @@ impl HardenedBindSpace {
746746
) -> Vec<u16> {
747747
self.metrics.writes.fetch_add(1, Ordering::Relaxed);
748748

749+
// WAL FIRST — write-ahead, not write-behind.
750+
// If we crash after WAL but before memory update, replay recovers.
751+
// If we crash after memory update but before WAL, data is lost.
752+
if let Some(ref wal) = self.wal {
753+
if let Ok(mut wal) = wal.lock() {
754+
let entry = WalEntry::Write {
755+
addr: addr.0,
756+
fingerprint: *fingerprint,
757+
label: label.map(|s| s.to_string()),
758+
};
759+
let _ = wal.append(&entry);
760+
self.metrics.wal_writes.fetch_add(1, Ordering::Relaxed);
761+
}
762+
}
763+
749764
let prefix = addr.prefix();
750765
let mut to_evict = Vec::new();
751766

@@ -784,26 +799,22 @@ impl HardenedBindSpace {
784799
}
785800
}
786801

787-
// WAL
788-
if let Some(ref wal) = self.wal {
789-
if let Ok(mut wal) = wal.lock() {
790-
let entry = WalEntry::Write {
791-
addr: addr.0,
792-
fingerprint: *fingerprint,
793-
label: label.map(|s| s.to_string()),
794-
};
795-
let _ = wal.append(&entry);
796-
self.metrics.wal_writes.fetch_add(1, Ordering::Relaxed);
797-
}
798-
}
799-
800802
to_evict
801803
}
802804

803805
/// Record a delete
804806
pub fn on_delete(&self, addr: Addr) {
805807
self.metrics.deletes.fetch_add(1, Ordering::Relaxed);
806808

809+
// WAL FIRST — durable record before in-memory mutation
810+
if let Some(ref wal) = self.wal {
811+
if let Ok(mut wal) = wal.lock() {
812+
let entry = WalEntry::Delete { addr: addr.0 };
813+
let _ = wal.append(&entry);
814+
self.metrics.wal_writes.fetch_add(1, Ordering::Relaxed);
815+
}
816+
}
817+
807818
let prefix = addr.prefix();
808819
if prefix >= PREFIX_FLUID_START && prefix <= PREFIX_FLUID_END {
809820
if let Ok(mut lru) = self.fluid_lru.lock() {
@@ -817,15 +828,6 @@ impl HardenedBindSpace {
817828
lru.remove(addr.0);
818829
}
819830
}
820-
821-
// WAL
822-
if let Some(ref wal) = self.wal {
823-
if let Ok(mut wal) = wal.lock() {
824-
let entry = WalEntry::Delete { addr: addr.0 };
825-
let _ = wal.append(&entry);
826-
self.metrics.wal_writes.fetch_add(1, Ordering::Relaxed);
827-
}
828-
}
829831
}
830832

831833
/// Record a link

0 commit comments

Comments
 (0)