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