use aok::{OK, Void};
use log::info;
use wrecord::{Error, RecordMut, RecordRef, encode_to_slice, record_size, try_encode_to_vec};
#[test]
fn test_predecessor_address_chain_backtracking() -> Void {
info!("开始测试: 前驱地址单向链表结构与多版本历史回溯");
let mut log_pool = Vec::<u8>::new();
let key = b"user:order:1001";
let versions: [&[u8]; 5] = [
b"{\"status\":\"created\",\"amount\":100}",
b"{\"status\":\"paid\",\"amount\":100}",
b"{\"status\":\"shipped\",\"amount\":100}",
b"{\"status\":\"delivered\",\"amount\":100}",
b"{\"status\":\"completed\",\"amount\":100}",
];
let mut current_hash_bucket_address: u64 = 0;
let mut record_offsets = Vec::with_capacity(versions.len());
for (idx, &val) in versions.iter().enumerate() {
let offset = log_pool.len() as u64;
record_offsets.push(offset);
let prev_address = current_hash_bucket_address;
let rec_len = record_size(key.len(), val.len());
let start = log_pool.len();
log_pool.resize(start + rec_len, 0);
encode_to_slice(&mut log_pool[start..], prev_address, key, val, false)?;
current_hash_bucket_address = offset;
info!(
"追加版本 V{}: offset={:#x}, prev_address={:#x}, val={}",
idx + 1,
offset,
prev_address,
String::from_utf8_lossy(val)
);
}
assert_eq!(record_offsets.len(), 5);
let mut trace_address = current_hash_bucket_address;
let mut traced_values = Vec::new();
let mut traced_steps = 0;
while trace_address != 0 {
let slice = &log_pool[trace_address as usize..];
let rec_ref = RecordRef::from_slice(slice)?;
assert_eq!(rec_ref.key(), key);
traced_values.push(rec_ref.value());
traced_steps += 1;
let next_trace = rec_ref.prev_address();
trace_address = next_trace;
}
let genesis_slice = &log_pool[0..];
let genesis_ref = RecordRef::from_slice(genesis_slice)?;
assert_eq!(genesis_ref.key(), key);
assert_eq!(genesis_ref.value(), versions[0]);
assert_eq!(genesis_ref.prev_address(), 0);
traced_values.push(genesis_ref.value());
traced_steps += 1;
assert_eq!(traced_steps, 5);
assert_eq!(traced_values.len(), 5);
let expected_descending_versions: Vec<&[u8]> = versions.iter().rev().copied().collect();
assert_eq!(traced_values, expected_descending_versions);
info!("前驱地址单向链表结构与多版本历史回溯测试通过");
OK
}
#[test]
fn test_in_place_value_update_preserves_predecessor() -> Void {
info!("开始测试: 原位内存覆写与前驱指针恒定性");
let key = b"sensor:temperature:node_42";
let initial_val = b"status=OK;temp=21.50;battery=98%";
let prev_address = 0x0000_3344_5566_7788_u64;
let mut buf = try_encode_to_vec(prev_address, key, initial_val, false)?;
let total_record_size = buf.len();
let mut rec_mut = RecordMut::from_slice_mut(&mut buf)?;
assert_eq!(rec_mut.key(), key);
assert_eq!(rec_mut.value(), initial_val);
assert_eq!(rec_mut.prev_address(), prev_address);
assert!(!rec_mut.is_tombstone());
let updated_val_1 = b"status=OK;temp=22.80;battery=97%";
assert_eq!(updated_val_1.len(), initial_val.len());
rec_mut.update_value_in_place(updated_val_1)?;
assert_eq!(rec_mut.value(), updated_val_1);
assert_eq!(rec_mut.prev_address(), prev_address);
assert_eq!(rec_mut.key(), key);
let updated_val_2 = b"status=WN;temp=35.10;battery=96%";
rec_mut.update_value_in_place(updated_val_2)?;
assert_eq!(rec_mut.value(), updated_val_2);
assert_eq!(rec_mut.prev_address(), prev_address);
rec_mut.value_mut()[0..9].copy_from_slice(b"status=AL");
assert_eq!(&rec_mut.value()[0..9], b"status=AL");
assert_eq!(rec_mut.prev_address(), prev_address);
const CURRENT_VAL: &[u8] = b"status=AL;temp=35.10;battery=96%";
assert_eq!(rec_mut.value(), CURRENT_VAL);
let short_val = b"status=ERR";
let err_short = rec_mut.update_value_in_place(short_val);
assert_eq!(
err_short,
Err(Error::ValueLengthMismatch {
expected: initial_val.len(),
actual: short_val.len(),
})
);
assert_eq!(rec_mut.value(), CURRENT_VAL);
assert_eq!(rec_mut.prev_address(), prev_address);
let long_val = b"status=OK;temp=21.50;battery=98%;extended_diagnostics=all_passed";
let err_long = rec_mut.update_value_in_place(long_val);
assert_eq!(
err_long,
Err(Error::ValueLengthMismatch {
expected: initial_val.len(),
actual: long_val.len(),
})
);
assert_eq!(rec_mut.value(), CURRENT_VAL);
assert_eq!(rec_mut.prev_address(), prev_address);
let rec_ref = rec_mut.into_ref();
assert_eq!(rec_ref.total_size(), total_record_size);
assert_eq!(rec_ref.prev_address(), prev_address);
assert_eq!(rec_ref.key(), key);
assert_eq!(rec_ref.value(), CURRENT_VAL);
info!("原位内存覆写与前驱指针恒定性测试通过");
OK
}
#[test]
fn test_rapid_tombstone_flip_and_deep_chain_traversal() -> Void {
info!("开始测试: 快速连续墓碑翻转与深层版本链回溯");
let key = b"tombstone_stress_key";
let val = b"stress_payload_v1";
let target_addr = 0x0000_dead_beef_cafe_u64;
let mut buf = try_encode_to_vec(target_addr, key, val, false)?;
{
let mut rec_mut = RecordMut::from_slice_mut(&mut buf)?;
for i in 0..100 {
let should_tombstone = i % 2 == 0;
rec_mut.set_tombstone(should_tombstone);
assert_eq!(rec_mut.is_tombstone(), should_tombstone);
assert_eq!(rec_mut.prev_address(), target_addr);
let view = rec_mut.as_ref();
assert_eq!(view.is_tombstone(), should_tombstone);
assert_eq!(view.prev_address(), target_addr);
}
}
let mut log_pool = Vec::<u8>::new();
let mut head_addr: u64 = 0;
const CHAIN_DEPTH: usize = 50;
let mut expected_history = Vec::new();
for ver in 0..CHAIN_DEPTH {
let offset = log_pool.len() as u64;
let is_deleted = ver % 5 == 3;
let v_str = format!("version_content_{ver:04}");
let v_bytes = if is_deleted {
b"".as_slice()
} else {
v_str.as_bytes()
};
let encoded = try_encode_to_vec(head_addr, key, v_bytes, is_deleted)?;
log_pool.extend_from_slice(&encoded);
expected_history.push((offset, is_deleted, v_bytes.to_vec()));
head_addr = offset;
}
let mut curr = head_addr;
let mut backward_steps = 0;
while backward_steps < CHAIN_DEPTH {
let slice = &log_pool[curr as usize..];
let r = RecordRef::from_slice(slice)?;
let expected_idx = CHAIN_DEPTH - 1 - backward_steps;
let (exp_offset, exp_tomb, ref exp_val) = expected_history[expected_idx];
assert_eq!(curr, exp_offset);
assert_eq!(r.is_tombstone(), exp_tomb);
assert_eq!(r.value(), exp_val.as_slice());
assert_eq!(r.key(), key);
curr = r.prev_address();
backward_steps += 1;
}
assert_eq!(backward_steps, CHAIN_DEPTH);
assert_eq!(curr, 0);
info!("快速连续墓碑翻转与深层版本链回溯测试通过");
OK
}
#[test]
fn test_post_copy_to_tail_and_slot_revivification() -> Void {
info!("开始测试: 尾部复制与槽位复活定型");
let key = b"session:order_id:999";
let v1_val = b"order_state=PENDING_PAYMENT";
let src_logical_address: u64 = 0x0000_0000_0001_0000;
let src_encoded = try_encode_to_vec(0, key, v1_val, false)?;
let src_ref = RecordRef::from_slice(&src_encoded)?;
assert_eq!(src_ref.key_len(), key.len() as u32);
assert_eq!(src_ref.val_len(), v1_val.len() as u32);
let v2_val = b"order_state=PAYMENT_SETTLED";
let mut tail_buffer = vec![0u8; 256];
let written = encode_to_slice(&mut tail_buffer, src_logical_address, key, v2_val, false)?;
assert_eq!(written, record_size(key.len(), v2_val.len()));
let tail_rec = RecordRef::from_slice(&tail_buffer[..written])?;
assert_eq!(tail_rec.prev_address(), src_logical_address);
assert_eq!(tail_rec.key(), key);
assert_eq!(tail_rec.value(), v2_val);
assert_eq!(tail_rec.key_len(), key.len() as u32);
assert_eq!(tail_rec.val_len(), v2_val.len() as u32);
let mut slot_buf = tail_buffer[..written].to_vec();
{
let mut rec_mut = RecordMut::from_slice_mut(&mut slot_buf)?;
rec_mut.set_tombstone(true);
assert!(rec_mut.is_tombstone());
assert_eq!(rec_mut.prev_address(), src_logical_address);
assert_eq!(rec_mut.as_slice().len(), written);
assert_eq!(
&rec_mut.as_slice()[0..8],
&rec_mut.header().prev_address.to_le_bytes()
);
rec_mut.set_tombstone(false);
let v3_val = b"order_state=DELIVERY_PACKED";
rec_mut.update_value_in_place(v3_val)?;
assert_eq!(rec_mut.key_len(), key.len() as u32);
assert_eq!(rec_mut.val_len(), v3_val.len() as u32);
assert_eq!(rec_mut.value(), v3_val);
assert_eq!(rec_mut.prev_address(), src_logical_address);
assert!(!rec_mut.is_tombstone());
}
let revivified_ref = RecordRef::from_slice(&slot_buf)?;
assert_eq!(revivified_ref.prev_address(), src_logical_address);
assert_eq!(revivified_ref.key(), key);
assert_eq!(revivified_ref.value(), b"order_state=DELIVERY_PACKED");
assert!(!revivified_ref.is_tombstone());
assert_eq!(revivified_ref.total_size(), written);
info!("尾部复制与槽位复活定型测试通过");
OK
}