From 9335f7193ae666c378f5011e1eb90db5721e43fd Mon Sep 17 00:00:00 2001 From: metamuffin Date: Fri, 10 Jan 2025 17:49:37 +0100 Subject: multithreaded world loading --- client/src/download.rs | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'client/src/download.rs') diff --git a/client/src/download.rs b/client/src/download.rs index 24dbe15..bc3de09 100644 --- a/client/src/download.rs +++ b/client/src/download.rs @@ -17,7 +17,7 @@ use crate::network::Network; use anyhow::Result; use log::debug; -use std::{collections::HashSet, marker::PhantomData}; +use std::{collections::HashSet, marker::PhantomData, sync::RwLock}; use weareshared::{ helper::ReadWrite, packets::{Packet, Resource}, @@ -25,6 +25,9 @@ use weareshared::{ }; pub struct Downloader { + inner: RwLock, +} +struct DownloaderState { have: HashSet, need: HashSet, pending: HashSet, @@ -34,33 +37,38 @@ pub struct Downloader { impl Downloader { pub fn new(store: ResourceStore) -> Self { Self { - have: HashSet::new(), - need: HashSet::new(), - pending: HashSet::new(), - store, + inner: DownloaderState { + have: HashSet::new(), + need: HashSet::new(), + pending: HashSet::new(), + store, + } + .into(), } } - pub fn try_get(&mut self, hash: Resource) -> Result> { + pub fn try_get(&self, hash: Resource) -> Result> { self.try_get_raw(Resource(hash.0, PhantomData))? .map(|x| T::read(&mut x.as_slice())) .transpose() } - pub fn try_get_raw(&mut self, hash: Resource) -> Result>> { - if self.have.contains(&hash) { - self.store.get_raw(hash) + pub fn try_get_raw(&self, hash: Resource) -> Result>> { + let mut state = self.inner.write().unwrap(); + if state.have.contains(&hash) { + state.store.get_raw(hash) } else { - self.need.insert(hash); + state.need.insert(hash); Ok(None) } } - pub fn packet(&mut self, p: &Packet) -> Result<()> { + pub fn packet(&self, p: &Packet) -> Result<()> { + let mut state = self.inner.write().unwrap(); match p { Packet::RespondResource(d) => { let key = Resource(sha256(&d.0), PhantomData); - self.store.set_raw(&d.0)?; - self.need.remove(&key); - self.pending.remove(&key); - if self.have.insert(key) { + state.store.set_raw(&d.0)?; + state.need.remove(&key); + state.pending.remove(&key); + if state.have.insert(key) { debug!("have {key}"); } } @@ -68,9 +76,10 @@ impl Downloader { } Ok(()) } - pub fn update(&mut self, network: &mut Network) -> Result<()> { + pub fn update(&self, network: &Network) -> Result<()> { + let mut state = self.inner.write().unwrap(); let mut new_pending = Vec::new(); - for n in self.need.difference(&self.pending) { + for n in state.need.difference(&state.pending) { network .packet_send .send(Packet::RequestResource(*n)) @@ -78,7 +87,7 @@ impl Downloader { debug!("need {n}"); new_pending.push(*n); } - self.pending.extend(new_pending); + state.pending.extend(new_pending); Ok(()) } } -- cgit v1.2.3-70-g09d2