rocketmq_protocol/protocol/body/
epoch_entry_cache.rs1use std::fmt;
16
17use cheetah_string::CheetahString;
18use serde::Deserialize;
19use serde::Serialize;
20
21#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
22#[serde(rename_all = "camelCase")]
23pub struct EpochEntry {
24 #[serde(default)]
25 epoch: i32,
26 #[serde(default)]
27 start_offset: i64,
28 #[serde(default = "EpochEntry::default_end_offset")]
29 end_offset: i64,
30}
31
32impl Default for EpochEntry {
33 fn default() -> Self {
34 Self::new(0, 0)
35 }
36}
37
38impl EpochEntry {
39 fn default_end_offset() -> i64 {
40 i64::MAX
41 }
42
43 pub fn new(epoch: i32, start_offset: i64) -> Self {
44 Self {
45 epoch,
46 start_offset,
47 end_offset: i64::MAX,
48 }
49 }
50
51 pub fn with_end_offset(epoch: i32, start_offset: i64, end_offset: i64) -> Self {
52 Self {
53 epoch,
54 start_offset,
55 end_offset,
56 }
57 }
58
59 pub fn get_epoch(&self) -> i32 {
60 self.epoch
61 }
62
63 pub fn set_epoch(&mut self, epoch: i32) {
64 self.epoch = epoch;
65 }
66
67 pub fn get_start_offset(&self) -> i64 {
68 self.start_offset
69 }
70
71 pub fn set_start_offset(&mut self, start_offset: i64) {
72 self.start_offset = start_offset;
73 }
74
75 pub fn get_end_offset(&self) -> i64 {
76 self.end_offset
77 }
78
79 pub fn set_end_offset(&mut self, end_offset: i64) {
80 self.end_offset = end_offset;
81 }
82}
83
84impl fmt::Display for EpochEntry {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 write!(
87 f,
88 "EpochEntry{{epoch={}, startOffset={}, endOffset={}}}",
89 self.epoch, self.start_offset, self.end_offset
90 )
91 }
92}
93
94#[derive(Deserialize, Serialize, Default)]
95#[serde(rename_all = "camelCase")]
96pub struct EpochEntryCache {
97 cluster_name: CheetahString,
98 broker_name: CheetahString,
99 broker_id: u64,
100 epoch_list: Vec<EpochEntry>,
101 max_offset: u64,
102}
103
104impl EpochEntryCache {
105 pub fn new(
106 cluster_name: impl Into<CheetahString>,
107 broker_name: impl Into<CheetahString>,
108 broker_id: u64,
109 epoch_list: Vec<EpochEntry>,
110 max_offset: u64,
111 ) -> Self {
112 Self {
113 cluster_name: cluster_name.into(),
114 broker_name: broker_name.into(),
115 broker_id,
116 epoch_list,
117 max_offset,
118 }
119 }
120 pub fn get_cluster_name(&self) -> &CheetahString {
121 &self.cluster_name
122 }
123 pub fn set_cluster_name(&mut self, cluster_name: impl Into<CheetahString>) {
124 self.cluster_name = cluster_name.into()
125 }
126 pub fn get_broker_name(&self) -> &CheetahString {
127 &self.broker_name
128 }
129 pub fn set_broker_name(&mut self, broker_name: impl Into<CheetahString>) {
130 self.broker_name = broker_name.into()
131 }
132 pub fn get_broker_id(&self) -> u64 {
133 self.broker_id
134 }
135 pub fn get_epoch_list(&self) -> &Vec<EpochEntry> {
136 &self.epoch_list
137 }
138 pub fn get_epoch_list_mut(&mut self) -> &mut Vec<EpochEntry> {
139 &mut self.epoch_list
140 }
141 pub fn get_max_offset(&self) -> u64 {
142 self.max_offset
143 }
144 pub fn set_max_offset(&mut self, max_offset: u64) {
145 self.max_offset = max_offset;
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use cheetah_string::CheetahString;
152
153 use super::*;
154
155 #[test]
156 fn epoch_entry_default_matches_constructor_and_missing_wire_fields() {
157 let expected = EpochEntry::new(0, 0);
158 assert_eq!(expected.get_end_offset(), i64::MAX);
159 assert_eq!(EpochEntry::default(), expected);
160 assert_eq!(serde_json::from_str::<EpochEntry>("{}").unwrap(), expected);
161 assert_eq!(
162 serde_json::to_value(&expected).unwrap(),
163 serde_json::json!({
164 "epoch": 0, "startOffset": 0, "endOffset": i64::MAX
165 })
166 );
167 for end_offset in [0, 42] {
168 let value = serde_json::json!({"endOffset": end_offset});
169 assert_eq!(
170 serde_json::from_value::<EpochEntry>(value).unwrap(),
171 EpochEntry::with_end_offset(0, 0, end_offset)
172 );
173 }
174 }
175
176 #[test]
177 fn epoch_entry_and_cache_accessors_update_all_fields() {
178 let mut entry = EpochEntry::new(1, 0);
179 assert_eq!(entry.get_end_offset(), i64::MAX);
180 entry.set_epoch(2);
181 entry.set_start_offset(100);
182 entry.set_end_offset(200);
183 assert_eq!(entry.get_epoch(), 2);
184 assert_eq!(entry.get_start_offset(), 100);
185 assert_eq!(entry.get_end_offset(), 200);
186
187 let mut cache = EpochEntryCache::new("cluster1", "broker1", 1, vec![entry], 500);
188 assert_eq!(cache.get_cluster_name(), &CheetahString::from("cluster1"));
189 assert_eq!(cache.get_broker_name(), &CheetahString::from("broker1"));
190 assert_eq!(cache.get_broker_id(), 1);
191 assert_eq!(cache.get_epoch_list().len(), 1);
192 assert_eq!(cache.get_max_offset(), 500);
193
194 cache.set_cluster_name("cluster2");
195 cache.set_broker_name("broker2");
196 cache.set_max_offset(600);
197 cache.get_epoch_list_mut().push(EpochEntry::new(3, 200));
198 assert_eq!(cache.get_cluster_name(), &CheetahString::from("cluster2"));
199 assert_eq!(cache.get_broker_name(), &CheetahString::from("broker2"));
200 assert_eq!(cache.get_max_offset(), 600);
201 assert_eq!(cache.get_epoch_list().len(), 2);
202 }
203
204 #[test]
205 fn epoch_entry_display() {
206 let entry = EpochEntry::with_end_offset(1, 100, 200);
207 assert_eq!(entry.to_string(), "EpochEntry{epoch=1, startOffset=100, endOffset=200}");
208 }
209}