Use a custom enum instead of Result<(),()> in DupFilter

This commit is contained in:
Ian Goldberg 2021-04-27 12:59:29 -04:00
parent befacce4ef
commit f067c8b79a
2 changed files with 37 additions and 24 deletions

View File

@ -14,21 +14,33 @@ pub struct DupFilter<IdType> {
seen_table: HashMap<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> { impl<IdType: Hash + Eq + Copy> DupFilter<IdType> {
/// Check to see if the id is in the seen table, but do not add it /// 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, /// to the seen table. Return Seen if it is already in the table,
/// false if not. /// Fresh if not.
pub fn check(&self, id: &IdType) -> bool { pub fn check(&self, id: &IdType) -> SeenType {
self.seen_table.contains_key(id) 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 /// 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 /// table, and add it if not. Return Fresh if it was not already
/// in the table, and Err(()) if it was. /// in the table, and Seen if it was.
pub fn filter(&mut self, id: &IdType) -> Result<(), ()> { pub fn filter(&mut self, id: &IdType) -> SeenType {
match self.seen_table.insert(*id, ()) { match self.seen_table.insert(*id, ()) {
None => Ok(()), None => SeenType::Fresh,
Some(()) => Err(()), Some(()) => SeenType::Seen,
} }
} }
} }

View File

@ -1,4 +1,5 @@
use lox::dup_filter; use lox::dup_filter;
use lox::dup_filter::SeenType::{Fresh, Seen};
use lox::BridgeDb; use lox::BridgeDb;
use curve25519_dalek::scalar::Scalar; use curve25519_dalek::scalar::Scalar;
@ -23,23 +24,23 @@ fn test_dup_filter() {
let s4 = Scalar::random(&mut rng); let s4 = Scalar::random(&mut rng);
let s5 = Scalar::random(&mut rng); let s5 = Scalar::random(&mut rng);
// Check basic behaviour // Check basic behaviour
assert_eq!(df1.check(&s1), false); assert_eq!(df1.check(&s1), Fresh);
assert_eq!(df1.filter(&s1), Ok(())); assert_eq!(df1.filter(&s1), Fresh);
assert_eq!(df1.check(&s1), true); assert_eq!(df1.check(&s1), Seen);
assert_eq!(df1.filter(&s1), Err(())); assert_eq!(df1.filter(&s1), Seen);
// Ensure different instances of DupFilter have different tables // Ensure different instances of DupFilter have different tables
assert_eq!(df2.check(&s1), false); assert_eq!(df2.check(&s1), Fresh);
assert_eq!(df2.filter(&s1), Ok(())); assert_eq!(df2.filter(&s1), Fresh);
assert_eq!(df2.filter(&s1), Err(())); assert_eq!(df2.filter(&s1), Seen);
assert_eq!(df2.check(&s1), true); assert_eq!(df2.check(&s1), Seen);
// Check multiple ids // Check multiple ids
assert_eq!(df1.check(&s2), false); assert_eq!(df1.check(&s2), Fresh);
assert_eq!(df1.filter(&s3), Ok(())); assert_eq!(df1.filter(&s3), Fresh);
assert_eq!(df1.filter(&s4), Ok(())); assert_eq!(df1.filter(&s4), Fresh);
assert_eq!(df1.filter(&s3), Err(())); assert_eq!(df1.filter(&s3), Seen);
assert_eq!(df1.check(&s1), true); assert_eq!(df1.check(&s1), Seen);
assert_eq!(df1.filter(&s1), Err(())); assert_eq!(df1.filter(&s1), Seen);
assert_eq!(df1.filter(&s5), Ok(())); assert_eq!(df1.filter(&s5), Fresh);
println!("df1 = {:?}", df1); println!("df1 = {:?}", df1);
println!("df2 = {:?}", df2); println!("df2 = {:?}", df2);
} }