put small field bitfields on the stack
All checks were successful
Build / build (push) Successful in 2m1s

This commit is contained in:
Max Känner 2025-01-21 20:25:54 +01:00
parent 47f75563ae
commit ea96a0eb0d

View File

@ -1,4 +1,9 @@
use std::{collections::VecDeque, fmt::Display};
use std::{
collections::VecDeque,
fmt::Display,
num::NonZeroUsize,
ops::{Deref, DerefMut},
};
use bitvec::prelude::*;
use log::{error, warn};
@ -6,6 +11,52 @@ use rand::prelude::*;
use super::{wire::Request, Coord, Direction};
#[derive(Debug, PartialEq, Eq, Clone)]
enum SmallBitBox {
Stack {
storage: BitArr!(for Self::STACK_BITS),
len: NonZeroUsize,
},
Heap(BitBox),
}
impl SmallBitBox {
const STACK_BITS: usize = usize::BITS as usize * 3;
fn new(initial: bool, len: usize) -> Self {
if let len @ 1..Self::STACK_BITS = len {
let Some(len) = NonZeroUsize::new(len) else {
unreachable!()
};
let mut storage = BitArray::ZERO;
storage.fill(initial);
Self::Stack { storage, len }
} else {
Self::Heap(bitbox![u8::from(initial); len])
}
}
}
impl Deref for SmallBitBox {
type Target = BitSlice;
fn deref(&self) -> &Self::Target {
match self {
Self::Stack { storage, len } => &storage[..len.get()],
Self::Heap(bit_box) => bit_box,
}
}
}
impl DerefMut for SmallBitBox {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
Self::Stack { storage, len } => &mut storage[..len.get()],
Self::Heap(bit_box) => bit_box,
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Board {
width: u8,
@ -14,9 +65,9 @@ pub struct Board {
food_spawn_chance: u8,
min_food: u16,
turn: u32,
food: BitBox,
hazard: BitBox,
free: BitBox,
food: SmallBitBox,
hazard: SmallBitBox,
free: SmallBitBox,
snakes: Vec<Snake>,
constrictor: bool,
}
@ -33,9 +84,9 @@ impl From<&Request> for Board {
food_spawn_chance: value.game.ruleset.settings.food_spawn_chance,
min_food: value.game.ruleset.settings.minimum_food,
turn: value.turn,
food: bitbox![0; fields],
hazard: bitbox![0; fields],
free: bitbox![1; fields],
food: SmallBitBox::new(false, fields),
hazard: SmallBitBox::new(false, fields),
free: SmallBitBox::new(true, fields),
snakes: Vec::with_capacity(value.board.snakes.len()),
constrictor: value.game.ruleset.name == "constrictor",
};