mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Better SmallCache
This commit is contained in:
parent
bdb71a15df
commit
9bb3681f55
@ -426,7 +426,7 @@ fn write_column<R: Rng>(
|
|||||||
wpos2d: Vec2<i32>,
|
wpos2d: Vec2<i32>,
|
||||||
z_range: Range<i32>,
|
z_range: Range<i32>,
|
||||||
tunnel: Tunnel,
|
tunnel: Tunnel,
|
||||||
mushroom_cache: &mut SmallCache<Option<Mushroom>>,
|
mushroom_cache: &mut SmallCache<Vec3<i32>, Option<Mushroom>>,
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
) {
|
) {
|
||||||
let info = canvas.info();
|
let info = canvas.info();
|
||||||
@ -494,7 +494,7 @@ fn write_column<R: Rng>(
|
|||||||
let mut get_mushroom = |wpos: Vec3<i32>, dynamic_rng: &mut R| {
|
let mut get_mushroom = |wpos: Vec3<i32>, dynamic_rng: &mut R| {
|
||||||
for (wpos2d, seed) in StructureGen2d::new(34537, 24, 8).get(wpos.xy()) {
|
for (wpos2d, seed) in StructureGen2d::new(34537, 24, 8).get(wpos.xy()) {
|
||||||
let mushroom = if let Some(mushroom) = mushroom_cache
|
let mushroom = if let Some(mushroom) = mushroom_cache
|
||||||
.get(wpos2d, |_| {
|
.get(wpos2d.with_z(tunnel.a.depth), |_| {
|
||||||
let mut rng = RandomPerm::new(seed);
|
let mut rng = RandomPerm::new(seed);
|
||||||
let (z_range, radius) =
|
let (z_range, radius) =
|
||||||
tunnel.z_range_at(wpos2d.map(|e| e as f64 + 0.5), info)?;
|
tunnel.z_range_at(wpos2d.map(|e| e as f64 + 0.5), info)?;
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
use arr_macro::arr;
|
use arr_macro::arr;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
fn calc_idx(v: Vec2<i32>) -> usize {
|
fn calc_idx(v: impl Iterator<Item = i32>) -> usize {
|
||||||
let mut x = v.x as u32;
|
let mut r = 0;
|
||||||
let mut y = v.y as u32;
|
for (e, h) in v.zip([0x6eed0e9d, 0x2f72b421, 0x18132f72, 0x891e2fba].into_iter()) {
|
||||||
x = x.wrapping_mul(0x6eed0e9d);
|
r ^= (e as u32).wrapping_mul(h);
|
||||||
y = y.wrapping_mul(0x2f72b421);
|
}
|
||||||
(x ^ y) as usize
|
r as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Use 128 if TerrainChunkSize::RECT_SIZE.x = 128.
|
// NOTE: Use 128 if TerrainChunkSize::RECT_SIZE.x = 128.
|
||||||
const CACHE_LEN: usize = 32;
|
const CACHE_LEN: usize = 32;
|
||||||
|
|
||||||
pub struct SmallCache<V: Default> {
|
pub struct SmallCache<K, V: Default> {
|
||||||
index: [Option<Vec2<i32>>; CACHE_LEN + 9],
|
index: [Option<K>; CACHE_LEN + 9],
|
||||||
data: [V; CACHE_LEN + 9],
|
data: [V; CACHE_LEN + 9],
|
||||||
random: u32,
|
random: u32,
|
||||||
}
|
}
|
||||||
impl<V: Default> Default for SmallCache<V> {
|
impl<K: Copy, V: Default> Default for SmallCache<K, V> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
index: [None; CACHE_LEN + 9],
|
index: [None; CACHE_LEN + 9],
|
||||||
@ -26,9 +26,9 @@ impl<V: Default> Default for SmallCache<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<V: Default> SmallCache<V> {
|
impl<K: Copy + Eq + IntoIterator<Item = i32>, V: Default> SmallCache<K, V> {
|
||||||
pub fn get<F: FnOnce(Vec2<i32>) -> V>(&mut self, key: Vec2<i32>, f: F) -> &V {
|
pub fn get<F: FnOnce(K) -> V>(&mut self, key: K, f: F) -> &V {
|
||||||
let idx = calc_idx(key) % CACHE_LEN;
|
let idx = calc_idx(key.into_iter()) % CACHE_LEN;
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
if self.index[idx].as_ref().map(|k| k == &key).unwrap_or(false) {
|
if self.index[idx].as_ref().map(|k| k == &key).unwrap_or(false) {
|
||||||
|
Loading…
Reference in New Issue
Block a user