use thiserror::Error;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct FenceValue(pub u64);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct UploadTicket(pub(super) u64);
impl UploadTicket {
#[must_use]
pub const fn sequence(self) -> u64 {
self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum UploadState {
Reserved,
Ready,
InFlight(FenceValue),
Cancelled,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct UploadReservation {
pub(super) ticket: UploadTicket,
pub(super) offset: usize,
pub(super) len: usize,
}
impl UploadReservation {
#[must_use]
pub const fn ticket(self) -> UploadTicket {
self.ticket
}
#[must_use]
pub const fn offset(self) -> usize {
self.offset
}
#[must_use]
pub const fn len(self) -> usize {
self.len
}
#[must_use]
pub const fn is_empty(self) -> bool {
self.len == 0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct UploadRingConfig {
pub capacity_bytes: usize,
pub ticket_capacity: usize,
pub epoch_budget_bytes: usize,
pub in_flight_budget_bytes: usize,
pub alignment: usize,
}
impl UploadRingConfig {
pub const fn validate(self) -> Result<(), UploadBackpressure> {
if self.capacity_bytes == 0
|| self.ticket_capacity == 0
|| self.epoch_budget_bytes == 0
|| self.in_flight_budget_bytes == 0
|| self.in_flight_budget_bytes > self.capacity_bytes
|| !self.alignment.is_power_of_two()
{
return Err(UploadBackpressure::InvalidConfiguration);
}
Ok(())
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct UploadMetrics {
pub bytes_staged: u64,
pub bytes_submitted: u64,
pub bytes_retired: u64,
pub bytes_cancelled: u64,
pub epoch_bytes: u64,
pub in_flight_bytes: u64,
pub peak_in_flight_bytes: u64,
pub occupied_bytes: u64,
pub peak_occupied_bytes: u64,
pub active_tickets: u64,
pub stall_events: u64,
pub stalled_bytes: u64,
pub host_allocation_events: u64,
}
#[derive(Clone, Copy, Debug, Error, PartialEq, Eq)]
pub enum UploadBackpressure {
#[error("upload ring configuration is invalid")]
InvalidConfiguration,
#[error("an upload reservation must contain at least one byte")]
EmptyUpload,
#[error("upload epoch budget exhausted")]
EpochBudget,
#[error("upload in-flight budget exhausted")]
InFlightBudget,
#[error("upload staging ring is full")]
RingFull,
#[error("upload ticket capacity is exhausted")]
TicketCapacity,
#[error("upload reservation size overflow")]
SizeOverflow,
#[error("upload ticket is stale or has an invalid state")]
InvalidTicket,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Retirement {
pub tickets: usize,
pub bytes: u64,
}