use do_memory_core::{ComplexityLevel, ExecutionStep, SelfLearningMemory, TaskContext, TaskType};
use uuid::Uuid;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let memory = SelfLearningMemory::new();
println!("=== Bulk Episode Operations Demo ===\n");
println!("Creating 5 test episodes...");
let context = TaskContext {
language: Some("rust".to_string()),
framework: Some("tokio".to_string()),
complexity: ComplexityLevel::Moderate,
domain: "async-programming".to_string(),
tags: vec!["demo".to_string(), "bulk-ops".to_string()],
};
let mut episode_ids = Vec::new();
for i in 1..=5 {
let id = memory
.start_episode(
format!("Task {i}: Implement async feature"),
context.clone(),
TaskType::CodeGeneration,
)
.await;
let step = ExecutionStep::new(1, "compiler".to_string(), "Build project".to_string());
memory.log_step(id, step).await;
episode_ids.push(id);
println!(" Created episode {i}: {id}");
}
println!("\n--- Single Episode Retrieval ---");
let first_id = episode_ids[0];
match memory.get_episode(first_id).await {
Ok(episode) => {
println!("✓ Retrieved episode: {}", episode.episode_id);
println!(" Task: {}", episode.task_description);
println!(" Steps: {}", episode.steps.len());
println!(" Domain: {}", episode.context.domain);
}
Err(e) => {
println!("✗ Failed to retrieve episode: {e}");
}
}
let non_existent = Uuid::new_v4();
println!("\nTrying to fetch non-existent episode {non_existent}...");
match memory.get_episode(non_existent).await {
Ok(_) => println!("✗ Unexpectedly found episode!"),
Err(e) => println!("✓ Expected error: {e}"),
}
println!("\n--- Bulk Episode Retrieval ---");
println!("\nRetrieving all {} episodes in bulk...", episode_ids.len());
let episodes = memory.get_episodes_by_ids(&episode_ids).await?;
println!("✓ Retrieved {} episodes", episodes.len());
for (idx, episode) in episodes.iter().enumerate() {
println!(
" [{}] {} - {} steps",
idx + 1,
episode.episode_id,
episode.steps.len()
);
}
println!("\n--- Partial Match Test ---");
let mut mixed_ids = vec![episode_ids[0], episode_ids[2]]; mixed_ids.push(Uuid::new_v4()); mixed_ids.push(Uuid::new_v4());
println!("Requesting 4 episodes (2 exist, 2 don't exist)...");
let partial_episodes = memory.get_episodes_by_ids(&mixed_ids).await?;
println!("✓ Retrieved {} out of 4 episodes", partial_episodes.len());
println!("\n--- Performance Comparison ---");
let start = std::time::Instant::now();
for id in &episode_ids {
let _ = memory.get_episode(*id).await?;
}
let individual_duration = start.elapsed();
let start = std::time::Instant::now();
let _ = memory.get_episodes_by_ids(&episode_ids).await?;
let bulk_duration = start.elapsed();
println!("Individual lookups (5 calls): {individual_duration:?}");
println!("Bulk lookup (1 call): {bulk_duration:?}");
if bulk_duration < individual_duration {
#[allow(clippy::cast_precision_loss)]
let speedup = individual_duration.as_micros() as f64 / bulk_duration.as_micros() as f64;
println!("✓ Bulk lookup is {speedup:.2}x faster!");
}
println!("\n=== Demo Complete ===");
Ok(())
}