use super::{alloc, pezpallet::Config};
use alloc::collections::BinaryHeap;
use core::cmp::{Ord, Ordering, PartialOrd};
use pezframe_support::{
pezpallet_prelude::{Decode, Encode, RuntimeDebug, TypeInfo},
traits::Currency,
};
use pezkuwi_primitives::{CoreIndex, Id as ParaId, ON_DEMAND_MAX_QUEUE_MAX_SIZE};
use pezsp_runtime::FixedU128;
pub type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as pezframe_system::Config>::AccountId>>::Balance;
#[derive(Encode, Decode, TypeInfo)]
pub struct QueueStatusType {
pub traffic: FixedU128,
pub next_index: QueueIndex,
pub smallest_index: QueueIndex,
pub freed_indices: BinaryHeap<ReverseQueueIndex>,
}
impl Default for QueueStatusType {
fn default() -> QueueStatusType {
QueueStatusType {
traffic: FixedU128::default(),
next_index: QueueIndex(0),
smallest_index: QueueIndex(0),
freed_indices: BinaryHeap::new(),
}
}
}
impl QueueStatusType {
pub fn size(&self) -> u32 {
self.next_index
.0
.overflowing_sub(self.smallest_index.0)
.0
.saturating_sub(self.freed_indices.len() as u32)
}
pub fn push_back(&mut self) -> QueueIndex {
let QueueIndex(next_index) = self.next_index;
self.next_index = QueueIndex(next_index.overflowing_add(1).0);
QueueIndex(next_index)
}
pub fn push_front(&mut self) -> QueueIndex {
self.smallest_index = QueueIndex(self.smallest_index.0.overflowing_sub(1).0);
self.smallest_index
}
pub fn consume_index(&mut self, removed_index: QueueIndex) {
if removed_index != self.smallest_index {
self.freed_indices.push(removed_index.reverse());
return;
}
let mut index = self.smallest_index.0.overflowing_add(1).0;
while self.freed_indices.peek() == Some(&ReverseQueueIndex(index)) {
index = index.overflowing_add(1).0;
self.freed_indices.pop();
}
self.smallest_index = QueueIndex(index);
}
}
#[derive(Encode, Decode, TypeInfo, Debug, PartialEq, Clone, Eq, Copy)]
pub struct QueueIndex(pub u32);
#[derive(Encode, Decode, TypeInfo, Debug, PartialEq, Clone, Eq, Copy)]
pub struct ReverseQueueIndex(pub u32);
impl QueueIndex {
fn reverse(self) -> ReverseQueueIndex {
ReverseQueueIndex(self.0)
}
}
impl Ord for QueueIndex {
fn cmp(&self, other: &Self) -> Ordering {
let diff = self.0.overflowing_sub(other.0).0;
if diff == 0 {
Ordering::Equal
} else if diff <= ON_DEMAND_MAX_QUEUE_MAX_SIZE {
Ordering::Greater
} else {
Ordering::Less
}
}
}
impl PartialOrd for QueueIndex {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for ReverseQueueIndex {
fn cmp(&self, other: &Self) -> Ordering {
QueueIndex(other.0).cmp(&QueueIndex(self.0))
}
}
impl PartialOrd for ReverseQueueIndex {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(&other))
}
}
#[derive(Encode, Decode, TypeInfo, Debug, PartialEq, Clone, Eq)]
pub struct EnqueuedOrder {
pub para_id: ParaId,
pub idx: QueueIndex,
}
impl EnqueuedOrder {
pub fn new(idx: QueueIndex, para_id: ParaId) -> Self {
Self { idx, para_id }
}
}
impl PartialOrd for EnqueuedOrder {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match other.idx.partial_cmp(&self.idx) {
Some(Ordering::Equal) => other.para_id.partial_cmp(&self.para_id),
o => o,
}
}
}
impl Ord for EnqueuedOrder {
fn cmp(&self, other: &Self) -> Ordering {
match other.idx.cmp(&self.idx) {
Ordering::Equal => other.para_id.cmp(&self.para_id),
o => o,
}
}
}
#[derive(Encode, Decode, Default, Clone, Copy, TypeInfo)]
#[cfg_attr(test, derive(PartialEq, RuntimeDebug))]
pub struct CoreAffinityCount {
pub core_index: CoreIndex,
pub count: u32,
}
#[cfg_attr(test, derive(RuntimeDebug))]
pub enum QueuePushDirection {
Back,
Front,
}
#[derive(PartialEq, RuntimeDebug)]
pub enum SpotTrafficCalculationErr {
QueueCapacityIsZero,
QueueSizeLargerThanCapacity,
Division,
}