#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ListHandle(pub usize);
struct ListNode {
prev: usize,
next: usize,
}
pub struct List {
nodes: Vec<ListNode>,
linked: Vec<bool>, }
impl List {
pub fn new() -> Self {
List {
nodes: vec![ListNode { prev: 0, next: 0 }],
linked: vec![false], }
}
pub fn alloc(&mut self) -> ListHandle {
let idx = self.nodes.len();
self.nodes.push(ListNode { prev: 0, next: 0 });
self.linked.push(false);
ListHandle(idx)
}
pub fn enqueue(&mut self, h: ListHandle) {
let idx = h.0;
if self.linked[idx] {
self.unlink(idx);
}
let sentinel = 0usize;
let old_next = self.nodes[sentinel].next;
self.nodes[idx].next = old_next;
self.nodes[idx].prev = sentinel;
self.nodes[old_next].prev = idx;
self.nodes[sentinel].next = idx;
self.linked[idx] = true;
}
pub fn dequeue(&mut self) -> Option<ListHandle> {
let sentinel = 0usize;
let entry = self.nodes[sentinel].prev;
if entry == sentinel {
return None;
}
self.unlink(entry);
Some(ListHandle(entry))
}
fn unlink(&mut self, idx: usize) {
let prev = self.nodes[idx].prev;
let next = self.nodes[idx].next;
self.nodes[prev].next = next;
self.nodes[next].prev = prev;
self.linked[idx] = false;
}
pub fn is_linked(&self, h: ListHandle) -> bool {
self.linked[h.0]
}
}
impl Default for List {
fn default() -> Self {
List::new()
}
}