use std::mem;
use crate::Id;
#[derive(Default)]
pub struct Graph {
pub root: Id,
pub children: Vec<Vec<Id>>,
pub parent: Vec<Id>,
free_list: Vec<Id>,
}
impl Graph {
pub fn alloc_node(&mut self) -> Id {
if let Some(id) = self.free_list.pop() {
return id;
}
let id = self.children.len();
self.children.push(vec![]);
self.parent.push(id);
id
}
pub fn append_child(&mut self, parent: Id, child: Id) {
self.children[parent].push(child);
self.parent[child] = parent;
}
pub fn add_before(&mut self, parent: Id, sibling: Id, child: Id) {
let pos = self.children[parent]
.iter()
.position(|&x| x == sibling)
.expect("tried add_before nonexistent sibling");
self.children[parent].insert(pos, child);
self.parent[child] = parent;
}
pub fn remove_child(&mut self, parent: Id, child: Id) {
let ix = self.children[parent]
.iter()
.position(|&x| x == child)
.expect("tried to remove nonexistent child");
self.children[parent].remove(ix);
self.parent[child] = child;
}
pub fn free_subtree(&mut self, node: Id) {
let mut ix = self.free_list.len();
self.free_list.push(node);
while ix < self.free_list.len() {
let node = self.free_list[ix];
ix += 1;
self.parent[node] = node;
self.free_list
.extend(mem::replace(&mut self.children[node], Vec::new()));
}
}
}