put small field bitfields on the stack
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build / build (push) Successful in 2m1s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build / build (push) Successful in 2m1s
				
			This commit is contained in:
		| @@ -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", | ||||
|         }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user