game_solver/
transposition.rs#[cfg(feature = "rayon")]
use moka::future::Cache;
#[cfg(feature = "rayon")]
use std::sync::Arc;
use crate::game::Game;
use std::{
collections::HashMap,
hash::{BuildHasher, Hash},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Score {
LowerBound(isize),
UpperBound(isize),
}
pub trait TranspositionTable<T: Eq + Hash + Game> {
fn get(&self, board: &T) -> Option<Score>;
fn insert(&mut self, board: T, score: Score);
fn has(&self, board: &T) -> bool;
}
impl<K: Eq + Hash + Game, S: BuildHasher + Default> TranspositionTable<K> for HashMap<K, Score, S> {
fn get(&self, board: &K) -> Option<Score> {
self.get(board).copied()
}
fn insert(&mut self, board: K, score: Score) {
self.insert(board, score);
}
fn has(&self, board: &K) -> bool {
self.contains_key(board)
}
}
#[cfg(feature = "rayon")]
pub struct TranspositionCache<K: Eq + Hash + Game + Send + Sync + 'static, S: BuildHasher + Default>(
Cache<K, Score, S>,
);
#[cfg(feature = "rayon")]
impl<
K: Eq + Hash + Game + Send + Sync,
S: BuildHasher + Default + Send + Sync + Clone + 'static,
> TranspositionCache<K, S>
{
pub fn with_capacity(capacity: u64) -> Self {
Self(
Cache::builder()
.max_capacity(capacity)
.build_with_hasher(S::default()),
)
}
#[must_use]
pub fn new() -> Self {
let score_size = std::mem::size_of::<Score>() as u64;
Self::with_capacity(
(sysinfo::System::new_all().total_memory() * 3 / 4) / score_size,
)
}
}
#[cfg(feature = "rayon")]
impl<
K: Eq + Hash + Game + Send + Sync,
S: BuildHasher + Default + Send + Sync + Clone + 'static,
> Default for TranspositionCache<K, S>
{
fn default() -> Self {
Self::new()
}
}
#[cfg(feature = "rayon")]
impl<
K: Eq + Hash + Game + Send + Sync + 'static,
S: BuildHasher + Default + Send + Sync + Clone + 'static,
> TranspositionTable<K> for Arc<TranspositionCache<K, S>>
{
fn get(&self, board: &K) -> Option<Score> {
futures::executor::block_on(self.0.get(board))
}
fn insert(&mut self, board: K, score: Score) {
futures::executor::block_on(self.0.insert(board, score));
}
fn has(&self, board: &K) -> bool {
self.0.contains_key(board)
}
}