11use libc:: pid_t;
22use serde:: { Deserialize , Serialize } ;
3+ use std:: io:: { Read , Write } ;
34
45#[ derive( Debug , Clone , Serialize , Deserialize ) ]
56pub struct MemtrackArtifact {
67 pub events : Vec < MemtrackEvent > ,
78}
8- impl super :: ArtifactExt for MemtrackArtifact { }
9+ impl super :: ArtifactExt for MemtrackArtifact {
10+ fn encode_to_writer < W : Write > ( & self , writer : W ) -> anyhow:: Result < ( ) > {
11+ // This is required for `decode_streamed`:
12+ let mut serializer = rmp_serde:: Serializer :: new ( writer) ;
13+ for event in & self . events {
14+ event. serialize ( & mut serializer) ?;
15+ }
16+ Ok ( ( ) )
17+ }
18+ }
19+
20+ impl MemtrackArtifact {
21+ pub fn decode_streamed < R : std:: io:: Read > ( reader : R ) -> anyhow:: Result < MemtrackEventStream < R > > {
22+ Ok ( MemtrackEventStream {
23+ deserializer : rmp_serde:: Deserializer :: new ( reader) ,
24+ } )
25+ }
26+ }
927
10- #[ derive( Debug , Clone , Copy , Serialize , Deserialize ) ]
28+ #[ derive( Debug , Clone , Copy , Serialize , Deserialize , PartialEq , Eq ) ]
1129pub struct MemtrackEvent {
1230 pub pid : pid_t ,
1331 pub tid : pid_t ,
@@ -17,7 +35,7 @@ pub struct MemtrackEvent {
1735 pub kind : MemtrackEventKind ,
1836}
1937
20- #[ derive( Debug , Clone , Copy , Serialize , Deserialize ) ]
38+ #[ derive( Debug , Clone , Copy , Serialize , Deserialize , PartialEq , Eq ) ]
2139#[ serde( tag = "type" ) ]
2240pub enum MemtrackEventKind {
2341 Malloc { size : u64 } ,
@@ -29,3 +47,55 @@ pub enum MemtrackEventKind {
2947 Munmap { size : u64 } ,
3048 Brk { size : u64 } ,
3149}
50+
51+ pub struct MemtrackEventStream < R : Read > {
52+ deserializer : rmp_serde:: Deserializer < rmp_serde:: decode:: ReadReader < R > > ,
53+ }
54+
55+ impl < R : Read > Iterator for MemtrackEventStream < R > {
56+ type Item = MemtrackEvent ;
57+
58+ fn next ( & mut self ) -> Option < Self :: Item > {
59+ MemtrackEvent :: deserialize ( & mut self . deserializer ) . ok ( )
60+ }
61+ }
62+
63+ #[ cfg( test) ]
64+ mod tests {
65+ use crate :: artifacts:: ArtifactExt ;
66+
67+ use super :: * ;
68+ use std:: io:: Cursor ;
69+
70+ #[ test]
71+ fn test_decode_streamed ( ) -> anyhow:: Result < ( ) > {
72+ let events = vec ! [
73+ MemtrackEvent {
74+ pid: 1 ,
75+ tid: 11 ,
76+ timestamp: 100 ,
77+ addr: 0x10 ,
78+ kind: MemtrackEventKind :: Malloc { size: 64 } ,
79+ } ,
80+ MemtrackEvent {
81+ pid: 1 ,
82+ tid: 12 ,
83+ timestamp: 200 ,
84+ addr: 0x20 ,
85+ kind: MemtrackEventKind :: Free ,
86+ } ,
87+ ] ;
88+
89+ let artifact = MemtrackArtifact {
90+ events : events. clone ( ) ,
91+ } ;
92+ let mut buf = Vec :: new ( ) ;
93+ artifact. encode_to_writer ( & mut buf) ?;
94+
95+ let stream = MemtrackArtifact :: decode_streamed ( Cursor :: new ( buf) ) ?;
96+ let collected: Vec < _ > = stream. collect ( ) ;
97+ assert_eq ! ( collected, events) ;
98+
99+ Ok ( ( ) )
100+ }
101+ }
0 commit comments