mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Use a single HashMap with the entry API and a KeyedJobTask
enum for KeyedJobs
.
This commit is contained in:
parent
6d3dcc3835
commit
8b21ed540c
@ -48,7 +48,7 @@ use conrod_core::{
|
|||||||
};
|
};
|
||||||
use core::{convert::TryInto, f32, f64, ops::Range};
|
use core::{convert::TryInto, f32, f64, ops::Range};
|
||||||
use graphic::TexId;
|
use graphic::TexId;
|
||||||
use hashbrown::{hash_map::Entry, HashMap, HashSet};
|
use hashbrown::{hash_map::Entry, HashMap};
|
||||||
use std::{hash::Hash, time::Duration};
|
use std::{hash::Hash, time::Duration};
|
||||||
use tracing::{error, warn};
|
use tracing::{error, warn};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
@ -1055,11 +1055,15 @@ fn default_scissor(renderer: &Renderer) -> Aabr<u16> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum KeyedJobTask<V> {
|
||||||
|
Pending,
|
||||||
|
Completed(V),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct KeyedJobs<K, V> {
|
pub struct KeyedJobs<K, V> {
|
||||||
tx: crossbeam_channel::Sender<(K, V)>,
|
tx: crossbeam_channel::Sender<(K, V)>,
|
||||||
rx: crossbeam_channel::Receiver<(K, V)>,
|
rx: crossbeam_channel::Receiver<(K, V)>,
|
||||||
completed: HashMap<K, V>,
|
tasks: HashMap<K, KeyedJobTask<V>>,
|
||||||
pending: HashSet<K>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Hash + Eq + Send + Sync + 'static + Clone, V: Send + Sync + 'static> KeyedJobs<K, V> {
|
impl<K: Hash + Eq + Send + Sync + 'static + Clone, V: Send + Sync + 'static> KeyedJobs<K, V> {
|
||||||
@ -1069,8 +1073,7 @@ impl<K: Hash + Eq + Send + Sync + 'static + Clone, V: Send + Sync + 'static> Key
|
|||||||
Self {
|
Self {
|
||||||
tx,
|
tx,
|
||||||
rx,
|
rx,
|
||||||
completed: HashMap::new(),
|
tasks: HashMap::new(),
|
||||||
pending: HashSet::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1081,26 +1084,35 @@ impl<K: Hash + Eq + Send + Sync + 'static + Clone, V: Send + Sync + 'static> Key
|
|||||||
f: impl FnOnce(&K) -> V + Send + Sync + 'static,
|
f: impl FnOnce(&K) -> V + Send + Sync + 'static,
|
||||||
) -> Option<(K, V)> {
|
) -> Option<(K, V)> {
|
||||||
if let Some(pool) = pool {
|
if let Some(pool) = pool {
|
||||||
if let Some(v) = self.completed.remove(&k) {
|
while let Ok((k2, v)) = self.rx.try_recv() {
|
||||||
Some((k, v))
|
if k == k2 {
|
||||||
} else {
|
return Some((k, v));
|
||||||
while let Ok((k2, v)) = self.rx.try_recv() {
|
} else {
|
||||||
self.pending.remove(&k2);
|
self.tasks.insert(k2, KeyedJobTask::Completed(v));
|
||||||
if k == k2 {
|
|
||||||
return Some((k, v));
|
|
||||||
} else {
|
|
||||||
self.completed.insert(k2, v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !self.pending.contains(&k) {
|
}
|
||||||
self.pending.insert(k.clone());
|
match self.tasks.entry(k.clone()) {
|
||||||
|
Entry::Occupied(e) => {
|
||||||
|
let mut ret = None;
|
||||||
|
e.replace_entry_with(|_, v| {
|
||||||
|
if let KeyedJobTask::Completed(v) = v {
|
||||||
|
ret = Some((k, v));
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(v)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ret
|
||||||
|
},
|
||||||
|
Entry::Vacant(e) => {
|
||||||
let tx = self.tx.clone();
|
let tx = self.tx.clone();
|
||||||
pool.spawn("IMAGE_PROCESSING", move || {
|
pool.spawn("IMAGE_PROCESSING", move || {
|
||||||
let v = f(&k);
|
let v = f(&k);
|
||||||
let _ = tx.send((k, v));
|
let _ = tx.send((k, v));
|
||||||
});
|
});
|
||||||
}
|
e.insert(KeyedJobTask::Pending);
|
||||||
None
|
None
|
||||||
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let v = f(&k);
|
let v = f(&k);
|
||||||
|
Loading…
Reference in New Issue
Block a user