From 0c0563472d70bd6bccdb1b138fec2cc11cdb51ac Mon Sep 17 00:00:00 2001 From: Jason Grlicky Date: Fri, 17 Feb 2017 10:15:18 -0800 Subject: [PATCH] Initial commit --- .gitignore | 2 ++ Cargo.toml | 6 +++++ src/lib.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a9d37c5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..13fa09a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "handlebox" +version = "0.1.0" +authors = ["Jason Grlicky "] + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..52e50f7 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,75 @@ +use std::collections::HashMap; + +pub type Handle = usize; + +/// A HashMap that keeps track of unused keys +#[derive(Default)] +pub struct HandleBox { + pub hash_map: HashMap, + discarded_handles: Vec, // Handles that have been added but later removed +} + +impl HandleBox { + pub fn new() -> HandleBox { + HandleBox { + hash_map: HashMap::new(), + discarded_handles: vec![], + } + } + + fn new_handle(&mut self) -> Handle { + self.discarded_handles.pop().unwrap_or(self.hash_map.values().len()) + } + + pub fn add(&mut self, value: V) -> Handle { + let h = self.new_handle(); + self.hash_map.insert(h, value); + h + } + + pub fn remove(&mut self, handle: Handle) { + let result = self.hash_map.remove(&handle); + if result.is_some() { + self.discarded_handles.push(handle) + } + } + + pub fn get(&self, handle: &Handle) -> Option<&V> { + self.hash_map.get(handle) + } + + pub fn hash_map(&self) -> &HashMap { + &self.hash_map + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_new() { + let c = HandleBox::::new(); + assert!(c.hash_map().is_empty()); + } + + #[test] + fn test_add_remove() { + let mut c = HandleBox::new(); + let h1 = c.add(888); + assert!(!c.hash_map().is_empty()); + assert_eq!(c.get(&h1).unwrap(), &888); + + let h2 = c.add(999); + assert_eq!(c.hash_map().values().len(), 2); + assert_eq!(c.get(&h2).unwrap(), &999); + + c.remove(h2); + assert_eq!(c.hash_map().values().len(), 1); + assert!(c.get(&h2).is_none()); + + c.remove(h1); + assert!(c.hash_map().is_empty()); + assert!(c.get(&h1).is_none()); + } +} \ No newline at end of file