1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
- /*! 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::cmp::Eq;
- use std::collections::HashMap;
- use std::hash::Hash;
- /// Each instance of DupFilter maintains its own independent table of
- /// seen ids. IdType will typically be Scalar.
- #[derive(Default, Debug)]
- pub struct DupFilter<IdType> {
- seen_table: HashMap<IdType, ()>,
- }
- /// A return type indicating whether the item was fresh (not previously
- /// seen) or previously seen
- #[derive(PartialEq, Eq, Debug)]
- pub enum SeenType {
- Fresh,
- Seen,
- }
- impl<IdType: Hash + Eq + Copy> DupFilter<IdType> {
- /// Check to see if the id is in the seen table, but do not add it
- /// to the seen table. Return Seen if it is already in the table,
- /// Fresh if not.
- pub fn check(&self, id: &IdType) -> SeenType {
- if self.seen_table.contains_key(id) {
- SeenType::Seen
- } else {
- SeenType::Fresh
- }
- }
- /// As atomically as possible, check to see if the id is in the seen
- /// table, and add it if not. Return Fresh if it was not already
- /// in the table, and Seen if it was.
- pub fn filter(&mut self, id: &IdType) -> SeenType {
- match self.seen_table.insert(*id, ()) {
- None => SeenType::Fresh,
- Some(()) => SeenType::Seen,
- }
- }
- }
|