1
+ use serde:: de:: Deserializer ;
1
2
use serde:: { Deserialize , Serialize } ;
2
3
use std:: convert:: TryFrom ;
3
4
use std:: sync:: Arc ;
@@ -15,22 +16,16 @@ impl Into<InternalSelfProfile> for SelfProfile {
15
16
let query_data = self . query_data ;
16
17
InternalSelfProfile :: Perf {
17
18
label : query_data. iter ( ) . map ( |qd| qd. label . clone ( ) ) . collect ( ) ,
18
- self_time : query_data
19
- . iter ( )
20
- . map ( |qd| u64:: try_from ( qd. self_time . as_nanos ( ) ) . unwrap ( ) )
21
- . collect ( ) ,
19
+ self_time : query_data. iter ( ) . map ( |qd| qd. self_time ) . collect ( ) ,
22
20
number_of_cache_hits : query_data
23
21
. iter ( )
24
22
. map ( |qd| qd. number_of_cache_hits )
25
23
. collect ( ) ,
26
24
invocation_count : query_data. iter ( ) . map ( |qd| qd. invocation_count ) . collect ( ) ,
27
- blocked_time : query_data
28
- . iter ( )
29
- . map ( |qd| u64:: try_from ( qd. blocked_time . as_nanos ( ) ) . unwrap ( ) )
30
- . collect ( ) ,
25
+ blocked_time : query_data. iter ( ) . map ( |qd| qd. blocked_time ) . collect ( ) ,
31
26
incremental_load_time : query_data
32
27
. iter ( )
33
- . map ( |qd| u64 :: try_from ( qd. incremental_load_time . as_nanos ( ) ) . unwrap ( ) )
28
+ . map ( |qd| qd. incremental_load_time )
34
29
. collect ( ) ,
35
30
}
36
31
}
@@ -55,13 +50,11 @@ impl From<InternalSelfProfile> for SelfProfile {
55
50
} => {
56
51
let mut query_data = Vec :: with_capacity ( label. len ( ) ) ;
57
52
let label = label. into_iter ( ) ;
58
- let mut self_time = self_time. into_iter ( ) . map ( from_nanoseconds_to_duration ) ;
53
+ let mut self_time = self_time. into_iter ( ) ;
59
54
let mut number_of_cache_hits = number_of_cache_hits. into_iter ( ) ;
60
55
let mut invocation_count = invocation_count. into_iter ( ) ;
61
- let mut blocked_time = blocked_time. into_iter ( ) . map ( from_nanoseconds_to_duration) ;
62
- let mut incremental_load_time = incremental_load_time
63
- . into_iter ( )
64
- . map ( from_nanoseconds_to_duration) ;
56
+ let mut blocked_time = blocked_time. into_iter ( ) ;
57
+ let mut incremental_load_time = incremental_load_time. into_iter ( ) ;
65
58
for label in label {
66
59
query_data. push ( QueryData {
67
60
label,
@@ -72,6 +65,7 @@ impl From<InternalSelfProfile> for SelfProfile {
72
65
incremental_load_time : incremental_load_time. next ( ) . unwrap ( ) ,
73
66
} ) ;
74
67
}
68
+ assert_eq ! ( query_data. capacity( ) , query_data. len( ) ) ;
75
69
query_data. shrink_to_fit ( ) ;
76
70
SelfProfile {
77
71
query_data : Arc :: new ( query_data) ,
@@ -101,28 +95,49 @@ enum InternalSelfProfile {
101
95
} ,
102
96
}
103
97
104
- // FIXME: We would prefer to store the nanoseconds as u128, which is lossless,
105
- // but serde's untagged enum representation (and the internal buffering API it
106
- // uses) do not support this yet.
107
- fn from_nanoseconds_to_duration ( nanos : u64 ) -> Duration {
108
- const NANOS_PER_SEC : u64 = 1_000_000_000 ;
109
- Duration :: new (
110
- u64:: try_from ( nanos / NANOS_PER_SEC ) . unwrap ( ) ,
111
- u32:: try_from ( nanos % NANOS_PER_SEC ) . unwrap ( ) ,
112
- )
113
- }
114
-
115
98
#[ derive( Deserialize , Clone , Debug ) ]
116
99
pub struct QueryData {
117
100
pub label : QueryLabel ,
118
- pub self_time : Duration ,
101
+ #[ serde( deserialize_with = "SerdeDuration::into_nanos" ) ]
102
+ self_time : u64 ,
119
103
pub number_of_cache_hits : u32 ,
120
104
pub invocation_count : u32 ,
121
- pub blocked_time : Duration ,
122
- pub incremental_load_time : Duration ,
105
+ blocked_time : u64 ,
106
+ incremental_load_time : u64 ,
107
+ }
108
+
109
+ #[ derive( Deserialize ) ]
110
+ #[ serde( untagged) ]
111
+ enum SerdeDuration {
112
+ Nanoseconds ( u64 ) ,
113
+ Duration ( Duration ) ,
114
+ }
115
+
116
+ impl SerdeDuration {
117
+ fn into_nanos < ' de , D > ( deserializer : D ) -> Result < u64 , D :: Error >
118
+ where
119
+ D : Deserializer < ' de > ,
120
+ {
121
+ match SerdeDuration :: deserialize ( deserializer) ? {
122
+ SerdeDuration :: Nanoseconds ( v) => Ok ( v) ,
123
+ SerdeDuration :: Duration ( d) => Ok ( u64:: try_from ( d. as_nanos ( ) ) . unwrap ( ) ) ,
124
+ }
125
+ }
123
126
}
124
127
125
128
impl QueryData {
129
+ pub fn self_time ( & self ) -> Duration {
130
+ Duration :: from_nanos ( self . self_time )
131
+ }
132
+
133
+ pub fn blocked_time ( & self ) -> Duration {
134
+ Duration :: from_nanos ( self . blocked_time )
135
+ }
136
+
137
+ pub fn incremental_load_time ( & self ) -> Duration {
138
+ Duration :: from_nanos ( self . incremental_load_time )
139
+ }
140
+
126
141
pub fn number_of_cache_misses ( & self ) -> u32 {
127
142
self . invocation_count - self . number_of_cache_hits
128
143
}
0 commit comments