///|
pub(all) struct PriorityEvent {
time : SimTime
priority : Int
id : EventId
mut cancelled : Bool
payload_id : Int
} derive(Debug)
///|
pub fn PriorityEvent::compare(
self : PriorityEvent,
other : PriorityEvent,
) -> Int {
let time_cmp = self.time.compare(other.time)
if time_cmp != 0 {
time_cmp
} else {
let prio_cmp = if self.priority < other.priority {
-1
} else if self.priority > other.priority {
1
} else {
0
}
if prio_cmp != 0 {
prio_cmp
} else {
self.id.compare(other.id)
}
}
}
///|
pub(all) struct EventHeap {
priv data : Array[PriorityEvent]
} derive(Debug)
///|
pub fn EventHeap::new() -> EventHeap {
{ data: [] }
}
///|
pub fn EventHeap::is_empty(self : EventHeap) -> Bool {
self.data.is_empty()
}
///|
pub fn EventHeap::size(self : EventHeap) -> Int {
self.data.length()
}
///|
pub fn EventHeap::clear(self : EventHeap) -> Unit {
self.data.clear()
}
///|
pub fn EventHeap::push(self : EventHeap, event : PriorityEvent) -> Unit {
self.data.push(event)
self.shift_up(self.data.length() - 1)
}
///|
pub fn EventHeap::peek(self : EventHeap) -> PriorityEvent? {
if self.data.is_empty() {
None
} else {
Some(self.data[0])
}
}
///|
pub fn EventHeap::pop(self : EventHeap) -> PriorityEvent? {
if self.data.is_empty() {
return None
}
let top = self.data[0]
let last_idx = self.data.length() - 1
self.data[0] = self.data[last_idx]
let _ = self.data.pop()
if !self.data.is_empty() {
self.shift_down(0)
}
Some(top)
}
///|
fn EventHeap::shift_up(self : EventHeap, idx : Int) -> Unit {
let mut curr = idx
while curr > 0 {
let parent = (curr - 1) / 2
if self.data[curr].compare(self.data[parent]) < 0 {
let tmp = self.data[curr]
self.data[curr] = self.data[parent]
self.data[parent] = tmp
curr = parent
} else {
break
}
}
}
///|
fn EventHeap::shift_down(self : EventHeap, idx : Int) -> Unit {
let mut curr = idx
let len = self.data.length()
while true {
let left = curr * 2 + 1
let right = curr * 2 + 2
let mut smallest = curr
if left < len && self.data[left].compare(self.data[smallest]) < 0 {
smallest = left
}
if right < len && self.data[right].compare(self.data[smallest]) < 0 {
smallest = right
}
if smallest != curr {
let tmp = self.data[curr]
self.data[curr] = self.data[smallest]
self.data[smallest] = tmp
curr = smallest
} else {
break
}
}
}
///|
pub fn EventHeap::cancel_by_id(self : EventHeap, target_id : EventId) -> Bool {
let mut found = false
for i = 0; i < self.data.length(); i = i + 1 {
if self.data[i].id == target_id && !self.data[i].cancelled {
self.data[i].cancelled = true
found = true
break
}
}
found
}
///|
pub fn EventHeap::filter_events(
self : EventHeap,
predicate : (PriorityEvent) -> Bool,
) -> Int {
let mut count = 0
for i = 0; i < self.data.length(); i = i + 1 {
if !self.data[i].cancelled && predicate(self.data[i]) {
self.data[i].cancelled = true
count = count + 1
}
}
count
}
///|
pub fn EventHeap::active_count(self : EventHeap) -> Int {
let mut count = 0
for i = 0; i < self.data.length(); i = i + 1 {
if !self.data[i].cancelled {
count = count + 1
}
}
count
}
///|
pub fn EventHeap::get_event_by_id(
self : EventHeap,
target_id : EventId,
) -> PriorityEvent? {
for i = 0; i < self.data.length(); i = i + 1 {
if self.data[i].id == target_id {
return Some(self.data[i])
}
}
None
}