From 6c467cefe4bee4adf14990e7268335c2bc71a325 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Tue, 17 Mar 2026 22:43:51 -0700 Subject: [PATCH] Fix read_append_at_ns to read timestamps from tombstone entries Go reads the full needle body for all entries including tombstones (deleted needles with size=0) to extract the actual AppendAtNs timestamp. The Rust version returned 0 early for size <= 0 entries, which would cause the binary search in incremental copy to produce incorrect results for positions containing deleted needles. Now uses get_actual_size to compute the on-disk size (which handles tombstones correctly) and only returns 0 when the actual size is 0. --- seaweed-volume/src/storage/volume.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/seaweed-volume/src/storage/volume.rs b/seaweed-volume/src/storage/volume.rs index 972e110be..4e55d06e1 100644 --- a/seaweed-volume/src/storage/volume.rs +++ b/seaweed-volume/src/storage/volume.rs @@ -2287,6 +2287,9 @@ impl Volume { } /// Read the append_at_ns timestamp from a needle at the given offset in the .dat file. + /// Go reads the full needle body for ALL entries including tombstones to get the + /// actual AppendAtNs timestamp, which is needed for correct binary search during + /// incremental copy. fn read_append_at_ns(&self, offset: Offset) -> Result { let actual_offset = offset.to_actual_offset() as u64; let version = self.version(); @@ -2295,11 +2298,11 @@ impl Volume { self.read_exact_at_backend(&mut header_buf, actual_offset)?; let (_cookie, _id, size) = Needle::parse_header(&header_buf); - if size.0 <= 0 { - return Ok(0); - } let actual_size = get_actual_size(size, version); + if actual_size <= 0 { + return Ok(0); + } let mut buf = vec![0u8; actual_size as usize]; self.read_exact_at_backend(&mut buf, actual_offset)?;