You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.2 KiB

use super::*;
use std::{
collections::HashSet,
io::{
self,
Write,
Read,
},
};
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct DupeMap(HashSet<hash::Sha256Hash>);
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<hash::Sha256Hash>
{
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<W: Write>(&self, to: &mut W) -> io::Result<usize>
{
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<W>(&self, to: &mut W) -> io::Result<usize>
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<R: Read>(&mut self, from: &mut R) -> io::Result<usize>
{
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<R>(&mut self, from: &mut R) -> io::Result<usize>
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)
}
}