use wrecord::record_size;
use super::{CopyOutcome, LogCompactor};
use crate::{
error::Result,
host::{CompactSession, CompactStore},
};
impl<S: CompactStore> LogCompactor<S> {
pub(super) async fn conditional_copy_to_tail(
&self,
session: &S::Session,
key: &[u8],
val: &[u8],
expected_main_addr: u64,
expected_index_addr: u64,
) -> Result<CopyOutcome> {
let _guard = session.enter_epoch();
let mut index_addr = expected_index_addr;
for _ in 0..self.cas_retries {
let new_addr = session
.append_record(key, val, expected_main_addr, false)
.await?;
if self.store.index().update_address(key, index_addr, new_addr) {
return Ok(CopyOutcome::Copied);
}
if self.store.enable_revivification() {
let rec_size = record_size(key.len(), val.len()) as u32;
self
.store
.reviv_put(new_addr, rec_size, self.store.read_only_address());
}
match self
.find_latest_address(session, key, Some((expected_main_addr, false)))
.await?
{
Some(latest) if latest.main_addr == expected_main_addr && !latest.is_tombstone => {
index_addr = latest.index_addr;
}
_ => return Ok(CopyOutcome::Superseded),
}
}
Ok(CopyOutcome::Retain)
}
}