diff --git a/crates/lox-library/src/dup_filter.rs b/crates/lox-library/src/dup_filter.rs new file mode 100644 index 0000000..48681ed --- /dev/null +++ b/crates/lox-library/src/dup_filter.rs @@ -0,0 +1,34 @@ +/*! Filter duplicate shows of credentials and open invitations by id + * (which will typically be a Scalar). This implementation just keeps + * the table of seen ids in memory, but a production one would of course + * use a disk-backed database. */ + +use std::collections::HashMap; +use std::hash::Hash; +use std::cmp::Eq; + +/// Each instance of DupFilter maintains its own independent table of +/// seen ids. IdType will typically be Scalar. +#[derive(Default,Debug)] +pub struct DupFilter { + seen_table: HashMap, +} + +impl DupFilter { + /// Check to see if the id is in the seen table, but do not add it + /// to the seen table. Return true if it is already in the table, + /// false if not. + pub fn check(&self, id: &IdType) -> bool { + self.seen_table.contains_key(id) + } + + /// As atomically as possible, check to see if the id is in the seen + /// table, and add it if not. Return Ok(()) if it was not already + /// in the table, and Err(()) if it was. + pub fn filter(&mut self, id: &IdType) -> Result<(),()> { + match self.seen_table.insert(*id, ()) { + None => Ok(()), + Some(()) => Err(()), + } + } +}