Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jasongrlicky committed Feb 17, 2017
0 parents commit 0c05634
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
Cargo.lock
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "handlebox"
version = "0.1.0"
authors = ["Jason Grlicky <[email protected]>"]

[dependencies]
75 changes: 75 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -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<V> {
pub hash_map: HashMap<Handle, V>,
discarded_handles: Vec<Handle>, // Handles that have been added but later removed
}

impl<V> HandleBox<V> {
pub fn new() -> HandleBox<V> {
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<Handle, V> {
&self.hash_map
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_new() {
let c = HandleBox::<i32>::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());
}
}

0 comments on commit 0c05634

Please sign in to comment.