use std::sync::Arc;
use wdev::Device;
use crate::aof::{
aof_address::AofAddress,
aof_processor::{AofProcessor, AofReplayError, ReplayTarget},
garnet_append_only_file::GarnetAppendOnlyFile,
recover::recover_log_driver::RecoverLogDriver,
};
pub struct AofRecover;
impl AofRecover {
pub async fn recover_replay_driver<D: Device>(
processor: &AofProcessor,
aof: &Arc<GarnetAppendOnlyFile>,
physical_sublog_idx: usize,
until_address: i64,
until_sequence_number: i64,
target: &ReplayTarget<'_, '_, D>,
) -> Result<u64, AofReplayError> {
let until = if until_address == -1 {
aof.log().get_tail_address(physical_sublog_idx)
} else {
until_address
};
let begin = aof
.log()
.get_sub_log(physical_sublog_idx)
.begin_address(physical_sublog_idx);
let driver = RecoverLogDriver::new(physical_sublog_idx, begin, until, until_sequence_number);
driver.run(processor, aof, target).await
}
pub async fn single_log_recover<D: Device>(
processor: &AofProcessor,
aof: &Arc<GarnetAppendOnlyFile>,
db_id: i64,
physical_sublog_idx: usize,
until_address: i64,
target: &ReplayTarget<'_, '_, D>,
) -> Result<u64, AofReplayError> {
processor.switch_active_database_context(db_id);
Self::recover_replay_driver(
processor,
aof,
physical_sublog_idx,
until_address,
i64::MAX,
target,
)
.await
}
pub async fn multi_log_recover<D: Device>(
processor: &AofProcessor,
aof: &Arc<GarnetAppendOnlyFile>,
db_id: i64,
until_address: &AofAddress,
until_sequence_number: i64,
target: &ReplayTarget<'_, '_, D>,
) -> Result<u64, AofReplayError> {
processor.switch_active_database_context(db_id);
let mut total = 0u64;
for physical_sublog_idx in 0..aof.log().size() {
let begin = aof
.log()
.get_sub_log(physical_sublog_idx)
.begin_address(physical_sublog_idx);
let driver = RecoverLogDriver::new(
physical_sublog_idx,
begin,
until_address.get(physical_sublog_idx).unwrap_or(-1),
until_sequence_number,
);
total += driver.run(processor, aof, target).await?;
}
Ok(total)
}
}