@@ -103,12 +103,13 @@ where
103
103
current_baseline : DateTime ,
104
104
}
105
105
106
+ #[ cfg_attr( test, derive( Clone , Debug ) ) ]
106
107
struct Gts {
107
108
pub lower : Option < u64 > ,
108
109
pub upper : Option < u64 > ,
109
110
}
110
111
impl Gts {
111
- const GTS2_SHIFT : usize = 26 ; // see (Appendix D4.2.5).
112
+ const GTS2_SHIFT : u32 = 26 ; // see (Appendix D4.2.5).
112
113
113
114
pub fn replace_lower ( & mut self , new : u64 ) {
114
115
self . lower = match self . lower {
@@ -127,7 +128,12 @@ impl Gts {
127
128
128
129
pub fn merge ( & self ) -> Option < u64 > {
129
130
if let ( Some ( lower) , Some ( upper) ) = ( self . lower , self . upper ) {
130
- Some ( ( upper << Self :: GTS2_SHIFT ) | lower)
131
+ Some (
132
+ upper
133
+ . checked_shl ( Self :: GTS2_SHIFT )
134
+ . expect ( "GTS merge overflow" )
135
+ | lower,
136
+ )
131
137
} else {
132
138
None
133
139
}
@@ -321,6 +327,7 @@ fn calc_offset(ts: u64, prescaler: Option<LocalTimestampOptions>, freq: u32) ->
321
327
let ticks = ts * prescale;
322
328
let seconds = ( 1_f64 / freq as f64 ) * ticks as f64 ;
323
329
330
+ // NOTE(ceil) ...
324
331
chrono:: Duration :: nanoseconds ( ( seconds * 1e9 ) . ceil ( ) as i64 )
325
332
}
326
333
@@ -330,6 +337,15 @@ mod timestamp_utils {
330
337
331
338
#[ test]
332
339
fn gts ( ) {
340
+ let mut gts = Gts {
341
+ lower : Some ( 1 ) , // bit 1
342
+ upper : Some ( 1 ) , // bit 26
343
+ } ;
344
+ assert_eq ! ( gts. merge( ) , Some ( 67108865 ) ) ;
345
+
346
+ gts. replace_lower ( 127 ) ;
347
+ assert_eq ! ( gts. merge( ) , Some ( 67108991 ) ) ;
348
+
333
349
let gts = Gts {
334
350
lower : None ,
335
351
upper : None ,
@@ -413,8 +429,8 @@ mod timestamps {
413
429
TimestampDataRelation :: Sync ,
414
430
) ,
415
431
( TracePacket :: LocalTimestamp2 { ts } , Some ( gts) ) => (
416
- false ,
417
- calc_offset ( gts. merge ( ) . unwrap_or ( 0 ) + ( ts as u64 ) , None , FREQ ) ,
432
+ true ,
433
+ calc_offset ( gts. merge ( ) . unwrap ( ) + ( ts as u64 ) , None , FREQ ) ,
418
434
TimestampDataRelation :: Sync ,
419
435
) ,
420
436
_ => panic ! ( "???" ) ,
@@ -434,8 +450,26 @@ mod timestamps {
434
450
}
435
451
}
436
452
453
+ fn is_sorted_increasing ( timestamps : & [ Timestamp ] ) -> bool {
454
+ let mut it = timestamps. iter ( ) ;
455
+ let mut prev = None ;
456
+ while let Some ( curr) = it. next ( ) {
457
+ if prev. is_none ( ) {
458
+ continue ;
459
+ }
460
+
461
+ if curr < prev. unwrap ( ) {
462
+ return false ;
463
+ }
464
+
465
+ prev = Some ( curr) ;
466
+ }
467
+
468
+ true
469
+ }
470
+
437
471
#[ test]
438
- fn test1 ( ) {
472
+ fn check_timestamps ( ) {
439
473
unsafe {
440
474
BASELINE = Some ( chrono:: DateTime :: < chrono:: Utc > :: from_utc (
441
475
chrono:: NaiveDateTime :: from_timestamp ( 0 , 0 ) ,
@@ -556,25 +590,7 @@ mod timestamps {
556
590
]
557
591
} ;
558
592
559
- // ensure timestamps are in increasing order
560
- // TODO(unstable) replace with slice::is_sorted
561
- assert ! ( || -> bool {
562
- let mut it = timestamps. iter( ) ;
563
- let mut prev = None ;
564
- while let Some ( curr) = it. next( ) {
565
- if prev. is_none( ) {
566
- continue ;
567
- }
568
-
569
- if curr < prev. unwrap( ) {
570
- return false ;
571
- }
572
-
573
- prev = Some ( curr) ;
574
- }
575
-
576
- true
577
- } ( ) ) ;
593
+ assert ! ( is_sorted_increasing( & timestamps) ) ;
578
594
579
595
let mut decoder = Decoder :: new ( stream. clone ( ) , DecoderOptions { ignore_eof : false } ) ;
580
596
let mut it = decoder. timestamps ( TimestampsConfiguration {
@@ -627,64 +643,146 @@ mod timestamps {
627
643
}
628
644
}
629
645
630
- // #[test]
631
- // fn test2() {
632
- // unsafe {
633
- // BASELINE = Some(chrono::DateTime::<chrono::Utc>::from_utc(
634
- // chrono::NaiveDateTime::from_timestamp(0, 0),
635
- // chrono::Utc,
636
- // ));
637
- // }
638
-
639
- // #[rustfmt::skip]
640
- // let stream: &[u8] = &[
641
- // // GTS1
642
- // 0b1001_0100,
643
- // 0b1000_0000,
644
- // 0b1010_0000,
645
- // 0b1000_0100,
646
- // 0b0000_0000,
647
-
648
- // // GTS2 (64-bit)
649
- // 0b1011_0100,
650
- // 0b1011_1101,
651
- // 0b1111_0100,
652
- // 0b1001_0001,
653
- // 0b1000_0001,
654
- // 0b1000_0001,
655
- // 0b0000_0001,
656
-
657
- // // LTS2
658
- // 0b0110_0000,
659
-
660
- // // GTS1 (compressed)
661
- // 0b1001_0100,
662
- // 0b0111_1111,
663
-
664
- // // LTS2
665
- // 0b0110_0000,
666
- // ];
667
-
668
- // let timestamps = {
669
- // let mut offset_sum = chrono::Duration::nanoseconds(0);
670
- // let mut decoder = Decoder::new(stream.clone(), DecoderOptions { ignore_eof: false });
671
- // let mut it = decoder.singles();
672
- // let mut gts = None;
673
- // [
674
- // {
675
- // let gts1 = it.nth(0).unwrap().unwrap();
676
- // let gts2 = it.nth(0).unwrap().unwrap();
677
- // let lts2 = it.nth(0).unwrap().unwrap();
678
- // gts = Gts::from_two(gts1, gts2);
679
-
680
- // outer_calc_offset(lts2, Some(Gts::from_two(gts1, gts2)), &mut offset_sum)
681
- // },
682
- // {
683
- // let gts1 = it.nth(0).unwrap().unwrap();
684
- // let lts2 = it.nth(0).unwrap().unwrap();
685
- // outer_calc_offset(lts2, Some(Gts::from_one(gts1)), &mut offset_sum)
686
- // },
687
- // ]
688
- // };
689
- // }
646
+ #[ test]
647
+ fn gts_compression ( ) {
648
+ unsafe {
649
+ BASELINE = Some ( chrono:: DateTime :: < chrono:: Utc > :: from_utc (
650
+ chrono:: NaiveDateTime :: from_timestamp ( 0 , 0 ) ,
651
+ chrono:: Utc ,
652
+ ) ) ;
653
+ }
654
+
655
+ #[ rustfmt:: skip]
656
+ let stream: & [ u8 ] = & [
657
+ // LTS2
658
+ 0b0110_0000 ,
659
+
660
+ // GTS1 (bit 1 set)
661
+ 0b1001_0100 ,
662
+ 0b1000_0001 ,
663
+ 0b1000_0000 ,
664
+ 0b1000_0000 ,
665
+ 0b0000_0000 ,
666
+
667
+ // GTS2 (64-bit, bit 26 set)
668
+ 0b1011_0100 ,
669
+ 0b1000_0001 ,
670
+ 0b1000_0000 ,
671
+ 0b1000_0000 ,
672
+ 0b1000_0000 ,
673
+ 0b1000_0000 ,
674
+ 0b0000_0000 ,
675
+
676
+ // LTS2
677
+ 0b0110_0000 ,
678
+
679
+ // GTS1 (compressed)
680
+ 0b1001_0100 ,
681
+ 0b1111_1111 ,
682
+ 0b0000_0000 ,
683
+
684
+ // LTS2
685
+ 0b0110_0000 ,
686
+ ] ;
687
+
688
+ let timestamps = {
689
+ let mut offset_sum = chrono:: Duration :: nanoseconds ( 0 ) ;
690
+ let mut decoder = Decoder :: new ( stream. clone ( ) , DecoderOptions { ignore_eof : false } ) ;
691
+ let mut it = decoder. singles ( ) ;
692
+ let mut gts: Option < Gts > = None ;
693
+ [
694
+ (
695
+ {
696
+ let lts2 = it. nth ( 0 ) . unwrap ( ) . unwrap ( ) ;
697
+
698
+ outer_calc_offset ( lts2, None , & mut offset_sum)
699
+ } ,
700
+ chrono:: Duration :: nanoseconds ( 375 ) ,
701
+ ) ,
702
+ (
703
+ {
704
+ let gts1 = it. nth ( 0 ) . unwrap ( ) . unwrap ( ) ;
705
+ let gts2 = it. nth ( 0 ) . unwrap ( ) . unwrap ( ) ;
706
+ let lts2 = it. nth ( 0 ) . unwrap ( ) . unwrap ( ) ;
707
+ gts = Some ( Gts :: from_two ( gts1, gts2) . to_owned ( ) ) ;
708
+
709
+ outer_calc_offset ( lts2, gts. clone ( ) , & mut offset_sum)
710
+ } ,
711
+ chrono:: Duration :: nanoseconds ( 4194304438 ) ,
712
+ ) ,
713
+ (
714
+ {
715
+ if let TracePacket :: GlobalTimestamp1 { ts, .. } =
716
+ it. nth ( 0 ) . unwrap ( ) . unwrap ( )
717
+ {
718
+ gts. as_mut ( ) . unwrap ( ) . replace_lower ( ts) ;
719
+ gts. as_ref ( ) . unwrap ( ) . merge ( ) ;
720
+ } else {
721
+ unreachable ! ( ) ;
722
+ }
723
+ let lts2 = it. nth ( 0 ) . unwrap ( ) . unwrap ( ) ;
724
+
725
+ outer_calc_offset ( lts2, gts, & mut offset_sum)
726
+ } ,
727
+ chrono:: Duration :: nanoseconds ( 4194312313 ) ,
728
+ ) ,
729
+ ]
730
+ } ;
731
+
732
+ assert ! ( is_sorted_increasing(
733
+ & timestamps
734
+ . iter( )
735
+ . map( |( ts, _since) | ts. clone( ) )
736
+ . collect:: <Vec <Timestamp >>( )
737
+ ) ) ;
738
+
739
+ for ( ts, since) in timestamps. iter ( ) {
740
+ assert_eq ! (
741
+ unsafe { BASELINE . unwrap( ) }
742
+ . checked_add_signed( since. clone( ) )
743
+ . unwrap( ) ,
744
+ ts. ts
745
+ ) ;
746
+ }
747
+
748
+ let mut decoder = Decoder :: new ( stream. clone ( ) , DecoderOptions { ignore_eof : false } ) ;
749
+ let mut it = decoder. timestamps ( TimestampsConfiguration {
750
+ clock_frequency : FREQ ,
751
+ lts_prescaler : LocalTimestampOptions :: Enabled ,
752
+ baseline : unsafe { BASELINE . unwrap ( ) } ,
753
+ expect_malformed : false ,
754
+ } ) ;
755
+
756
+ for ( i, set) in [
757
+ TimestampedTracePackets {
758
+ packets : [ ] . into ( ) ,
759
+ malformed_packets : [ ] . into ( ) ,
760
+ timestamp : timestamps[ 0 ] . 0 . clone ( ) ,
761
+ consumed_packets : 1 ,
762
+ } ,
763
+ TimestampedTracePackets {
764
+ packets : [ ] . into ( ) ,
765
+ malformed_packets : [ ] . into ( ) ,
766
+ timestamp : timestamps[ 1 ] . 0 . clone ( ) ,
767
+ consumed_packets : 3 ,
768
+ } ,
769
+ TimestampedTracePackets {
770
+ packets : [ ] . into ( ) ,
771
+ malformed_packets : [ ] . into ( ) ,
772
+ timestamp : timestamps[ 2 ] . 0 . clone ( ) ,
773
+ consumed_packets : 2 ,
774
+ } ,
775
+ ]
776
+ . iter ( )
777
+ . enumerate ( )
778
+ {
779
+ let ttp = it. next ( ) . unwrap ( ) . unwrap ( ) ;
780
+ let since = ttp
781
+ . timestamp
782
+ . ts
783
+ . signed_duration_since ( unsafe { BASELINE . unwrap ( ) } ) ;
784
+ assert_eq ! ( dbg!( since) , dbg!( timestamps[ i] . 1 ) ) ;
785
+ assert_eq ! ( ttp, * set) ;
786
+ }
787
+ }
690
788
}
0 commit comments