1use bytes::{Buf, BufMut};
4
5use crate::{
6 Decode, Encode, ProtocolError, UnknownTaggedFields,
7 primitives::{
8 fixed::{get_bool, get_i8, get_i32, get_i64, put_bool, put_i8, put_i32, put_i64},
9 string_bytes::{
10 compact_nullable_bytes_len, get_compact_nullable_bytes_owned, get_nullable_bytes_owned,
11 nullable_bytes_len, put_compact_nullable_bytes, put_nullable_bytes,
12 },
13 },
14 tagged_fields::{WriteTaggedFields, encode_to_bytes, read_tagged_fields, tagged_fields_len},
15};
16pub const MIN_VERSION: i16 = 0;
17pub const MAX_VERSION: i16 = 0;
18pub const FLEXIBLE_MIN: i16 = 0;
19#[inline]
20#[must_use]
21pub fn is_flexible(version: i16) -> bool {
22 version >= FLEXIBLE_MIN
23}
24#[derive(Debug, Clone, PartialEq, Eq, Default)]
25pub struct RemoteLogSegmentMetadataSnapshotRecord {
26 pub segment_id: crate::primitives::uuid::Uuid,
27 pub start_offset: i64,
28 pub end_offset: i64,
29 pub broker_id: i32,
30 pub max_timestamp_ms: i64,
31 pub event_timestamp_ms: i64,
32 pub segment_leader_epochs: Vec<SegmentLeaderEpochEntry>,
33 pub segment_size_in_bytes: i32,
34 pub custom_metadata: Option<::bytes::Bytes>,
35 pub remote_log_segment_state: i8,
36 pub txn_index_empty: bool,
37 pub unknown_tagged_fields: UnknownTaggedFields,
38}
39impl RemoteLogSegmentMetadataSnapshotRecord {
40 fn encode_field_0<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
41 if version >= 0 {
42 crate::primitives::uuid::put_uuid(buf, self.segment_id);
43 }
44 }
45 fn encode_field_1<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
46 if version >= 0 {
47 put_i64(buf, self.start_offset);
48 }
49 }
50 fn encode_field_2<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
51 if version >= 0 {
52 put_i64(buf, self.end_offset);
53 }
54 }
55 fn encode_field_3<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
56 if version >= 0 {
57 put_i32(buf, self.broker_id);
58 }
59 }
60 fn encode_field_4<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
61 if version >= 0 {
62 put_i64(buf, self.max_timestamp_ms);
63 }
64 }
65 fn encode_field_5<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
66 if version >= 0 {
67 put_i64(buf, self.event_timestamp_ms);
68 }
69 }
70 fn encode_field_6<B: BufMut>(
71 &self,
72 buf: &mut B,
73 version: i16,
74 flex: bool,
75 ) -> Result<(), ProtocolError> {
76 if version >= 0 {
77 {
78 crate::primitives::array::put_array_len(
79 buf,
80 (self.segment_leader_epochs).len(),
81 flex,
82 );
83 for it in &self.segment_leader_epochs {
84 it.encode(buf, version)?;
85 }
86 };
87 }
88 Ok(())
89 }
90 fn encode_field_7<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
91 if version >= 0 {
92 put_i32(buf, self.segment_size_in_bytes);
93 }
94 }
95 fn encode_field_8<B: BufMut>(&self, buf: &mut B, version: i16, flex: bool) {
96 if version >= 0 {
97 if flex {
98 let () = put_compact_nullable_bytes(buf, self.custom_metadata.as_deref());
99 } else {
100 let () = put_nullable_bytes(buf, self.custom_metadata.as_deref());
101 }
102 }
103 }
104 fn encode_field_9<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
105 if version >= 0 {
106 put_i8(buf, self.remote_log_segment_state);
107 }
108 }
109 fn encode_tagged_fields<B: BufMut>(&self, buf: &mut B, _version: i16, flex: bool) {
110 if flex {
111 let mut tagged = WriteTaggedFields::new();
112 if !(crate::codegen_helpers::is_default(&self.txn_index_empty)) {
113 let payload = encode_to_bytes(1, |b| {
114 put_bool(b, self.txn_index_empty);
115 Ok(())
116 });
117 tagged.add(0, payload);
118 }
119 tagged.write(buf, &self.unknown_tagged_fields);
120 }
121 }
122 fn decode_field_0<B: Buf>(
123 out: &mut Self,
124 buf: &mut B,
125 version: i16,
126 _flex: bool,
127 ) -> Result<(), ProtocolError> {
128 if version >= 0 {
129 out.segment_id = crate::primitives::uuid::get_uuid(buf)?;
130 }
131 Ok(())
132 }
133 fn decode_field_1<B: Buf>(
134 out: &mut Self,
135 buf: &mut B,
136 version: i16,
137 _flex: bool,
138 ) -> Result<(), ProtocolError> {
139 if version >= 0 {
140 out.start_offset = get_i64(buf)?;
141 }
142 Ok(())
143 }
144 fn decode_field_2<B: Buf>(
145 out: &mut Self,
146 buf: &mut B,
147 version: i16,
148 _flex: bool,
149 ) -> Result<(), ProtocolError> {
150 if version >= 0 {
151 out.end_offset = get_i64(buf)?;
152 }
153 Ok(())
154 }
155 fn decode_field_3<B: Buf>(
156 out: &mut Self,
157 buf: &mut B,
158 version: i16,
159 _flex: bool,
160 ) -> Result<(), ProtocolError> {
161 if version >= 0 {
162 out.broker_id = get_i32(buf)?;
163 }
164 Ok(())
165 }
166 fn decode_field_4<B: Buf>(
167 out: &mut Self,
168 buf: &mut B,
169 version: i16,
170 _flex: bool,
171 ) -> Result<(), ProtocolError> {
172 if version >= 0 {
173 out.max_timestamp_ms = get_i64(buf)?;
174 }
175 Ok(())
176 }
177 fn decode_field_5<B: Buf>(
178 out: &mut Self,
179 buf: &mut B,
180 version: i16,
181 _flex: bool,
182 ) -> Result<(), ProtocolError> {
183 if version >= 0 {
184 out.event_timestamp_ms = get_i64(buf)?;
185 }
186 Ok(())
187 }
188 fn decode_field_6<B: Buf>(
189 out: &mut Self,
190 buf: &mut B,
191 version: i16,
192 flex: bool,
193 ) -> Result<(), ProtocolError> {
194 if version >= 0 {
195 out.segment_leader_epochs = {
196 let n = crate::primitives::array::get_array_len(buf, flex)?;
197 let mut v = Vec::with_capacity(n);
198 for _ in 0..n {
199 v.push(SegmentLeaderEpochEntry::decode(buf, version)?);
200 }
201 v
202 };
203 }
204 Ok(())
205 }
206 fn decode_field_7<B: Buf>(
207 out: &mut Self,
208 buf: &mut B,
209 version: i16,
210 _flex: bool,
211 ) -> Result<(), ProtocolError> {
212 if version >= 0 {
213 out.segment_size_in_bytes = get_i32(buf)?;
214 }
215 Ok(())
216 }
217 fn decode_field_8<B: Buf>(
218 out: &mut Self,
219 buf: &mut B,
220 version: i16,
221 flex: bool,
222 ) -> Result<(), ProtocolError> {
223 if version >= 0 {
224 out.custom_metadata = if flex {
225 get_compact_nullable_bytes_owned(buf)?
226 } else {
227 get_nullable_bytes_owned(buf)?
228 };
229 }
230 Ok(())
231 }
232 fn decode_field_9<B: Buf>(
233 out: &mut Self,
234 buf: &mut B,
235 version: i16,
236 _flex: bool,
237 ) -> Result<(), ProtocolError> {
238 if version >= 0 {
239 out.remote_log_segment_state = get_i8(buf)?;
240 }
241 Ok(())
242 }
243 fn decode_tagged_fields<B: Buf>(
244 out: &mut Self,
245 buf: &mut B,
246 _version: i16,
247 flex: bool,
248 ) -> Result<(), ProtocolError> {
249 if flex {
250 let mut tag_txn_index_empty = None;
251 out.unknown_tagged_fields = read_tagged_fields(buf, |tag, payload| match tag {
252 0 => {
253 tag_txn_index_empty = Some({
254 let b: &mut &[u8] = payload;
255 get_bool(b)?
256 });
257 Ok(true)
258 }
259 _ => Ok(false),
260 })?;
261 if let Some(v) = tag_txn_index_empty {
262 out.txn_index_empty = v;
263 }
264 }
265 Ok(())
266 }
267}
268impl Encode for RemoteLogSegmentMetadataSnapshotRecord {
269 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
270 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
271 return Err(ProtocolError::SchemaMismatch(
272 "RemoteLogSegmentMetadataSnapshotRecord version out of range",
273 ));
274 }
275 let flex = is_flexible(version);
276 self.encode_field_0(buf, version, flex);
277 self.encode_field_1(buf, version, flex);
278 self.encode_field_2(buf, version, flex);
279 self.encode_field_3(buf, version, flex);
280 self.encode_field_4(buf, version, flex);
281 self.encode_field_5(buf, version, flex);
282 self.encode_field_6(buf, version, flex)?;
283 self.encode_field_7(buf, version, flex);
284 self.encode_field_8(buf, version, flex);
285 self.encode_field_9(buf, version, flex);
286 self.encode_tagged_fields(buf, version, flex);
287 Ok(())
288 }
289 fn encoded_len(&self, version: i16) -> usize {
290 let flex = is_flexible(version);
291 let mut n: usize = 0;
292 if version >= 0 {
293 n += 16;
294 }
295 if version >= 0 {
296 n += 8;
297 }
298 if version >= 0 {
299 n += 8;
300 }
301 if version >= 0 {
302 n += 4;
303 }
304 if version >= 0 {
305 n += 8;
306 }
307 if version >= 0 {
308 n += 8;
309 }
310 if version >= 0 {
311 n += {
312 let prefix = crate::primitives::array::array_len_prefix_len(
313 (self.segment_leader_epochs).len(),
314 flex,
315 );
316 let body: usize = (self.segment_leader_epochs)
317 .iter()
318 .map(|it| it.encoded_len(version))
319 .sum();
320 prefix + body
321 };
322 }
323 if version >= 0 {
324 n += 4;
325 }
326 if version >= 0 {
327 n += if flex {
328 compact_nullable_bytes_len(self.custom_metadata.as_deref())
329 } else {
330 nullable_bytes_len(self.custom_metadata.as_deref())
331 };
332 }
333 if version >= 0 {
334 n += 1;
335 }
336 if flex {
337 let mut known_pairs: Vec<(u32, usize)> = Vec::new();
338 if !(crate::codegen_helpers::is_default(&self.txn_index_empty)) {
339 known_pairs.push((0, 1));
340 }
341 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
342 }
343 n
344 }
345}
346impl Decode<'_> for RemoteLogSegmentMetadataSnapshotRecord {
347 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
348 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
349 return Err(ProtocolError::SchemaMismatch(
350 "RemoteLogSegmentMetadataSnapshotRecord version out of range",
351 ));
352 }
353 let flex = is_flexible(version);
354 let mut out = Self::default();
355 Self::decode_field_0(&mut out, buf, version, flex)?;
356 Self::decode_field_1(&mut out, buf, version, flex)?;
357 Self::decode_field_2(&mut out, buf, version, flex)?;
358 Self::decode_field_3(&mut out, buf, version, flex)?;
359 Self::decode_field_4(&mut out, buf, version, flex)?;
360 Self::decode_field_5(&mut out, buf, version, flex)?;
361 Self::decode_field_6(&mut out, buf, version, flex)?;
362 Self::decode_field_7(&mut out, buf, version, flex)?;
363 Self::decode_field_8(&mut out, buf, version, flex)?;
364 Self::decode_field_9(&mut out, buf, version, flex)?;
365 Self::decode_tagged_fields(&mut out, buf, version, flex)?;
366 Ok(out)
367 }
368}
369#[cfg(test)]
370impl RemoteLogSegmentMetadataSnapshotRecord {
371 #[must_use]
372 pub fn populated(version: i16) -> Self {
373 let mut m = Self::default();
374 if version >= 0 {
375 m.segment_id = crate::primitives::uuid::Uuid([1u8; 16]);
376 }
377 if version >= 0 {
378 m.start_offset = 1i64;
379 }
380 if version >= 0 {
381 m.end_offset = 1i64;
382 }
383 if version >= 0 {
384 m.broker_id = 1i32;
385 }
386 if version >= 0 {
387 m.max_timestamp_ms = 1i64;
388 }
389 if version >= 0 {
390 m.event_timestamp_ms = 1i64;
391 }
392 if version >= 0 {
393 m.segment_leader_epochs = vec![SegmentLeaderEpochEntry::populated(version)];
394 }
395 if version >= 0 {
396 m.segment_size_in_bytes = 1i32;
397 }
398 if version >= 0 {
399 m.custom_metadata = Some(::bytes::Bytes::from_static(b"x"));
400 }
401 if version >= 0 {
402 m.remote_log_segment_state = 1i8;
403 }
404 if version >= 0 {
405 m.txn_index_empty = true;
406 }
407 m
408 }
409}
410#[derive(Debug, Clone, PartialEq, Eq, Default)]
411pub struct SegmentLeaderEpochEntry {
412 pub leader_epoch: i32,
413 pub offset: i64,
414 pub unknown_tagged_fields: UnknownTaggedFields,
415}
416impl Encode for SegmentLeaderEpochEntry {
417 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
418 let flex = version >= 0;
419 if version >= 0 {
420 put_i32(buf, self.leader_epoch);
421 }
422 if version >= 0 {
423 put_i64(buf, self.offset);
424 }
425 if flex {
426 let tagged = WriteTaggedFields::new();
427 tagged.write(buf, &self.unknown_tagged_fields);
428 }
429 Ok(())
430 }
431 fn encoded_len(&self, version: i16) -> usize {
432 let flex = version >= 0;
433 let mut n: usize = 0;
434 if version >= 0 {
435 n += 4;
436 }
437 if version >= 0 {
438 n += 8;
439 }
440 if flex {
441 let known_pairs: Vec<(u32, usize)> = Vec::new();
442 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
443 }
444 n
445 }
446}
447impl Decode<'_> for SegmentLeaderEpochEntry {
448 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
449 let flex = version >= 0;
450 let mut out = Self::default();
451 if version >= 0 {
452 out.leader_epoch = get_i32(buf)?;
453 }
454 if version >= 0 {
455 out.offset = get_i64(buf)?;
456 }
457 if flex {
458 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
459 }
460 Ok(out)
461 }
462}
463#[cfg(test)]
464impl SegmentLeaderEpochEntry {
465 #[must_use]
466 pub fn populated(version: i16) -> Self {
467 let mut m = Self::default();
468 if version >= 0 {
469 m.leader_epoch = 1i32;
470 }
471 if version >= 0 {
472 m.offset = 1i64;
473 }
474 m
475 }
476}
477#[must_use]
480#[allow(unused_comparisons)]
481pub fn default_json(_version: i16) -> ::serde_json::Value {
482 let mut obj = ::serde_json::Map::new();
483 obj.insert(
484 "segmentId".to_string(),
485 ::serde_json::Value::String("AAAAAAAAAAAAAAAAAAAAAA".to_string()),
486 );
487 obj.insert("startOffset".to_string(), ::serde_json::json!(0));
488 obj.insert("endOffset".to_string(), ::serde_json::json!(0));
489 obj.insert("brokerId".to_string(), ::serde_json::json!(0));
490 obj.insert("maxTimestampMs".to_string(), ::serde_json::json!(0));
491 obj.insert("eventTimestampMs".to_string(), ::serde_json::json!(0));
492 obj.insert(
493 "segmentLeaderEpochs".to_string(),
494 ::serde_json::Value::Array(vec![]),
495 );
496 obj.insert("segmentSizeInBytes".to_string(), ::serde_json::json!(0));
497 obj.insert("customMetadata".to_string(), ::serde_json::Value::Null);
498 obj.insert("remoteLogSegmentState".to_string(), ::serde_json::json!(0));
499 obj.insert(
500 "txnIndexEmpty".to_string(),
501 ::serde_json::Value::Bool(false),
502 );
503 ::serde_json::Value::Object(obj)
504}
505#[must_use]
508pub fn tagged_fixture() -> RemoteLogSegmentMetadataSnapshotRecord {
509 RemoteLogSegmentMetadataSnapshotRecord {
510 txn_index_empty: true,
511 ..RemoteLogSegmentMetadataSnapshotRecord::default()
512 }
513}
514#[must_use]
517pub fn tagged_fixture_json(_version: i16) -> ::serde_json::Value {
518 let mut m = ::serde_json::Map::new();
519 m.insert(
520 "segmentId".to_string(),
521 ::serde_json::Value::String("AAAAAAAAAAAAAAAAAAAAAA".to_string()),
522 );
523 m.insert("startOffset".to_string(), ::serde_json::json!(0));
524 m.insert("endOffset".to_string(), ::serde_json::json!(0));
525 m.insert("brokerId".to_string(), ::serde_json::json!(0));
526 m.insert("maxTimestampMs".to_string(), ::serde_json::json!(0));
527 m.insert("eventTimestampMs".to_string(), ::serde_json::json!(0));
528 m.insert(
529 "segmentLeaderEpochs".to_string(),
530 ::serde_json::Value::Array(vec![]),
531 );
532 m.insert("segmentSizeInBytes".to_string(), ::serde_json::json!(0));
533 m.insert("customMetadata".to_string(), ::serde_json::Value::Null);
534 m.insert("remoteLogSegmentState".to_string(), ::serde_json::json!(0));
535 m.insert("txnIndexEmpty".to_string(), ::serde_json::Value::Bool(true));
536 ::serde_json::Value::Object(m)
537}