Skip to content

Commit 5de07db

Browse files
committed
commitlog: Fix index truncation test.
Since #2771, and error is returned instead of the zero key if an offset index lookup yields the zero key. `truncate` removes the entry at its argument's key, i.e. `truncate(1)` empties the index. Adjust the `offset_index_writer_truncates_to_offset` test to handle this edge case. Also de-randomize it so all keys are tested.
1 parent e7b9c61 commit 5de07db

2 files changed

Lines changed: 42 additions & 16 deletions

File tree

crates/commitlog/src/index/indexfile.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::{
55
mem,
66
};
77

8-
use log::debug;
8+
use log::{debug, trace};
99
use memmap2::MmapMut;
1010
use spacetimedb_paths::server::OffsetIndexFile;
1111

@@ -190,19 +190,32 @@ impl<Key: Into<u64> + From<u64>> IndexFileMut<Key> {
190190
self.inner.flush_async()
191191
}
192192

193-
/// Truncates the index file starting from the entry with a key greater than or equal to the given key.
193+
/// Truncates the index file starting from the entry with a key greater than
194+
/// or equal to the given key.
195+
///
196+
/// If successful, `key` will no longer be in the index.
194197
pub(crate) fn truncate(&mut self, key: Key) -> Result<(), IndexError> {
195198
let key = key.into();
196-
let (found_key, index) = self.find_index(Key::from(key))?;
199+
let (found_key, index) = self
200+
.find_index(Key::from(key))
201+
.map(|(found, index)| (found.into(), index))?;
197202

198-
// If returned key is smalled than asked key, truncate from next entry
199-
self.num_entries = if found_key.into() == key {
203+
// If returned key is smaller than asked key, truncate from next entry
204+
self.num_entries = if found_key == key {
200205
index as usize
201206
} else {
202207
index as usize + 1
203208
};
204209

205210
let start = self.num_entries * ENTRY_SIZE;
211+
trace!(
212+
"truncate key={} found={} index={} num-entries={} start={}",
213+
key,
214+
found_key,
215+
index,
216+
self.num_entries,
217+
start
218+
);
206219

207220
if start < self.inner.len() {
208221
self.inner[start..].fill(0);

crates/commitlog/src/segment.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ mod tests {
695695
use super::*;
696696
use crate::{payload::ArrayDecoder, repo, Options};
697697
use itertools::Itertools;
698+
use pretty_assertions::assert_matches;
698699
use proptest::prelude::*;
699700
use spacetimedb_paths::server::CommitLogDir;
700701
use tempfile::tempdir;
@@ -924,16 +925,28 @@ mod tests {
924925

925926
// Truncating to any offset in the written range or larger
926927
// retains that offset - 1, or the max offset written.
927-
let truncate_to: TxOffset = rand::random_range(1..=32);
928-
let retained_key = truncate_to.saturating_sub(1).min(10);
929-
let retained_val = retained_key * 128;
930-
let retained = (retained_key, retained_val);
931-
932-
writer.ftruncate(truncate_to, rand::random()).unwrap();
933-
assert_eq!(writer.head.key_lookup(truncate_to).unwrap(), retained);
934-
// Make sure this also holds after reopen.
935-
drop(writer);
936-
let index = TxOffsetIndex::open_index_file(&index_path).unwrap();
937-
assert_eq!(index.key_lookup(truncate_to).unwrap(), retained);
928+
for truncate_to in (2..=10u64).rev() {
929+
let retained_key = truncate_to.saturating_sub(1).min(10);
930+
let retained_val = retained_key * 128;
931+
let retained = (retained_key, retained_val);
932+
933+
writer.ftruncate(truncate_to, rand::random()).unwrap();
934+
assert_matches!(
935+
writer.head.key_lookup(truncate_to),
936+
Ok(x) if x == retained,
937+
"truncate to {truncate_to} should retain {retained:?}"
938+
);
939+
// Make sure this also holds after reopen.
940+
let index = TxOffsetIndex::open_index_file(&index_path).unwrap();
941+
assert_matches!(
942+
index.key_lookup(truncate_to),
943+
Ok(x) if x == retained,
944+
"truncate to {truncate_to} should retain {retained:?} after reopen"
945+
);
946+
}
947+
948+
// Truncating to 1 leaves no entries in the index
949+
writer.ftruncate(1, rand::random()).unwrap();
950+
assert_matches!(writer.head.key_lookup(1), Err(IndexError::KeyNotFound));
938951
}
939952
}

0 commit comments

Comments
 (0)