@@ -2,21 +2,22 @@ use std::collections::VecDeque;
2
2
use std:: io:: Cursor ;
3
3
use std:: io:: Read as _;
4
4
5
+ use re_build_info:: CrateVersion ;
6
+ use re_log_types:: LogMsg ;
7
+
5
8
use crate :: EncodingOptions ;
6
9
use crate :: FileHeader ;
7
10
use crate :: Serializer ;
8
11
use crate :: app_id_injector:: CachingApplicationIdInjector ;
9
12
use crate :: decoder:: options_from_bytes;
10
- use re_build_info:: CrateVersion ;
11
- use re_log_types:: LogMsg ;
12
13
13
14
use super :: DecodeError ;
14
15
15
- /// The stream decoder is a state machine which ingests byte chunks
16
- /// and outputs messages once it has enough data to deserialize one.
16
+ /// The stream decoder is a state machine which ingests byte chunks and outputs messages once it
17
+ /// has enough data to deserialize one.
17
18
///
18
- /// Chunks are given to the stream via `StreamDecoder::push_chunk`,
19
- /// and messages are read back via `StreamDecoder::try_read`.
19
+ /// Byte chunks are given to the stream via [ `StreamDecoder::push_byte_chunk`], and messages are read
20
+ /// back via [ `StreamDecoder::try_read`] .
20
21
pub struct StreamDecoder {
21
22
/// The Rerun version used to encode the RRD data.
22
23
///
@@ -25,10 +26,10 @@ pub struct StreamDecoder {
25
26
26
27
options : EncodingOptions ,
27
28
28
- /// Incoming chunks are stored here
29
- chunks : ChunkBuffer ,
29
+ /// Incoming byte chunks are stored here.
30
+ byte_chunks : ByteChunkBuffer ,
30
31
31
- /// The stream state
32
+ /// The stream state.
32
33
state : State ,
33
34
34
35
/// The application id cache used for migrating old data.
@@ -49,20 +50,19 @@ pub struct StreamDecoder {
49
50
enum State {
50
51
/// The beginning of the stream.
51
52
///
52
- /// The stream header contains the magic bytes (e.g. `RRF2`),
53
- /// the encoded version, and the encoding options.
53
+ /// The stream header contains the magic bytes (e.g. `RRF2`), the encoded version, and the
54
+ /// encoding options.
54
55
///
55
- /// After the stream header is read once, the state machine
56
- /// will only ever switch between `MessageHeader` and `Message`
56
+ /// After the stream header is read once, the state machine will only ever switch between
57
+ /// `MessageHeader` and `Message`
57
58
StreamHeader ,
58
59
59
60
/// The beginning of a Protobuf message.
60
61
MessageHeader ,
61
62
62
63
/// The message content, serialized using `Protobuf`.
63
64
///
64
- /// Compression is only applied to individual `ArrowMsg`s, instead of
65
- /// the entire stream.
65
+ /// Compression is only applied to individual `ArrowMsg`s, instead of the entire stream.
66
66
Message ( crate :: codec:: file:: MessageHeader ) ,
67
67
68
68
/// Stop reading
@@ -74,17 +74,17 @@ impl StreamDecoder {
74
74
pub fn new ( ) -> Self {
75
75
Self {
76
76
version : None ,
77
- // Note: `options` are filled in once we read `FileHeader`,
78
- // so this value does not matter.
77
+ // Note: `options` are filled in once we read `FileHeader`, so this value does not matter.
79
78
options : EncodingOptions :: PROTOBUF_UNCOMPRESSED ,
80
- chunks : ChunkBuffer :: new ( ) ,
79
+ byte_chunks : ByteChunkBuffer :: new ( ) ,
81
80
state : State :: StreamHeader ,
82
81
app_id_cache : CachingApplicationIdInjector :: default ( ) ,
83
82
}
84
83
}
85
84
86
- pub fn push_chunk ( & mut self , chunk : Vec < u8 > ) {
87
- self . chunks . push ( chunk) ;
85
+ /// Feed a bunch of bytes to the decoding state machine.
86
+ pub fn push_byte_chunk ( & mut self , byte_chunk : Vec < u8 > ) {
87
+ self . byte_chunks . push ( byte_chunk) ;
88
88
}
89
89
90
90
/// Read the next message in the stream, dropping messages missing application id that cannot
@@ -112,8 +112,8 @@ impl StreamDecoder {
112
112
fn try_read_impl ( & mut self ) -> Result < Option < LogMsg > , DecodeError > {
113
113
match self . state {
114
114
State :: StreamHeader => {
115
- let is_first_header = self . chunks . num_read ( ) == 0 ;
116
- if let Some ( header) = self . chunks . try_read ( FileHeader :: SIZE ) {
115
+ let is_first_header = self . byte_chunks . num_read ( ) == 0 ;
116
+ if let Some ( header) = self . byte_chunks . try_read ( FileHeader :: SIZE ) {
117
117
re_log:: trace!( ?header, "Decoding StreamHeader" ) ;
118
118
119
119
// header contains version and compression options
@@ -144,29 +144,30 @@ impl StreamDecoder {
144
144
Serializer :: Protobuf => self . state = State :: MessageHeader ,
145
145
}
146
146
147
- // we might have data left in the current chunk,
148
- // immediately try to read length of the next message
147
+ // we might have data left in the current byte chunk, immediately try to read
148
+ // length of the next message.
149
149
return self . try_read ( ) ;
150
150
}
151
151
}
152
152
153
153
State :: MessageHeader => {
154
154
if let Some ( bytes) = self
155
- . chunks
155
+ . byte_chunks
156
156
. try_read ( crate :: codec:: file:: MessageHeader :: SIZE_BYTES )
157
157
{
158
158
let header = crate :: codec:: file:: MessageHeader :: from_bytes ( bytes) ?;
159
159
160
160
re_log:: trace!( ?header, "MessageHeader" ) ;
161
161
162
162
self . state = State :: Message ( header) ;
163
- // we might have data left in the current chunk,
164
- // immediately try to read the message content
163
+ // we might have data left in the current byte chunk, immediately try to read
164
+ // the message content.
165
165
return self . try_read ( ) ;
166
166
}
167
167
}
168
+
168
169
State :: Message ( header) => {
169
- if let Some ( bytes) = self . chunks . try_read ( header. len as usize ) {
170
+ if let Some ( bytes) = self . byte_chunks . try_read ( header. len as usize ) {
170
171
re_log:: trace!( ?header, "Read message" ) ;
171
172
172
173
let message = crate :: codec:: file:: decoder:: decode_bytes_to_app (
@@ -217,14 +218,15 @@ fn propagate_version(message: &mut LogMsg, version: Option<CrateVersion>) {
217
218
}
218
219
}
219
220
220
- type Chunk = Cursor < Vec < u8 > > ;
221
+ /// A bunch of contiguous bytes.
222
+ type ByteChunk = Cursor < Vec < u8 > > ;
221
223
222
- struct ChunkBuffer {
223
- /// Any incoming chunks are queued until they are emptied
224
- queue : VecDeque < Chunk > ,
224
+ struct ByteChunkBuffer {
225
+ /// Any incoming byte chunks are queued until they are emptied.
226
+ queue : VecDeque < ByteChunk > ,
225
227
226
- /// This buffer is used as scratch space for any read bytes,
227
- /// so that we can return a contiguous slice from `try_read`.
228
+ /// This buffer is used as scratch space for any read bytes, so that we can return a contiguous
229
+ /// slice from `try_read`.
228
230
buffer : Vec < u8 > ,
229
231
230
232
/// How many bytes of valid data are currently in `self.buffer`.
@@ -234,7 +236,7 @@ struct ChunkBuffer {
234
236
num_read : usize ,
235
237
}
236
238
237
- impl ChunkBuffer {
239
+ impl ByteChunkBuffer {
238
240
fn new ( ) -> Self {
239
241
Self {
240
242
queue : VecDeque :: with_capacity ( 16 ) ,
@@ -244,19 +246,19 @@ impl ChunkBuffer {
244
246
}
245
247
}
246
248
247
- fn push ( & mut self , chunk : Vec < u8 > ) {
248
- if chunk . is_empty ( ) {
249
+ fn push ( & mut self , byte_chunk : Vec < u8 > ) {
250
+ if byte_chunk . is_empty ( ) {
249
251
return ;
250
252
}
251
- self . queue . push_back ( Chunk :: new ( chunk ) ) ;
253
+ self . queue . push_back ( ByteChunk :: new ( byte_chunk ) ) ;
252
254
}
253
255
254
256
/// How many bytes have been read with [`Self::try_read`] so far?
255
257
fn num_read ( & self ) -> usize {
256
258
self . num_read
257
259
}
258
260
259
- /// Attempt to read exactly `n` bytes out of the queued chunks.
261
+ /// Attempt to read exactly `n` bytes out of the queued byte chunks.
260
262
///
261
263
/// Returns `None` if there is not enough data to return a slice of `n` bytes.
262
264
///
@@ -276,13 +278,15 @@ impl ChunkBuffer {
276
278
// try to read some bytes from the front of the queue,
277
279
// until either:
278
280
// - we've read enough to return a slice of `n` bytes
279
- // - we run out of chunks to read
280
- // while also discarding any empty chunks
281
+ // - we run out of byte chunks to read
282
+ // while also discarding any empty byte chunks
281
283
while self . buffer_fill != n {
282
- if let Some ( chunk ) = self . queue . front_mut ( ) {
284
+ if let Some ( byte_chunk ) = self . queue . front_mut ( ) {
283
285
let remainder = & mut self . buffer [ self . buffer_fill ..] ;
284
- self . buffer_fill += chunk. read ( remainder) . expect ( "failed to read from chunk" ) ;
285
- if is_chunk_empty ( chunk) {
286
+ self . buffer_fill += byte_chunk
287
+ . read ( remainder)
288
+ . expect ( "failed to read from byte chunk" ) ;
289
+ if is_byte_chunk_empty ( byte_chunk) {
286
290
self . queue . pop_front ( ) ;
287
291
}
288
292
} else {
@@ -303,8 +307,8 @@ impl ChunkBuffer {
303
307
}
304
308
}
305
309
306
- fn is_chunk_empty ( chunk : & Chunk ) -> bool {
307
- chunk . position ( ) >= chunk . get_ref ( ) . len ( ) as u64
310
+ fn is_byte_chunk_empty ( byte_chunk : & ByteChunk ) -> bool {
311
+ byte_chunk . position ( ) >= byte_chunk . get_ref ( ) . len ( ) as u64
308
312
}
309
313
310
314
#[ cfg( test) ]
@@ -381,7 +385,7 @@ mod tests {
381
385
382
386
assert_message_incomplete ! ( decoder. try_read( ) ) ;
383
387
384
- decoder. push_chunk ( data) ;
388
+ decoder. push_byte_chunk ( data) ;
385
389
386
390
let decoded_messages: Vec < _ > = ( 0 ..16 )
387
391
. map ( |_| assert_message_ok ! ( decoder. try_read( ) ) )
@@ -398,8 +402,8 @@ mod tests {
398
402
399
403
assert_message_incomplete ! ( decoder. try_read( ) ) ;
400
404
401
- for chunk in data. chunks ( 1 ) {
402
- decoder. push_chunk ( chunk . to_vec ( ) ) ;
405
+ for byte_chunk in data. chunks ( 1 ) {
406
+ decoder. push_byte_chunk ( byte_chunk . to_vec ( ) ) ;
403
407
}
404
408
405
409
let decoded_messages: Vec < _ > = ( 0 ..16 )
@@ -419,8 +423,8 @@ mod tests {
419
423
420
424
assert_message_incomplete ! ( decoder. try_read( ) ) ;
421
425
422
- decoder. push_chunk ( data1) ;
423
- decoder. push_chunk ( data2) ;
426
+ decoder. push_byte_chunk ( data1) ;
427
+ decoder. push_byte_chunk ( data2) ;
424
428
425
429
let decoded_messages: Vec < _ > = ( 0 ..32 )
426
430
. map ( |_| assert_message_ok ! ( decoder. try_read( ) ) )
@@ -437,7 +441,7 @@ mod tests {
437
441
438
442
assert_message_incomplete ! ( decoder. try_read( ) ) ;
439
443
440
- decoder. push_chunk ( data) ;
444
+ decoder. push_byte_chunk ( data) ;
441
445
442
446
let decoded_messages: Vec < _ > = ( 0 ..16 )
443
447
. map ( |_| assert_message_ok ! ( decoder. try_read( ) ) )
@@ -454,8 +458,8 @@ mod tests {
454
458
455
459
assert_message_incomplete ! ( decoder. try_read( ) ) ;
456
460
457
- for chunk in data. chunks ( 1 ) {
458
- decoder. push_chunk ( chunk . to_vec ( ) ) ;
461
+ for byte_chunk in data. chunks ( 1 ) {
462
+ decoder. push_byte_chunk ( byte_chunk . to_vec ( ) ) ;
459
463
}
460
464
461
465
let decoded_messages: Vec < _ > = ( 0 ..16 )
@@ -474,11 +478,11 @@ mod tests {
474
478
475
479
// keep pushing 3 chunks of 16 bytes at a time, and attempting to read messages
476
480
// until there are no more chunks
477
- let mut chunks = data. chunks ( 16 ) . peekable ( ) ;
478
- while chunks . peek ( ) . is_some ( ) {
481
+ let mut byte_chunks = data. chunks ( 16 ) . peekable ( ) ;
482
+ while byte_chunks . peek ( ) . is_some ( ) {
479
483
for _ in 0 ..3 {
480
- if let Some ( chunk ) = chunks . next ( ) {
481
- decoder. push_chunk ( chunk . to_vec ( ) ) ;
484
+ if let Some ( byte_chunk ) = byte_chunks . next ( ) {
485
+ decoder. push_byte_chunk ( byte_chunk . to_vec ( ) ) ;
482
486
} else {
483
487
break ;
484
488
}
@@ -494,15 +498,15 @@ mod tests {
494
498
495
499
#[ test]
496
500
fn stream_irregular_chunks_protobuf ( ) {
497
- // this attempts to stress-test `try_read` with chunks of various sizes
501
+ // this attempts to stress-test `try_read` with byte chunks of various sizes
498
502
499
503
let ( input, data) = test_data ( EncodingOptions :: PROTOBUF_COMPRESSED , 16 ) ;
500
504
let mut data = Cursor :: new ( data) ;
501
505
502
506
let mut decoder = StreamDecoder :: new ( ) ;
503
507
let mut decoded_messages = vec ! [ ] ;
504
508
505
- // read chunks 2xN bytes at a time, where `N` comes from a regular pattern
509
+ // read byte chunks 2xN bytes at a time, where `N` comes from a regular pattern
506
510
// this is slightly closer to using random numbers while still being
507
511
// fully deterministic
508
512
@@ -514,7 +518,7 @@ mod tests {
514
518
for _ in 0 ..2 {
515
519
let n = data. read ( & mut temp[ ..pattern[ pattern_index] ] ) . unwrap ( ) ;
516
520
pattern_index = ( pattern_index + 1 ) % pattern. len ( ) ;
517
- decoder. push_chunk ( temp[ ..n] . to_vec ( ) ) ;
521
+ decoder. push_byte_chunk ( temp[ ..n] . to_vec ( ) ) ;
518
522
}
519
523
520
524
while let Some ( message) = decoder. try_read ( ) . unwrap ( ) {
@@ -527,9 +531,9 @@ mod tests {
527
531
528
532
#[ test]
529
533
fn chunk_buffer_read_single_chunk ( ) {
530
- // reading smaller `n` from multiple larger chunks
534
+ // reading smaller `n` from multiple larger byte chunks
531
535
532
- let mut buffer = ChunkBuffer :: new ( ) ;
536
+ let mut buffer = ByteChunkBuffer :: new ( ) ;
533
537
534
538
let data = & [ 0 , 1 , 2 , 3 , 4 ] ;
535
539
assert_eq ! ( None , buffer. try_read( 1 ) ) ;
@@ -541,16 +545,16 @@ mod tests {
541
545
542
546
#[ test]
543
547
fn chunk_buffer_read_multi_chunk ( ) {
544
- // reading a large `n` from multiple smaller chunks
548
+ // reading a large `n` from multiple smaller byte chunks
545
549
546
- let mut buffer = ChunkBuffer :: new ( ) ;
550
+ let mut buffer = ByteChunkBuffer :: new ( ) ;
547
551
548
- let chunks : & [ & [ u8 ] ] = & [ & [ 0 , 1 , 2 ] , & [ 3 , 4 ] ] ;
552
+ let byte_chunks : & [ & [ u8 ] ] = & [ & [ 0 , 1 , 2 ] , & [ 3 , 4 ] ] ;
549
553
550
554
assert_eq ! ( None , buffer. try_read( 1 ) ) ;
551
- buffer. push ( chunks [ 0 ] . to_vec ( ) ) ;
555
+ buffer. push ( byte_chunks [ 0 ] . to_vec ( ) ) ;
552
556
assert_eq ! ( None , buffer. try_read( 5 ) ) ;
553
- buffer. push ( chunks [ 1 ] . to_vec ( ) ) ;
557
+ buffer. push ( byte_chunks [ 1 ] . to_vec ( ) ) ;
554
558
assert_eq ! ( Some ( & [ 0 , 1 , 2 , 3 , 4 ] [ ..] ) , buffer. try_read( 5 ) ) ;
555
559
assert_eq ! ( None , buffer. try_read( 1 ) ) ;
556
560
}
@@ -559,7 +563,7 @@ mod tests {
559
563
fn chunk_buffer_read_same_n ( ) {
560
564
// reading the same `n` multiple times should not return the same bytes
561
565
562
- let mut buffer = ChunkBuffer :: new ( ) ;
566
+ let mut buffer = ByteChunkBuffer :: new ( ) ;
563
567
564
568
let data = & [ 0 , 1 , 2 , 3 ] ;
565
569
buffer. push ( data. to_vec ( ) ) ;
0 commit comments