//! Storage orchestration for IngestWorker. use super::IngestWorker; use crate::error::Result; use stemedb_storage::KVStore; impl IngestWorker { /// Write cascade markers for superseded epochs. /// /// Walks the epoch supersession chain and writes markers so that /// queries can check if an epoch is superseded in O(1) time. pub async fn write_supersession_cascade( &self, new_epoch_id: &[u8; 32], old_epoch_id: &[u8; 32], ) -> Result<()> { let mut current_id = *old_epoch_id; let mut depth = 0; const MAX_CASCADE_DEPTH: usize = 100; while depth < MAX_CASCADE_DEPTH { // Write marker: \x00SUPERSEDED:{old_id} -> {new_id} let key = stemedb_storage::key_codec::superseded_key(&hex::encode(current_id)); self.store.put(&key, new_epoch_id).await?; // Follow the chain: look up what this epoch superseded let epoch_key = stemedb_storage::key_codec::epoch_key(&hex::encode(current_id)); if let Some(bytes) = self.store.get(&epoch_key).await? { let epoch: stemedb_core::types::Epoch = stemedb_core::serde::deserialize(&bytes) .map_err(|e| crate::error::IngestError::Serialization(e.to_string()))?; if let Some(prev_id) = epoch.supersedes { current_id = prev_id; depth += 1; } else { break; } } else { break; } } Ok(()) } }