use super::*; use std::{ collections::HashSet, io::{ self, Write, Read, }, }; #[derive(Clone, PartialEq, Eq, Debug)] pub struct DupeMap(HashSet); impl DupeMap { /// Create a new empty dupe map pub fn new() -> Self { Self(HashSet::new()) } /// Iterator over all added keys pub fn iter(&self) -> std::collections::hash_set::Iter { self.0.iter() } /// Is this hash in the set? pub fn peek(&self, hash: &hash::Sha256Hash) -> bool { self.0.contains(hash) } /// Try to add an entry, returns true if was not a dupe, false if it was. pub fn try_add(&mut self, hash: hash::Sha256Hash) -> bool { if self.0.contains(&hash) { false } else { self.0.insert(hash); true } } /// Save this list to a file pub fn save(&self, to: &mut W) -> io::Result { let mut done=0; for x in self.0.iter() { to.write(x.as_ref())?; done+=1; } Ok(done) } /// Save this list to a file async #[cfg(feature="threads")] pub async fn save_async(&self, to: &mut W) -> io::Result where W: tokio::io::AsyncWrite + std::marker::Send + std::marker::Sync + std::marker::Unpin { use tokio::prelude::*; let mut done=0; for x in self.0.iter() { to.write(x.as_ref()).await?; done+=1; } Ok(done) } /// Load from file. pub fn load(&mut self, from: &mut R) -> io::Result { let mut done=0; let mut read; let mut buffer = [0u8; hash::SHA256_SIZE]; while {read = from.read(&mut buffer[..])?; read==hash::SHA256_SIZE} { done += if self.try_add(hash::Sha256Hash::new(buffer)) { 1 } else { 0 }; } Ok(done) } /// Load from file. #[cfg(feature="threads")] pub async fn load_async(&mut self, from: &mut R) -> io::Result where R: tokio::io::AsyncRead + std::marker::Send + std::marker::Sync + std::marker::Unpin { use tokio::prelude::*; let mut done=0; let mut read; let mut buffer = [0u8; hash::SHA256_SIZE]; while {read = from.read(&mut buffer[..]).await?; read==hash::SHA256_SIZE} { done += if self.try_add(hash::Sha256Hash::new(buffer)) { 1 } else { 0 }; } Ok(done) } }