Filename | /usr/local/src/github.com/foswiki/core/lib/Foswiki/Serialise/Embedded.pm |
Statements | Executed 1001 statements in 6.19ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
6 | 2 | 1 | 1.78ms | 3.83ms | _writeTypes | Foswiki::Serialise::Embedded::
66 | 2 | 1 | 1.01ms | 1.80ms | _writeKeyValue | Foswiki::Serialise::Embedded::
66 | 1 | 1 | 663µs | 792µs | dataEncode | Foswiki::Serialise::Embedded::
2 | 1 | 1 | 180µs | 4.06ms | getEmbeddedStoreForm | Foswiki::Serialise::Embedded::
22 | 1 | 1 | 137µs | 137µs | CORE:sort (opcode) | Foswiki::Serialise::Embedded::
66 | 1 | 1 | 130µs | 130µs | CORE:subst (opcode) | Foswiki::Serialise::Embedded::
48 | 3 | 1 | 111µs | 111µs | CORE:match (opcode) | Foswiki::Serialise::Embedded::
1 | 1 | 1 | 60µs | 79µs | BEGIN@15 | Foswiki::Serialise::Embedded::
2 | 1 | 1 | 58µs | 4.12ms | write | Foswiki::Serialise::Embedded::
1 | 1 | 1 | 37µs | 133µs | BEGIN@19 | Foswiki::Serialise::Embedded::
1 | 1 | 1 | 36µs | 81µs | BEGIN@16 | Foswiki::Serialise::Embedded::
1 | 1 | 1 | 26µs | 26µs | new | Foswiki::Serialise::Embedded::
1 | 1 | 1 | 18µs | 18µs | BEGIN@17 | Foswiki::Serialise::Embedded::
1 | 1 | 1 | 16µs | 16µs | BEGIN@18 | Foswiki::Serialise::Embedded::
0 | 0 | 0 | 0s | 0s | read | Foswiki::Serialise::Embedded::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # See bottom of file for license and copyright information | ||||
2 | |||||
3 | =begin TML | ||||
4 | |||||
5 | ---+ package Foswiki::Serialise::Embedded | ||||
6 | |||||
7 | This is __the__ on disk format serialiser and deserialise for TWiki and Foswiki topics legacy .txt format. | ||||
8 | |||||
9 | __WARNING__ this is only for Foswiki::Meta objects. | ||||
10 | |||||
11 | =cut | ||||
12 | |||||
13 | package Foswiki::Serialise::Embedded; | ||||
14 | |||||
15 | 2 | 96µs | 2 | 98µs | # spent 79µs (60+19) within Foswiki::Serialise::Embedded::BEGIN@15 which was called:
# once (60µs+19µs) by Foswiki::Serialise::getSerialiser at line 15 # spent 79µs making 1 call to Foswiki::Serialise::Embedded::BEGIN@15
# spent 19µs making 1 call to strict::import |
16 | 2 | 87µs | 2 | 127µs | # spent 81µs (36+45) within Foswiki::Serialise::Embedded::BEGIN@16 which was called:
# once (36µs+45µs) by Foswiki::Serialise::getSerialiser at line 16 # spent 81µs making 1 call to Foswiki::Serialise::Embedded::BEGIN@16
# spent 45µs making 1 call to warnings::import |
17 | 2 | 60µs | 1 | 18µs | # spent 18µs within Foswiki::Serialise::Embedded::BEGIN@17 which was called:
# once (18µs+0s) by Foswiki::Serialise::getSerialiser at line 17 # spent 18µs making 1 call to Foswiki::Serialise::Embedded::BEGIN@17 |
18 | 2 | 57µs | 1 | 16µs | # spent 16µs within Foswiki::Serialise::Embedded::BEGIN@18 which was called:
# once (16µs+0s) by Foswiki::Serialise::getSerialiser at line 18 # spent 16µs making 1 call to Foswiki::Serialise::Embedded::BEGIN@18 |
19 | 2 | 1.81ms | 2 | 229µs | # spent 133µs (37+96) within Foswiki::Serialise::Embedded::BEGIN@19 which was called:
# once (37µs+96µs) by Foswiki::Serialise::getSerialiser at line 19 # spent 133µs making 1 call to Foswiki::Serialise::Embedded::BEGIN@19
# spent 96µs making 1 call to Assert::import |
20 | |||||
21 | =begin TML | ||||
22 | |||||
23 | ---++ ClassMethod new( $class, ) -> $cereal | ||||
24 | |||||
25 | =cut | ||||
26 | |||||
27 | # spent 26µs within Foswiki::Serialise::Embedded::new which was called:
# once (26µs+0s) by Foswiki::Serialise::getSerialiser at line 81 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Serialise.pm | ||||
28 | 3 | 33µs | my $class = shift; | ||
29 | my $this = bless( {}, $class ); | ||||
30 | return $this; | ||||
31 | } | ||||
32 | |||||
33 | # spent 4.12ms (58µs+4.06) within Foswiki::Serialise::Embedded::write which was called 2 times, avg 2.06ms/call:
# 2 times (58µs+4.06ms) by Foswiki::Serialise::serialise at line 39 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Serialise.pm, avg 2.06ms/call | ||||
34 | 8 | 42µs | my $module = shift; | ||
35 | my ( $session, $result ) = @_; | ||||
36 | |||||
37 | 2 | 8µs | ASSERT( $result->isa('Foswiki::Meta') ) if DEBUG; # spent 8µs making 2 calls to Assert::ASSERTS_OFF, avg 4µs/call | ||
38 | 2 | 4.06ms | return getEmbeddedStoreForm($result); # spent 4.06ms making 2 calls to Foswiki::Serialise::Embedded::getEmbeddedStoreForm, avg 2.03ms/call | ||
39 | } | ||||
40 | |||||
41 | #really awkward - setEmbeddedStoreForm interleaves reading from text and calling Meta calls to update cache information | ||||
42 | #need to separate these out in a performant way. | ||||
43 | sub read { | ||||
44 | die 'not implemented'; | ||||
45 | my $module = shift; | ||||
46 | my ( $session, $result ) = @_; | ||||
47 | |||||
48 | ASSERT( $result->isa('Foswiki::Meta') ) if DEBUG; | ||||
49 | return setEmbeddedStoreForm($result); | ||||
50 | } | ||||
51 | |||||
52 | =begin TML | ||||
53 | |||||
54 | ---++ ObjectMethod getEmbeddedStoreForm() -> $text | ||||
55 | |||||
56 | Generate the embedded store form of the topic. The embedded store | ||||
57 | form has meta-data values embedded using %META: lines. The text | ||||
58 | stored in the meta is taken as the topic text. | ||||
59 | |||||
60 | TODO: Soooo.... if we wanted to make a meta->setPreference('VARIABLE', 'Values...'); we would have to change this to | ||||
61 | 1 see if that preference is set in the {_text} using the * Set syntax, in which case, replace that | ||||
62 | 2 or let the META::PREF.. work as it does now.. | ||||
63 | |||||
64 | yay :/ | ||||
65 | |||||
66 | TODO: can we move this code into Foswiki::Serialise ? | ||||
67 | |||||
68 | =cut | ||||
69 | |||||
70 | # spent 4.06ms (180µs+3.88) within Foswiki::Serialise::Embedded::getEmbeddedStoreForm which was called 2 times, avg 2.03ms/call:
# 2 times (180µs+3.88ms) by Foswiki::Serialise::Embedded::write at line 38, avg 2.03ms/call | ||||
71 | 24 | 160µs | my $this = shift; | ||
72 | |||||
73 | 2 | 6µs | ASSERT( $this->{_web} && $this->{_topic}, 'this is not a topic object' ) # spent 6µs making 2 calls to Assert::ASSERTS_OFF, avg 3µs/call | ||
74 | if DEBUG; | ||||
75 | $this->{_text} ||= ''; | ||||
76 | |||||
77 | require Foswiki::Store; # for encoding | ||||
78 | |||||
79 | 2 | 42µs | my $ti = $this->get('TOPICINFO'); # spent 42µs making 2 calls to Foswiki::Meta::get, avg 21µs/call | ||
80 | delete $ti->{rev} if $ti; # don't want this written | ||||
81 | |||||
82 | 2 | 544µs | my $text = _writeTypes( $this, 'TOPICINFO', 'TOPICPARENT' ); # spent 544µs making 2 calls to Foswiki::Serialise::Embedded::_writeTypes, avg 272µs/call | ||
83 | $text .= $this->{_text}; | ||||
84 | 4 | 3.28ms | my $end = # spent 3.28ms making 4 calls to Foswiki::Serialise::Embedded::_writeTypes, avg 821µs/call | ||
85 | _writeTypes( $this, 'FORM', 'FIELD', 'FILEATTACHMENT', 'TOPICMOVED' ) | ||||
86 | . _writeTypes( $this, 'not', 'TOPICINFO', 'TOPICPARENT', 'FORM', 'FIELD', | ||||
87 | 'FILEATTACHMENT', 'TOPICMOVED' ); | ||||
88 | $text .= "\n" if $end; | ||||
89 | |||||
90 | $ti->{rev} = $ti->{version} if $ti; | ||||
91 | |||||
92 | return $text . $end; | ||||
93 | } | ||||
94 | |||||
95 | # PRIVATE STATIC Write a meta-data key=value pair | ||||
96 | # The encoding is reversed in _readKeyValues | ||||
97 | # spent 1.80ms (1.01+792µs) within Foswiki::Serialise::Embedded::_writeKeyValue which was called 66 times, avg 27µs/call:
# 45 times (695µs+543µs) by Foswiki::Serialise::Embedded::_writeTypes at line 149, avg 28µs/call
# 21 times (316µs+249µs) by Foswiki::Serialise::Embedded::_writeTypes at line 141, avg 27µs/call | ||||
98 | 264 | 979µs | my ( $key, $value ) = @_; | ||
99 | |||||
100 | if ( defined($value) ) { | ||||
101 | 66 | 792µs | $value = dataEncode($value); # spent 792µs making 66 calls to Foswiki::Serialise::Embedded::dataEncode, avg 12µs/call | ||
102 | } | ||||
103 | else { | ||||
104 | $value = ''; | ||||
105 | } | ||||
106 | |||||
107 | return $key . '="' . $value . '"'; | ||||
108 | } | ||||
109 | |||||
110 | # PRIVATE STATIC: Write all the key=value pairs for the types listed | ||||
111 | # spent 3.83ms (1.78+2.05) within Foswiki::Serialise::Embedded::_writeTypes which was called 6 times, avg 638µs/call:
# 4 times (1.50ms+1.78ms) by Foswiki::Serialise::Embedded::getEmbeddedStoreForm at line 84, avg 821µs/call
# 2 times (275µs+269µs) by Foswiki::Serialise::Embedded::getEmbeddedStoreForm at line 82, avg 272µs/call | ||||
112 | 493 | 1.97ms | my ( $this, @types ) = @_; | ||
113 | |||||
114 | my $text = ''; | ||||
115 | |||||
116 | if ( $types[0] eq 'not' ) { | ||||
117 | |||||
118 | # write all types that are not in the list | ||||
119 | my %seen; | ||||
120 | @seen{@types} = (); | ||||
121 | @types = (); # empty "not in list" | ||||
122 | foreach my $key ( keys %$this ) { | ||||
123 | 14 | 37µs | push( @types, $key ) # spent 37µs making 14 calls to Foswiki::Serialise::Embedded::CORE:match, avg 3µs/call | ||
124 | unless ( exists $seen{$key} || $key =~ /^_/ ); | ||||
125 | } | ||||
126 | } | ||||
127 | |||||
128 | foreach my $type (@types) { | ||||
129 | 12 | 23µs | next if ( $type =~ /^_/ ); # spent 23µs making 12 calls to Foswiki::Serialise::Embedded::CORE:match, avg 2µs/call | ||
130 | my $data = $this->{$type}; | ||||
131 | next if !defined $data; | ||||
132 | foreach my $item (@$data) { | ||||
133 | 22 | 51µs | next if ( $item =~ /^_/ ); # spent 51µs making 22 calls to Foswiki::Serialise::Embedded::CORE:match, avg 2µs/call | ||
134 | my $sep = ''; | ||||
135 | $text .= '%META:' . $type . '{'; | ||||
136 | my $name = $item->{name}; | ||||
137 | if ($name) { | ||||
138 | |||||
139 | # If there's a name field, put first to make regexp | ||||
140 | # based searching easier | ||||
141 | 21 | 565µs | $text .= _writeKeyValue( 'name', $item->{name} ); # spent 565µs making 21 calls to Foswiki::Serialise::Embedded::_writeKeyValue, avg 27µs/call | ||
142 | $sep = ' '; | ||||
143 | } | ||||
144 | 22 | 137µs | foreach my $key ( sort keys %$item ) { # spent 137µs making 22 calls to Foswiki::Serialise::Embedded::CORE:sort, avg 6µs/call | ||
145 | |||||
146 | #next if ($key =~ /^_/ ); | ||||
147 | if ( $key ne 'name' ) { | ||||
148 | $text .= $sep; | ||||
149 | 45 | 1.24ms | $text .= _writeKeyValue( $key, $item->{$key} ); # spent 1.24ms making 45 calls to Foswiki::Serialise::Embedded::_writeKeyValue, avg 28µs/call | ||
150 | $sep = ' '; | ||||
151 | } | ||||
152 | } | ||||
153 | $text .= '}%' . "\n"; | ||||
154 | } | ||||
155 | } | ||||
156 | |||||
157 | return $text; | ||||
158 | } | ||||
159 | |||||
160 | =begin TML | ||||
161 | |||||
162 | ---++ StaticMethod dataEncode( $uncoded ) -> $coded | ||||
163 | |||||
164 | Encode meta-data field values, escaping out selected characters. | ||||
165 | The encoding is chosen to avoid problems with parsing the attribute | ||||
166 | values in embedded meta-data, while minimising the number of | ||||
167 | characters encoded so searches can still work (fairly) sensibly. | ||||
168 | |||||
169 | The encoding has to be exported because Foswiki (and plugins) use | ||||
170 | encoded field data in other places e.g. RDiff, mainly as a shorthand | ||||
171 | for the properly parsed meta object. Some day we may be able to | ||||
172 | eliminate that.... | ||||
173 | |||||
174 | =cut | ||||
175 | |||||
176 | # spent 792µs (663+130) within Foswiki::Serialise::Embedded::dataEncode which was called 66 times, avg 12µs/call:
# 66 times (663µs+130µs) by Foswiki::Serialise::Embedded::_writeKeyValue at line 101, avg 12µs/call | ||||
177 | 198 | 886µs | my $datum = shift; | ||
178 | |||||
179 | 66 | 130µs | $datum =~ s/([%"\r\n{}])/'%'.sprintf('%02x',ord($1))/ge; # spent 130µs making 66 calls to Foswiki::Serialise::Embedded::CORE:subst, avg 2µs/call | ||
180 | return $datum; | ||||
181 | } | ||||
182 | |||||
183 | 1 | 6µs | 1; | ||
184 | __END__ | ||||
# spent 111µs within Foswiki::Serialise::Embedded::CORE:match which was called 48 times, avg 2µs/call:
# 22 times (51µs+0s) by Foswiki::Serialise::Embedded::_writeTypes at line 133, avg 2µs/call
# 14 times (37µs+0s) by Foswiki::Serialise::Embedded::_writeTypes at line 123, avg 3µs/call
# 12 times (23µs+0s) by Foswiki::Serialise::Embedded::_writeTypes at line 129, avg 2µs/call | |||||
# spent 137µs within Foswiki::Serialise::Embedded::CORE:sort which was called 22 times, avg 6µs/call:
# 22 times (137µs+0s) by Foswiki::Serialise::Embedded::_writeTypes at line 144, avg 6µs/call | |||||
# spent 130µs within Foswiki::Serialise::Embedded::CORE:subst which was called 66 times, avg 2µs/call:
# 66 times (130µs+0s) by Foswiki::Serialise::Embedded::dataEncode at line 179, avg 2µs/call |