use super::{clone_hull, compare_hull_data, destroy_hull, hash_hull_data, HullData};
use std::rc::Rc;
#[derive(Debug, Default)]
pub struct HullDatabase {
entries: Vec<Rc<HullData>>,
}
impl HullDatabase {
pub fn new() -> Self {
Self {
entries: Vec::new(),
}
}
fn find(&self, src: &HullData) -> Option<Rc<HullData>> {
let h = hash_hull_data(src);
for entry in &self.entries {
if hash_hull_data(entry) == h && compare_hull_data(entry, src) {
return Some(Rc::clone(entry));
}
}
None
}
pub fn add(&mut self, src: &HullData) -> Rc<HullData> {
if let Some(existing) = self.find(src) {
return existing;
}
let owned = clone_hull(src).expect("valid hull");
let rc = Rc::new(owned);
self.entries.push(Rc::clone(&rc));
rc
}
pub fn add_owned(&mut self, owned: HullData) -> Rc<HullData> {
if let Some(existing) = self.find(&owned) {
destroy_hull(owned);
return existing;
}
let rc = Rc::new(owned);
self.entries.push(Rc::clone(&rc));
rc
}
pub fn release(&mut self, hull: &Rc<HullData>) {
if Rc::strong_count(hull) == 2 {
self.entries.retain(|e| !Rc::ptr_eq(e, hull));
}
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn len(&self) -> usize {
self.entries.len()
}
}