rusty_bubbles/internal/
memoization.rs1use sha2::{Digest, Sha256};
5use std::collections::HashMap;
6
7pub trait Hasher {
10 fn hash(&self) -> String;
12}
13
14struct Entry<T> {
15 #[allow(dead_code)]
16 key: String,
17 value: T,
18}
19
20pub struct MemoCache<T> {
23 capacity: usize,
24 cache: HashMap<String, Entry<T>>,
25 order: Vec<String>,
26}
27
28pub fn new_memo_cache<T>(capacity: usize) -> MemoCache<T> {
31 MemoCache {
32 capacity,
33 cache: HashMap::new(),
34 order: Vec::new(),
35 }
36}
37
38impl<T> MemoCache<T> {
39 pub fn capacity(&self) -> usize {
41 self.capacity
42 }
43
44 pub fn size(&self) -> usize {
47 self.order.len()
48 }
49
50 pub fn get<H: Hasher>(&mut self, h: &H) -> Option<&T> {
53 let hashed_key = h.hash();
54 if let Some(entry) = self.cache.get(&hashed_key) {
55 if let Some(pos) = self.order.iter().position(|k| *k == hashed_key) {
57 let k = self.order.remove(pos);
58 self.order.push(k);
59 }
60 return Some(&entry.value);
61 }
62 None
63 }
64
65 pub fn set<H: Hasher>(&mut self, h: &H, value: T) {
69 let hashed_key = h.hash();
70 if let Some(entry) = self.cache.get_mut(&hashed_key) {
71 entry.value = value;
72 if let Some(pos) = self.order.iter().position(|k| *k == hashed_key) {
73 let k = self.order.remove(pos);
74 self.order.push(k);
75 }
76 return;
77 }
78
79 if self.order.len() >= self.capacity {
81 if let Some(oldest) = self.order.first().cloned() {
83 self.order.remove(0);
84 self.cache.remove(&oldest);
85 }
86 }
87
88 let entry = Entry {
89 key: hashed_key.clone(),
90 value,
91 };
92 self.cache.insert(hashed_key.clone(), entry);
93 self.order.push(hashed_key);
94 }
95}
96
97#[derive(Debug, Clone, PartialEq, Eq)]
99pub struct HString(pub String);
100
101impl Hasher for HString {
102 fn hash(&self) -> String {
103 let digest = Sha256::digest(self.0.as_bytes());
104 let mut s = String::new();
105 for b in digest.iter() {
106 s.push_str(&format!("{:02x}", b));
107 }
108 s
109 }
110}
111
112#[derive(Debug, Clone, Copy, PartialEq, Eq)]
114pub struct HInt(pub i64);
115
116impl Hasher for HInt {
117 fn hash(&self) -> String {
118 let digest = Sha256::digest(self.0.to_string().as_bytes());
119 let mut s = String::new();
120 for b in digest.iter() {
121 s.push_str(&format!("{:02x}", b));
122 }
123 s
124 }
125}