use std::collections::{BTreeMap, HashMap};
use std::sync::{Arc, Mutex};
use nodedb_array::sync::apply::ApplyOutcome;
use nodedb_array::sync::op::ArrayOp;
use nodedb_array::sync::snapshot::{SnapshotChunk, SnapshotHeader};
use crate::error::LiteError;
use crate::storage::engine::StorageEngine;
use crate::sync::array::catchup::CatchupTracker;
use crate::sync::array::pending::PendingQueue;
use crate::sync::array::replica_state::ReplicaState;
use crate::sync::array::schema_registry::SchemaRegistry;
use super::apply::LiteApplyEngine;
use super::outcome::InboundOutcome;
pub(super) struct SnapshotAssembly {
pub(super) header: SnapshotHeader,
pub(super) chunks: BTreeMap<u32, SnapshotChunk>,
}
impl SnapshotAssembly {
pub(super) fn new(header: SnapshotHeader) -> Self {
Self {
header,
chunks: BTreeMap::new(),
}
}
}
pub struct ArrayInbound<S: StorageEngine> {
pub(super) engine: Arc<LiteApplyEngine<S>>,
pub(super) schemas: Arc<SchemaRegistry<S>>,
pub(super) replica: Arc<ReplicaState>,
pub(super) pending: Arc<PendingQueue<S>>,
pub(super) catchup: Arc<CatchupTracker<S>>,
pub(super) snapshots: Mutex<HashMap<(String, [u8; 18]), SnapshotAssembly>>,
}
impl<S: StorageEngine> ArrayInbound<S> {
pub fn new(
engine: Arc<LiteApplyEngine<S>>,
schemas: Arc<SchemaRegistry<S>>,
replica: Arc<ReplicaState>,
pending: Arc<PendingQueue<S>>,
catchup: Arc<CatchupTracker<S>>,
) -> Self {
Self {
engine,
schemas,
replica,
pending,
catchup,
snapshots: Mutex::new(HashMap::new()),
}
}
pub fn replica_id(&self) -> u64 {
self.replica.replica_id().as_u64()
}
pub(super) fn apply_single_op(&self, op: &ArrayOp) -> Result<ApplyOutcome, LiteError> {
let mut engine_ref: &LiteApplyEngine<S> = &self.engine;
nodedb_array::sync::apply::apply_op(&mut engine_ref, op).map_err(|e| LiteError::Storage {
detail: format!("apply: {e}"),
})
}
}
pub(super) fn map_apply_outcome(outcome: ApplyOutcome) -> InboundOutcome {
match outcome {
ApplyOutcome::Applied => InboundOutcome::Applied,
ApplyOutcome::Idempotent => InboundOutcome::Idempotent,
ApplyOutcome::Rejected(r) => InboundOutcome::Rejected(r),
}
}