use crate::network::Network; use anyhow::Result; use log::debug; use std::collections::HashSet; use weareshared::{ packets::{Packet, Resource}, store::{ResourceStore, sha256}, }; pub struct Downloader { have: HashSet, need: HashSet, pending: HashSet, store: ResourceStore, } impl Downloader { pub fn new(store: ResourceStore) -> Self { Self { have: HashSet::new(), need: HashSet::new(), pending: HashSet::new(), store, } } pub fn try_get(&mut self, hash: Resource) -> Result>> { if self.have.contains(&hash) { self.store.get(hash) } else { self.need.insert(hash); Ok(None) } } pub fn packet(&mut self, p: &Packet) -> Result<()> { match p { Packet::RespondResource(d) => { let key = Resource(sha256(&d.0)); self.store.set(&d.0)?; self.need.remove(&key); self.pending.remove(&key); if self.have.insert(key) { debug!("have {key}"); } } _ => (), } Ok(()) } pub fn update(&mut self, network: &mut Network) -> Result<()> { let mut new_pending = Vec::new(); for n in self.need.difference(&self.pending) { network .packet_send .send(Packet::RequestResource(*n)) .unwrap(); debug!("need {n}"); new_pending.push(*n); } self.pending.extend(new_pending); Ok(()) } }