File Coverage

blib/lib/POE/Devel/Profiler/Parser.pm
Criterion Covered Total %
statement 9 71 12.6
branch 0 52 0.0
condition n/a
subroutine 3 4 75.0
pod 0 1 0.0
total 12 128 9.3


line stmt bran cond sub pod time code
1             # Declare our package
2             package POE::Devel::Profiler::Parser;
3              
4             # Standard stuff to catch errors
5 1     1   960 use strict qw(subs vars refs); # Make sure we can't mess up
  1         3  
  1         47  
6 1     1   6 use warnings FATAL => 'all'; # Enable warnings to catch errors
  1         2  
  1         69  
7              
8             # Initialize our version
9             our $VERSION = '0.01';
10              
11             # Export our routines
12 1     1   16 use Exporter;
  1         2  
  1         2137  
13             our @ISA = qw( Exporter );
14             our @EXPORT_OK = qw( load_profile );
15              
16             # Okay, here is the core of this module :)
17             sub load_profile {
18             # Get the filename
19 0     0 0   my $file = shift;
20              
21             # Check if we can read this and etc...
22 0 0         open( PARSE, "< $file" ) or die $!;
23              
24             # Construct our data structure
25             # PROGNAME
26             # TIME -> {
27             # START
28             # END
29             # WALL
30             # USER
31             # SYSTEM
32             # CUSER
33             # CSYSTEM
34             # SESSION
35             # ID -> {
36             # GC -> [
37             # TIME
38             # ALARMS -> [
39             # EVENT
40             # TIME_ALARM
41             # FILE
42             # LINE
43             # TIME
44             # DELAYS -> [
45             # EVENT
46             # TIME_ALARM
47             # FILE
48             # LINE
49             # TIME
50             # SIGNALS -> [
51             # DEST
52             # SIGNAL
53             # FILE
54             # LINE
55             # TIME
56             # ALIASES -> {
57             # NAME -> {
58             # TIME
59             # FILE
60             # LINE
61             # TIME
62             # HITS
63             # CREATE -> {
64             # TIME
65             # FILE
66             # LINE
67             # PARENT
68             # DIETIME
69             # STATES -> {
70             # NAME -> {
71             # FAILURES -> HITS
72             # DEAFULT -> HITS
73             # TIME
74             # HITS
75             # CALLS -> {
76             # ID -> {
77             # STATE -> [
78             # FILE
79             # LINE
80             # TIME
81             # POSTS -> {
82             # ID -> {
83             # STATE -> [
84             # FILE
85             # LINE
86             # TIME
87             # YIELD -> {
88             # STATE -> [
89             # FILE
90             # LINE
91             # TIME
92 0           my %data = ();
93              
94             # The stack for entertimes -> used to figure out time spent in state/session
95 0           my @stack = ();
96              
97             # Loop through the file
98 0           while ( my $line = ) {
99             # What kind of line is this?
100 0 0         if ( $line =~ /^ENTERSTATE\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
101             # ENTERSTATE current_session_id statename caller_session_id caller_file_name caller_file_line time
102              
103             # Put on the top of the stack the entertime
104 0           unshift( @stack, $6 );
105              
106 0 0         if ( ! exists $data{'SESSION'}->{ $1 }->{'HITS'} ) {
107 0           $data{'SESSION'}->{ $1 }->{'HITS'} = 0;
108             }
109 0 0         if ( ! exists $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'HITS'} ) {
110 0           $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'HITS'} = 0;
111             }
112              
113             # Add the hits for this session and state
114 0           $data{'SESSION'}->{ $1 }->{'HITS'}++;
115 0           $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'HITS'}++;
116             } elsif ( $line =~ /^LEAVESTATE\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
117             # LEAVESTATE current_session_id statename time
118              
119             # Subtract the time
120 0           my $diff = $3 - shift( @stack );
121              
122             # Make sure the diff output makes sense
123 0           $diff = sprintf( "%.6f", $diff );
124              
125             # Tally up the time for this session + state
126 0 0         if ( ! exists $data{'SESSION'}->{ $1 }->{'TIME'} ) {
127 0           $data{'SESSION'}->{ $1 }->{'TIME'} = 0;
128             }
129 0 0         if ( ! exists $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'TIME'} ) {
130 0           $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'TIME'} = 0;
131             }
132              
133 0           $data{'SESSION'}->{ $1 }->{'TIME'} += $diff;
134 0           $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'TIME'} += $diff;
135             } elsif ( $line =~ /^YIELD\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
136             # YIELD current_session_id statename yield_event file line time
137              
138 0           push( @{ $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'YIELD'}->{ $3 } }, {
  0            
139             'FILE' => $4,
140             'LINE' => $5,
141             'TIME' => $6,
142             } );
143             } elsif ( $line =~ /^POST\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
144             # POST current_session_id statename post_session post_event file line time
145              
146 0           push( @{ $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'POST'}->{ $3 }->{ $4 } }, {
  0            
147             'FILE' => $5,
148             'LINE' => $6,
149             'TIME' => $7,
150             } );
151             } elsif ( $line =~ /^CALL\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
152             # CALL current_session_id statename call_session call_event file line time
153              
154 0           push( @{ $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'CALL'}->{ $3 }->{ $4 } }, {
  0            
155             'FILE' => $5,
156             'LINE' => $6,
157             'TIME' => $7,
158             } );
159             } elsif ( $line =~ /^FAILSTATE\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
160             # FAILSTATE current_session_id statename caller_session_id caller_file_name caller_file_line time
161              
162 0 0         if ( ! exists $data{'SESSION'}->{ $1 }->{'HITS'} ) {
163 0           $data{'SESSION'}->{ $1 }->{'HITS'} = 0;
164             }
165 0 0         if ( ! exists $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'FAILURES'} ) {
166 0           $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'FAILURES'} = 0;
167             }
168              
169             # Add the hits for this session and state
170 0           $data{'SESSION'}->{ $1 }->{'HITS'}++;
171 0           $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'FAILURES'}++;
172             } elsif ( $line =~ /^DEFAULTSTATE\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
173             # DEFAULTSTATE current_session_id statename caller_session_id caller_file_name caller_file_line time
174              
175             # Put on the top of the stack the entertime
176 0           unshift( @stack, $6 );
177            
178 0 0         if ( ! exists $data{'SESSION'}->{ $1 }->{'HITS'} ) {
179 0           $data{'SESSION'}->{ $1 }->{'HITS'} = 0;
180             }
181 0 0         if ( ! exists $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'DEFAULT'} ) {
182 0           $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'DEFAULT'} = 0;
183             }
184              
185             # Add the hits for this session and state
186 0           $data{'SESSION'}->{ $1 }->{'HITS'}++;
187 0           $data{'SESSION'}->{ $1 }->{'STATES'}->{ $2 }->{'DEFAULT'}++;
188             } elsif ( $line =~ /^STARTPROGRAM\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
189             # STARTPROGRAM name time
190              
191             # Store the data
192 0           $data{'PROGNAME'} = $1;
193 0           $data{'TIME'}->{'START'} = $2;
194             } elsif ( $line =~ /^ENDPROGRAM\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
195             # ENDPROGRAM time wall user system cuser csystem
196              
197             # Store the data
198 0           $data{'TIME'}->{'END'} = $1;
199 0           $data{'TIME'}->{'WALL'} = $2;
200 0           $data{'TIME'}->{'USER'} = $3;
201 0           $data{'TIME'}->{'SYSTEM'} = $4;
202 0           $data{'TIME'}->{'CUSER'} = $5;
203 0           $data{'TIME'}->{'CSYSTEM'} = $6;
204             } elsif ( $line =~ /^SESSIONALIAS\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
205             # SESSIONALIAS session_id alias file line time
206              
207             # Store it!
208 0           $data{'SESSION'}->{ $1 }->{'ALIASES'}->{ $2 } = {
209             'FILE' => $3,
210             'LINE' => $4,
211             'TIME' => $5,
212             };
213             } elsif ( $line =~ /^SESSIONNEW\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
214             # SESSIONNEW session_id parent_id file line time
215              
216 0           $data{'SESSION'}->{ $1 }->{'CREATE'} = {
217             'PARENT' => $2,
218             'FILE' => $3,
219             'LINE' => $4,
220             'TIME' => $5,
221             };
222             } elsif ( $line =~ /^SESSIONDIE\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
223             # SESSIONDIE session_id time
224              
225 0           $data{'SESSION'}->{ $1 }->{'DIETIME'} = $2;
226             } elsif ( $line =~ /^ALARMSET\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
227             # ALARMSET session_id event_name time_alarm file line time
228            
229 0           push( @{ $data{'SESSION'}->{ $1 }->{'ALARMS'} }, {
  0            
230             'EVENT' => $2,
231             'TIME_ALARM' => $3,
232             'FILE' => $4,
233             'LINE' => $5,
234             'TIME' => $6,
235             } );
236             } elsif ( $line =~ /^DELAYSET\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
237             # DELAYSET session_id event_name time_alarm file line time
238            
239 0           push( @{ $data{'SESSION'}->{ $1 }->{'DELAYS'} }, {
  0            
240             'EVENT' => $2,
241             'TIME_ALARM' => $3,
242             'FILE' => $4,
243             'LINE' => $5,
244             'TIME' => $6,
245             } );
246             } elsif ( $line =~ /^SIGNAL\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
247             # SIGNAL session_id dest_id signal file line time
248            
249 0           push( @{ $data{'SESSION'}->{ $1 }->{'SIGNALS'} }, {
  0            
250             'DEST' => $2,
251             'SIGNAL' => $3,
252             'FILE' => $4,
253             'LINE' => $5,
254             'TIME' => $6,
255             } );
256             } elsif ( $line =~ /^GC\s+\"([^\"]+)\"\s+\"([^\"]+)\"$/ ) {
257             # GC session_id time
258            
259 0           push( @{ $data{'SESSION'}->{ $1 }->{'GC'} }, $2 );
  0            
260             } else {
261             # Funky line...
262 0           warn "Funky line: $line";
263             }
264             }
265              
266             # All done with the file
267 0 0         close( PARSE ) or die $!;
268              
269             # Return the data structure
270 0           return \%data;
271             }
272              
273             # End of module
274             1;
275              
276             __END__