use diskann::ANNResult;
use super::{CheckpointManager, Progress, WorkStage};
pub struct CheckpointContext<'a> {
checkpoint_manager: &'a dyn CheckpointManager,
current_stage: WorkStage,
next_stage: WorkStage,
}
impl<'a> CheckpointContext<'a> {
pub fn new(
checkpoint_manager: &'a dyn CheckpointManager,
current_stage: WorkStage,
next_stage: WorkStage,
) -> Self {
Self {
checkpoint_manager,
current_stage,
next_stage,
}
}
pub fn current_stage(&self) -> WorkStage {
self.current_stage
}
pub fn to_owned(&self) -> OwnedCheckpointContext {
OwnedCheckpointContext::new(
self.checkpoint_manager.clone_box(),
self.current_stage,
self.next_stage,
)
}
pub fn get_resumption_point(&self) -> ANNResult<Option<usize>> {
self.checkpoint_manager
.get_resumption_point(self.current_stage)
}
}
pub struct OwnedCheckpointContext {
checkpoint_manager: Box<dyn CheckpointManager>,
current_stage: WorkStage,
next_stage: WorkStage,
}
impl OwnedCheckpointContext {
pub fn new(
checkpoint_manager: Box<dyn CheckpointManager>,
current_stage: WorkStage,
next_stage: WorkStage,
) -> Self {
Self {
checkpoint_manager,
current_stage,
next_stage,
}
}
pub fn current_stage(&self) -> WorkStage {
self.current_stage
}
pub fn get_resumption_point(&mut self) -> ANNResult<Option<usize>> {
self.checkpoint_manager
.get_resumption_point(self.current_stage)
}
pub fn update(&mut self, progress: Progress) -> ANNResult<()> {
self.checkpoint_manager.update(progress, self.next_stage)
}
pub fn mark_as_invalid(&mut self) -> ANNResult<()> {
self.checkpoint_manager.mark_as_invalid()
}
}
#[cfg(test)]
mod tests {
use super::super::NaiveCheckpointRecordManager;
use super::*;
#[test]
fn test_checkpoint_context_new() {
let manager = NaiveCheckpointRecordManager;
let context = CheckpointContext::new(&manager, WorkStage::Start, WorkStage::End);
assert_eq!(context.current_stage(), WorkStage::Start);
}
#[test]
fn test_checkpoint_context_current_stage() {
let manager = NaiveCheckpointRecordManager;
let context =
CheckpointContext::new(&manager, WorkStage::QuantizeFPV, WorkStage::InMemIndexBuild);
assert_eq!(context.current_stage(), WorkStage::QuantizeFPV);
}
#[test]
fn test_checkpoint_context_get_resumption_point() {
let manager = NaiveCheckpointRecordManager;
let context = CheckpointContext::new(&manager, WorkStage::Start, WorkStage::End);
let result = context.get_resumption_point();
assert!(result.is_ok());
assert_eq!(result.unwrap(), Some(0));
}
#[test]
fn test_checkpoint_context_to_owned() {
let manager = NaiveCheckpointRecordManager;
let context = CheckpointContext::new(&manager, WorkStage::Start, WorkStage::End);
let owned = context.to_owned();
assert_eq!(owned.current_stage(), WorkStage::Start);
}
#[test]
fn test_owned_checkpoint_context_new() {
let manager = Box::new(NaiveCheckpointRecordManager);
let context = OwnedCheckpointContext::new(
manager,
WorkStage::TrainBuildQuantizer,
WorkStage::PartitionData,
);
assert_eq!(context.current_stage(), WorkStage::TrainBuildQuantizer);
}
#[test]
fn test_owned_checkpoint_context_update() {
let manager = Box::new(NaiveCheckpointRecordManager);
let mut context = OwnedCheckpointContext::new(manager, WorkStage::Start, WorkStage::End);
let result = context.update(Progress::Completed);
assert!(result.is_ok());
}
#[test]
fn test_owned_checkpoint_context_mark_as_invalid() {
let manager = Box::new(NaiveCheckpointRecordManager);
let mut context = OwnedCheckpointContext::new(manager, WorkStage::Start, WorkStage::End);
let result = context.mark_as_invalid();
assert!(result.is_ok());
}
}