use crate::coordinate::Coordinate;
use crate::event::{EventKind, StoredEvent};
use crate::store::{DiskPos, StoreError};
use serde::Serialize;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum CausationRef {
#[default]
None,
Absolute(u128),
PriorItem(usize),
}
#[derive(Clone, Debug)]
pub struct BatchAppendItem {
pub coord: Coordinate,
pub kind: EventKind,
pub payload_bytes: Vec<u8>,
pub options: AppendOptions,
pub causation: CausationRef,
}
impl BatchAppendItem {
pub fn new(
coord: Coordinate,
kind: EventKind,
payload: &impl Serialize,
options: AppendOptions,
causation: CausationRef,
) -> Result<Self, StoreError> {
let payload_bytes =
rmp_serde::to_vec(payload).map_err(|e| StoreError::Serialization(Box::new(e)))?;
Ok(Self {
coord,
kind,
payload_bytes,
options,
causation,
})
}
}
#[derive(Clone, Debug)]
pub struct AppendReceipt {
pub event_id: u128,
pub sequence: u64,
pub disk_pos: DiskPos,
}
#[derive(Clone, Copy, Debug, Default)]
pub struct AppendOptions {
pub expected_sequence: Option<u32>,
pub idempotency_key: Option<u128>,
pub correlation_id: Option<u128>,
pub causation_id: Option<u128>,
pub flags: u8,
}
impl AppendOptions {
pub fn new() -> Self {
Self::default()
}
pub fn with_cas(mut self, seq: u32) -> Self {
self.expected_sequence = Some(seq);
self
}
pub fn with_idempotency(mut self, key: u128) -> Self {
self.idempotency_key = Some(key);
self
}
pub fn with_flags(mut self, flags: u8) -> Self {
self.flags = flags;
self
}
pub fn with_correlation(mut self, id: u128) -> Self {
self.correlation_id = Some(id);
self
}
pub fn with_causation(mut self, id: u128) -> Self {
self.causation_id = Some(id);
self
}
}
pub type RetentionPredicate = Box<dyn Fn(&StoredEvent<serde_json::Value>) -> bool + Send>;
#[non_exhaustive]
pub enum CompactionStrategy {
Merge,
Retention(RetentionPredicate),
Tombstone(RetentionPredicate),
}
pub struct CompactionConfig {
pub strategy: CompactionStrategy,
pub min_segments: usize,
}
impl Default for CompactionConfig {
fn default() -> Self {
Self {
strategy: CompactionStrategy::Merge,
min_segments: 2,
}
}
}
pub(crate) fn checked_payload_len(payload_bytes: &[u8]) -> Result<u32, StoreError> {
u32::try_from(payload_bytes.len())
.map_err(|_| StoreError::ser_msg("payload size exceeds u32::MAX (4GB limit)"))
}