api_rate_limiter/cache/
in_memory.rs1use std::time::{Duration, Instant};
2use dashmap::DashMap;
3use crate::limiter::CacheBackend;
4
5#[derive(Debug)]
6struct CacheEntry {
7 value: u32,
8 expires_at: Instant,
9}
10
11pub struct InMemoryCache {
14 store: DashMap<String, CacheEntry>,
15}
16
17impl InMemoryCache {
18 pub fn new() -> Self {
20 InMemoryCache {
21 store: DashMap::new(),
22 }
23 }
24}
25
26impl CacheBackend for InMemoryCache {
27 fn get(&self, key: &str) -> Option<u32> {
28 if let Some(entry) = self.store.get(key) {
29 if entry.expires_at > Instant::now() {
30 return Some(entry.value);
32 } else {
33 drop(entry);
36 self.store.remove(key);
37 return None;
39 }
40 } else {
41 return None;
43 }
44 }
45
46 fn set(&self, key: &str, value: u32, ttl: Duration) -> Result<(), String> {
47 let expires_at = Instant::now() + ttl;
48 let entry = CacheEntry { value, expires_at };
49 self.store.insert(key.to_string(), entry);
50 Ok(())
51 }
52
53 fn incr(&self, key: &str, amount: u32) -> Result<u32, String> {
54 let now = Instant::now();
55 if let Some(mut entry) = self.store.get_mut(key) {
56 if entry.expires_at <= now {
57 entry.value = amount;
59 } else {
60 entry.value += amount;
61 }
62 Ok(entry.value)
63 } else {
64 self.store.insert(key.to_string(), CacheEntry {
66 value: amount,
67 expires_at: now, });
69 Ok(amount)
70 }
71 }
72}