dscale 0.7.1

A fast & deterministic simulation framework for benchmarking and testing distributed systems
Documentation
// DScale: deterministic distributed systems simulator
// Copyright (C) 2026  Konstantin Shprenger

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use std::{collections::BinaryHeap, fmt::Debug, hash::Hash};

use log::trace;
use rustc_hash::FxHashMap;

#[derive(Debug)]
pub struct LazyRemoveBinHeap<T: Ord + Hash + Eq + Clone> {
    heap: BinaryHeap<T>,
    tombstones: FxHashMap<T, ()>,
}

impl<T: Ord + Hash + Eq + Clone + Debug> LazyRemoveBinHeap<T> {
    pub fn new(prealloc_size: usize) -> Self {
        LazyRemoveBinHeap {
            heap: BinaryHeap::with_capacity(prealloc_size.next_power_of_two()),
            tombstones: FxHashMap::default(),
        }
    }

    pub fn push(&mut self, item: T) {
        self.heap.push(item);
        trace!("new lazyheap state after push:\n{:#?}", self)
    }

    pub fn remove(&mut self, item: T) {
        self.tombstones.insert(item, ());
        trace!("new lazyheap state after remove:\n{:#?}", self)
    }

    pub fn peek(&mut self) -> Option<&T> {
        self.evict_tombstones();
        self.heap.peek()
    }

    pub fn is_empty(&mut self) -> bool {
        self.peek().is_none()
    }

    fn evict_tombstones(&mut self) {
        loop {
            match self.heap.peek() {
                None => break,
                Some(top) => match self.tombstones.remove(&top) {
                    Some(_) => {
                        self.heap.pop();
                    }
                    _ => break,
                },
            }
        }
        trace!("new lazyheap state after eviction:\n{:#?}", self)
    }
}