///|
/// 最小堆优先级事件队列
///
/// 按 `(time, priority)` 维护最小堆,保证每次弹出的是时间最早、优先级最高的事件。
/// 这是离散事件仿真时序正确性的核心保证。
pub(all) struct EventQueue {
mut heap : Array[Event]
}
///|
/// 创建空事件队列
pub fn new_queue() -> EventQueue {
{ heap: [] }
}
///|
/// 创建带容量提示的事件队列
///
/// 预分配数组容量以减少动态扩容开销,适用于大规模仿真场景。
pub fn new_queue_with_capacity(capacity : Int) -> EventQueue {
let heap : Array[Event] = []
heap.reserve_capacity(capacity)
{ heap, }
}
///|
/// 队列是否为空
pub fn EventQueue::is_empty(self : EventQueue) -> Bool {
self.heap.length() == 0
}
///|
/// 队列中事件数量
pub fn EventQueue::length(self : EventQueue) -> Int {
self.heap.length()
}
///|
/// 插入事件到队列(上浮调整)
pub fn EventQueue::push(self : EventQueue, event : Event) -> Unit {
self.heap.push(event)
self._sift_up(self.heap.length() - 1)
}
///|
/// 查看堆顶事件(不弹出),返回 None 如果队列为空
pub fn EventQueue::peek(self : EventQueue) -> Event? {
if self.heap.length() == 0 {
None
} else {
Some(self.heap[0])
}
}
///|
/// 弹出堆顶事件(下沉调整),返回 None 如果队列为空
pub fn EventQueue::pop(self : EventQueue) -> Event? {
let n = self.heap.length()
if n == 0 {
return None
}
let top = self.heap[0]
let last = self.heap.pop()
if self.heap.length() > 0 {
match last {
Some(e) => {
self.heap[0] = e
self._sift_down(0)
}
None => ()
}
}
Some(top)
}
///|
/// 移除所有已取消的事件(惰性清理)
pub fn EventQueue::remove_canceled(self : EventQueue) -> Unit {
let active : Array[Event] = []
for e in self.heap {
if e.is_pending() {
active.push(e)
}
}
self.heap = active
// 元素少于 2 个时已是堆,无需调整
if self.heap.length() < 2 {
return
}
// 重新建堆:从最后一个非叶节点顺序下沉到根
let start = self.heap.length() / 2 - 1
for i in 0..<=start {
self._sift_down(start - i)
}
}
///|
/// 上浮操作:将位置 i 的元素向上调整直到满足堆性质
fn EventQueue::_sift_up(self : EventQueue, i_param : Int) -> Unit {
let mut i = i_param
while i > 0 {
let parent = (i - 1) / 2
if event_compare(self.heap[i], self.heap[parent]) < 0 {
let tmp = self.heap[i]
self.heap[i] = self.heap[parent]
self.heap[parent] = tmp
i = parent
} else {
break
}
}
}
///|
/// 下沉操作:将位置 i 的元素向下调整直到满足堆性质
fn EventQueue::_sift_down(self : EventQueue, i_param : Int) -> Unit {
let mut i = i_param
let n = self.heap.length()
for ;; {
let left = 2 * i + 1
let right = 2 * i + 2
let mut smallest = i
if left < n && event_compare(self.heap[left], self.heap[smallest]) < 0 {
smallest = left
}
if right < n && event_compare(self.heap[right], self.heap[smallest]) < 0 {
smallest = right
}
if smallest == i {
break
}
let tmp = self.heap[i]
self.heap[i] = self.heap[smallest]
self.heap[smallest] = tmp
i = smallest
}
}