1use std::{
2 collections::HashMap,
3 iter::Inspect,
4 time::{Duration, Instant},
5};
6
7use crate::{FixedBucket, Selfb};
8
9impl FixedBucket {
15 pub fn new(total_request: u64, minutes: u64) -> Self {
16 FixedBucket {
17 request: total_request,
18 duration: Duration::from_secs(minutes * 60),
19 capacity: 0,
20 rates: 0.0,
21 last_update: HashMap::new(),
22 requests: HashMap::new(),
23 }
24 }
25 pub fn bucket(self, capacity: u64, rates: f64) -> Self {
26 let rates = rates / 1000.0;
27 FixedBucket {
28 request: self.request,
29 duration: self.duration,
30 capacity: capacity,
31 rates: rates,
32 last_update: self.last_update,
33 requests: self.requests,
34 }
35 }
36 fn bucket_update(&mut self, key: String) {
37 let now = Instant::now();
38 let (tokens, b) = self.last_update.entry(key).or_insert((0.0, now));
39 println!("{}", tokens);
40 let current_time = now.duration_since(*b).as_millis();
41 let token = (self.rates * current_time as f64).ceil();
42 *tokens = (*tokens + token).min(self.capacity as f64);
43 *b = now;
44 }
45 fn fixed_bucket(&mut self, key: String) -> bool {
46 let now = Instant::now();
47 let (tokens, b) = self.requests.entry(key).or_insert((0, now));
48 let current = now.duration_since(*b);
49 if current > self.duration {
51 *b = now;
52 *tokens = 0;
53 }
54 if *tokens <= self.request {
55 *tokens += 1;
56 true
57 } else {
58 false
59 }
60 }
61 pub fn allow(&mut self, ip: impl Into<String> + Copy, token: f64) -> Selfb {
62 let ip = ip.into();
63 let request = self.fixed_bucket(ip.clone());
64 if request {
65 self.bucket_update(ip.clone());
66 let (tokens, _) = self.last_update.get_mut(&ip).unwrap();
67 if *tokens >= token {
68 *tokens -= token;
69 Selfb {
70 is_allowed: true,
71 remaning_count: *tokens as u64,
72 }
73 } else {
74 Selfb {
75 is_allowed: false,
76 remaning_count: *tokens as u64,
77 }
78 }
79 } else {
80 Selfb {
81 is_allowed: false,
82 remaning_count: 0,
83 }
84 }
85 }
86}