dup_filter.rs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. /*! Filter duplicate shows of credentials and open invitations by id
  2. (which will typically be a Scalar).
  3. This implementation just keeps the table of seen ids in memory, but a
  4. production one would of course use a disk-backed database. */
  5. use std::cmp::Eq;
  6. use std::collections::HashMap;
  7. use std::hash::Hash;
  8. /// Each instance of DupFilter maintains its own independent table of
  9. /// seen ids. IdType will typically be Scalar.
  10. #[derive(Default, Debug)]
  11. pub struct DupFilter<IdType> {
  12. seen_table: HashMap<IdType, ()>,
  13. }
  14. /// A return type indicating whether the item was fresh (not previously
  15. /// seen) or previously seen
  16. #[derive(PartialEq, Eq, Debug)]
  17. pub enum SeenType {
  18. Fresh,
  19. Seen,
  20. }
  21. impl<IdType: Hash + Eq + Copy> DupFilter<IdType> {
  22. /// Check to see if the id is in the seen table, but do not add it
  23. /// to the seen table. Return Seen if it is already in the table,
  24. /// Fresh if not.
  25. pub fn check(&self, id: &IdType) -> SeenType {
  26. if self.seen_table.contains_key(id) {
  27. SeenType::Seen
  28. } else {
  29. SeenType::Fresh
  30. }
  31. }
  32. /// As atomically as possible, check to see if the id is in the seen
  33. /// table, and add it if not. Return Fresh if it was not already
  34. /// in the table, and Seen if it was.
  35. pub fn filter(&mut self, id: &IdType) -> SeenType {
  36. match self.seen_table.insert(*id, ()) {
  37. None => SeenType::Fresh,
  38. Some(()) => SeenType::Seen,
  39. }
  40. }
  41. }