cubecl_server/memory_management/drop_queue/
policy.rs1use cubecl_common::bytes::Bytes;
2
3#[derive(Debug)]
9pub struct FlushingPolicy {
10 pub max_bytes_count: u32,
12 pub max_bytes_size: u32,
14}
15
16impl Default for FlushingPolicy {
17 fn default() -> Self {
18 Self {
19 max_bytes_count: 64,
20 max_bytes_size: 64 * 1024 * 1024, }
22 }
23}
24
25#[derive(Default, Debug)]
27pub(crate) struct FlushingPolicyState {
28 bytes_count: u32,
29 bytes_size: u32,
30}
31
32impl FlushingPolicyState {
33 pub(crate) fn register(&mut self, bytes: &Bytes) {
35 self.bytes_count = self.bytes_count.saturating_add(1);
36 self.bytes_size = self
37 .bytes_size
38 .saturating_add(u32::try_from(bytes.len()).unwrap_or(u32::MAX));
39 }
40
41 pub(crate) fn reset(&mut self) {
43 self.bytes_count = 0;
44 self.bytes_size = 0;
45 }
46
47 pub(crate) fn should_flush(&self, policy: &FlushingPolicy) -> bool {
49 self.bytes_count >= policy.max_bytes_count || self.bytes_size >= policy.max_bytes_size
50 }
51}
52
53#[cfg(test)]
54mod policy_tests {
55 use std::vec;
56
57 use super::*;
58
59 fn policy() -> FlushingPolicy {
60 FlushingPolicy {
61 max_bytes_count: 4,
62 max_bytes_size: 100,
63 }
64 }
65
66 fn state() -> FlushingPolicyState {
67 FlushingPolicyState {
68 bytes_count: 0,
69 bytes_size: 0,
70 }
71 }
72
73 #[test]
74 fn no_flush_when_below_both_thresholds() {
75 let s = state();
76 assert!(!s.should_flush(&policy()));
77 }
78
79 #[test]
80 fn flush_when_count_threshold_reached() {
81 let mut s = state();
82 for _ in 0..4 {
83 s.register(&Bytes::from_elems(vec![0u8]));
84 }
85 assert!(s.should_flush(&policy()));
86 }
87
88 #[test]
89 fn flush_when_size_threshold_reached() {
90 let mut s = state();
91 s.register(&Bytes::from_elems(vec![0u8; 101]));
92 assert!(s.should_flush(&policy()));
93 }
94
95 #[test]
96 fn flush_triggered_by_whichever_limit_comes_first() {
97 let mut s = state();
98 s.register(&Bytes::from_elems(vec![0u8; 60]));
100 s.register(&Bytes::from_elems(vec![0u8; 60]));
101 assert!(s.should_flush(&policy()));
102 }
103
104 #[test]
105 fn register_saturates_instead_of_overflowing() {
106 let mut s = FlushingPolicyState {
109 bytes_count: u32::MAX,
110 bytes_size: u32::MAX - 1,
111 };
112 s.register(&Bytes::from_elems(vec![0u8; 8]));
113 assert_eq!(s.bytes_count, u32::MAX);
114 assert_eq!(s.bytes_size, u32::MAX);
115 assert!(s.should_flush(&policy()));
116 }
117
118 #[test]
119 fn reset_clears_state() {
120 let mut s = state();
121 for _ in 0..4 {
122 s.register(&Bytes::from_elems(vec![0u8]));
123 }
124 assert!(s.should_flush(&policy()));
125 s.reset();
126 assert!(!s.should_flush(&policy()));
127 }
128}