Filename | /var/www/foswikidev/core/lib/Foswiki/Store/Rcs/Store.pm |
Statements | Executed 555774 statements in 997ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
26327 | 1 | 1 | 1.58s | 75.8s | readTopic | Foswiki::Store::Rcs::Store::
40 | 1 | 1 | 7.10ms | 2.79s | eachTopic | Foswiki::Store::Rcs::Store::
80 | 2 | 2 | 3.74ms | 108s | query (recurses: max depth 1, inclusive time 49.2s) | Foswiki::Store::Rcs::Store::
197 | 3 | 3 | 1.44ms | 13.0ms | topicExists | Foswiki::Store::Rcs::Store::
101 | 1 | 1 | 906µs | 6.90ms | webExists | Foswiki::Store::Rcs::Store::
26 | 2 | 2 | 641µs | 17.9ms | eachWeb (recurses: max depth 2, inclusive time 19.9ms) | Foswiki::Store::Rcs::Store::
3 | 1 | 1 | 94µs | 14.9ms | getVersionInfo | Foswiki::Store::Rcs::Store::
4 | 2 | 1 | 32µs | 102µs | __ANON__[:61] | Foswiki::Store::Rcs::Store::
2 | 1 | 1 | 31µs | 731µs | getRevisionHistory | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 28µs | 30µs | finish | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 19µs | 93µs | attachmentExists | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 18µs | 29µs | BEGIN@33 | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 11µs | 11µs | BEGIN@47 | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 10µs | 23µs | BEGIN@665 | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 9µs | 13µs | BEGIN@34 | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 9µs | 34µs | BEGIN@39 | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 9µs | 114µs | BEGIN@40 | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 8µs | 18µs | BEGIN@667 | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 5µs | 5µs | BEGIN@42 | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 4µs | 4µs | BEGIN@45 | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 4µs | 4µs | BEGIN@36 | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 3µs | 3µs | BEGIN@44 | Foswiki::Store::Rcs::Store::
1 | 1 | 1 | 3µs | 3µs | BEGIN@43 | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | __ANON__[:62] | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | __ANON__[:65] | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | __ANON__[:66] | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | _getAttachmentVersionInfo | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | atomicLock | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | atomicLockInfo | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | atomicUnlock | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | copyAttachment | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | delRev | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | eachAttachment | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | eachChange | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | getApproxRevTime | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | getHandler | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | getLease | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | getNextRevision | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | getRevisionAtTime | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | getRevisionDiff | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | moveAttachment | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | moveTopic | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | moveWeb | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | openAttachment | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | recordChange | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | remove | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | removeSpuriousLeases | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | repRev | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | saveAttachment | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | saveTopic | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | setLease | Foswiki::Store::Rcs::Store::
0 | 0 | 0 | 0s | 0s | testAttachment | Foswiki::Store::Rcs::Store::
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::Store::Rcs::Store | ||||
6 | |||||
7 | Almost-complete implementation of =Foswiki::Store=. The methods | ||||
8 | of this class implement the =Foswiki::Store= interface. | ||||
9 | |||||
10 | The store uses a "handler" class to handle all interactions with the | ||||
11 | actual version control system (and via it with the actual file system). | ||||
12 | A "handler" is created for each individual file in the file system, and | ||||
13 | this handler then brokers all requests to open, read, write etc the file. | ||||
14 | The handler object must implement the interface specified by | ||||
15 | =Foswiki::Store::Rcs::Handler=. | ||||
16 | |||||
17 | The main additional responsibilities of _this_ class are to support storing | ||||
18 | Foswiki meta-data in plain text files, and to ensure that the =Foswiki::Meta= | ||||
19 | for a page is maintained in synchronisation with the files on disk. | ||||
20 | |||||
21 | All that is required to create a working store is to subclass this class | ||||
22 | and override the 'new' method to specify the actual handler to use. See | ||||
23 | Foswiki::Store::RcsWrap for an example subclass. | ||||
24 | |||||
25 | For readers who are familiar with Foswiki version 1.0, the functionality | ||||
26 | in this class _previously_ resided in =Foswiki::Store=. | ||||
27 | |||||
28 | These methods are documented in the Foswiki:Store abstract base class | ||||
29 | |||||
30 | =cut | ||||
31 | |||||
32 | package Foswiki::Store::Rcs::Store; | ||||
33 | 2 | 26µs | 2 | 41µs | # spent 29µs (18+12) within Foswiki::Store::Rcs::Store::BEGIN@33 which was called:
# once (18µs+12µs) by Foswiki::Store::RcsWrap::BEGIN@23 at line 33 # spent 29µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@33
# spent 12µs making 1 call to strict::import |
34 | 2 | 22µs | 2 | 17µs | # spent 13µs (9+4) within Foswiki::Store::Rcs::Store::BEGIN@34 which was called:
# once (9µs+4µs) by Foswiki::Store::RcsWrap::BEGIN@23 at line 34 # spent 13µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@34
# spent 4µs making 1 call to warnings::import |
35 | |||||
36 | 2 | 32µs | 1 | 4µs | # spent 4µs within Foswiki::Store::Rcs::Store::BEGIN@36 which was called:
# once (4µs+0s) by Foswiki::Store::RcsWrap::BEGIN@23 at line 36 # spent 4µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@36 |
37 | 1 | 8µs | our @ISA = ('Foswiki::Store'); | ||
38 | |||||
39 | 2 | 29µs | 2 | 59µs | # spent 34µs (9+25) within Foswiki::Store::Rcs::Store::BEGIN@39 which was called:
# once (9µs+25µs) by Foswiki::Store::RcsWrap::BEGIN@23 at line 39 # spent 34µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@39
# spent 25µs making 1 call to Exporter::import |
40 | 2 | 29µs | 2 | 218µs | # spent 114µs (9+105) within Foswiki::Store::Rcs::Store::BEGIN@40 which was called:
# once (9µs+105µs) by Foswiki::Store::RcsWrap::BEGIN@23 at line 40 # spent 114µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@40
# spent 105µs making 1 call to Error::import |
41 | |||||
42 | 2 | 18µs | 1 | 5µs | # spent 5µs within Foswiki::Store::Rcs::Store::BEGIN@42 which was called:
# once (5µs+0s) by Foswiki::Store::RcsWrap::BEGIN@23 at line 42 # spent 5µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@42 |
43 | 2 | 17µs | 1 | 3µs | # spent 3µs within Foswiki::Store::Rcs::Store::BEGIN@43 which was called:
# once (3µs+0s) by Foswiki::Store::RcsWrap::BEGIN@23 at line 43 # spent 3µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@43 |
44 | 2 | 18µs | 1 | 3µs | # spent 3µs within Foswiki::Store::Rcs::Store::BEGIN@44 which was called:
# once (3µs+0s) by Foswiki::Store::RcsWrap::BEGIN@23 at line 44 # spent 3µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@44 |
45 | 2 | 183µs | 1 | 4µs | # spent 4µs within Foswiki::Store::Rcs::Store::BEGIN@45 which was called:
# once (4µs+0s) by Foswiki::Store::RcsWrap::BEGIN@23 at line 45 # spent 4µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@45 |
46 | |||||
47 | # spent 11µs within Foswiki::Store::Rcs::Store::BEGIN@47 which was called:
# once (11µs+0s) by Foswiki::Store::RcsWrap::BEGIN@23 at line 70 | ||||
48 | |||||
49 | # Do a dynamic 'use locale' for this module | ||||
50 | 1 | 600ns | if ( $Foswiki::cfg{UseLocale} ) { | ||
51 | require locale; | ||||
52 | import locale(); | ||||
53 | } | ||||
54 | |||||
55 | # The RCS Handler code works on bytes, so we have to mediate | ||||
56 | 1 | 7µs | if ($Foswiki::UNICODE) { | ||
57 | 1 | 500ns | require Encode; | ||
58 | |||||
59 | 1 | 2µs | *_decode = \&Foswiki::Store::decode; | ||
60 | 1 | 600ns | *_encode = \&Foswiki::Store::encode; | ||
61 | 5 | 35µs | 4 | 70µs | # spent 102µs (32+70) within Foswiki::Store::Rcs::Store::__ANON__[/var/www/foswikidev/core/lib/Foswiki/Store/Rcs/Store.pm:61] which was called 4 times, avg 25µs/call:
# 2 times (20µs+35µs) by Foswiki::Store::Rcs::Handler::noCheckinPending at line 306 of /var/www/foswikidev/core/lib/Foswiki/Store/Rcs/Handler.pm, avg 27µs/call
# 2 times (12µs+35µs) by Foswiki::Store::Rcs::Handler::noCheckinPending at line 307 of /var/www/foswikidev/core/lib/Foswiki/Store/Rcs/Handler.pm, avg 24µs/call # spent 70µs making 4 calls to Foswiki::Store::encode, avg 17µs/call |
62 | 1 | 1µs | *_unlink = sub { unlink( _encode( $_[0] ) ); }; | ||
63 | } | ||||
64 | else { | ||||
65 | *_decode = sub { return $_[0] }; | ||||
66 | *_encode = sub { return $_[0] }; | ||||
67 | *_stat = \&stat; | ||||
68 | *_unlink = \&unlink; | ||||
69 | } | ||||
70 | 1 | 2.63ms | 1 | 11µs | } # spent 11µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@47 |
71 | |||||
72 | # Note to developers; please undef *all* fields in the object explicitly, | ||||
73 | # whether they are references or not. That way this method is "golden | ||||
74 | # documentation" of the live fields in the object. | ||||
75 | # spent 30µs (28+2) within Foswiki::Store::Rcs::Store::finish which was called:
# once (28µs+2µs) by Foswiki::finish at line 2488 of /var/www/foswikidev/core/lib/Foswiki.pm | ||||
76 | 1 | 600ns | my $this = shift; | ||
77 | 1 | 21µs | 1 | 2µs | $this->SUPER::finish(); # spent 2µs making 1 call to Foswiki::Store::finish |
78 | 1 | 4µs | undef $this->{searchFn}; | ||
79 | } | ||||
80 | |||||
81 | # SMELL: this module does not respect $Foswiki::inUnitTestMode; tests | ||||
82 | # just sit on top of the store which is configured in the current $Foswiki::cfg. | ||||
83 | # Most of the time this is ok, as store listeners will be told that | ||||
84 | # the store is in test mode, so caches should be unaffected. However | ||||
85 | # it's very untidy, potentially risky, and causes grief when unit tests | ||||
86 | # don't clean up after themselves. | ||||
87 | |||||
88 | # PACKAGE PRIVATE | ||||
89 | # Get a handler for the given object in the store. | ||||
90 | sub getHandler { | ||||
91 | |||||
92 | #my ( $this, $web, $topic, $attachment ) = @_; | ||||
93 | ASSERT( 0, "Must be implemented by subclasses" ) if DEBUG; | ||||
94 | } | ||||
95 | |||||
96 | # spent 75.8s (1.58+74.2) within Foswiki::Store::Rcs::Store::readTopic which was called 26327 times, avg 2.88ms/call:
# 26327 times (1.58s+74.2s) by Foswiki::Meta::loadVersion at line 1156 of /var/www/foswikidev/core/lib/Foswiki/Meta.pm, avg 2.88ms/call | ||||
97 | 26327 | 11.7ms | my ( $this, $topicObject, $version ) = @_; | ||
98 | |||||
99 | 26327 | 81.1ms | 78981 | 808ms | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); # spent 730ms making 26327 calls to Foswiki::Store::RcsWrap::getHandler, avg 28µs/call
# spent 39.3ms making 26327 calls to Foswiki::Meta::web, avg 1µs/call
# spent 39.1ms making 26327 calls to Foswiki::Meta::topic, avg 1µs/call |
100 | 26327 | 4.85ms | my $isLatest = 0; | ||
101 | |||||
102 | # check that the requested revision actually exists | ||||
103 | 26327 | 9.83ms | if ( defined $version && $version =~ /^\d+$/ ) { | ||
104 | if ( $version == 0 || !$handler->revisionExists($version) ) { | ||||
105 | $version = $handler->getLatestRevisionID(); | ||||
106 | } | ||||
107 | } | ||||
108 | else { | ||||
109 | 26327 | 8.19ms | undef $version; # if it's a non-numeric string, we need to return undef | ||
110 | } | ||||
111 | |||||
112 | 26327 | 78.5ms | 26327 | 1.27s | return ( undef, undef ) unless $handler->storedDataExists(); # spent 1.27s making 26327 calls to Foswiki::Store::Rcs::Handler::storedDataExists, avg 48µs/call |
113 | |||||
114 | 26327 | 141ms | 26327 | 4.75s | ( my $text, $isLatest ) = $handler->getRevision($version); # spent 4.75s making 26327 calls to Foswiki::Store::Rcs::RcsWrapHandler::getRevision, avg 180µs/call |
115 | 26327 | 6.06ms | $text = '' unless defined $text; | ||
116 | 26327 | 51.4ms | 26327 | 1.48s | $text = _decode($text); # spent 1.48s making 26327 calls to Foswiki::Store::decode, avg 56µs/call |
117 | 26327 | 152ms | $text =~ s/\r//g; # Remove carriage returns | ||
118 | 26327 | 33.1ms | 26327 | 64.5s | Foswiki::Serialise::deserialise( $text, 'Embedded', $topicObject ); # spent 64.5s making 26327 calls to Foswiki::Serialise::deserialise, avg 2.45ms/call |
119 | |||||
120 | # Item11983 - switched off for performance reasons | ||||
121 | # unless ( $handler->noCheckinPending() ) { | ||||
122 | # | ||||
123 | # # If a checkin is pending, fix the TOPICINFO | ||||
124 | # my $ri = $topicObject->get('TOPICINFO'); | ||||
125 | # my $truth = $handler->getInfo($version); | ||||
126 | # for my $i (qw(author version date)) { | ||||
127 | # $ri->{$i} = $truth->{$i}; | ||||
128 | # } | ||||
129 | # } | ||||
130 | |||||
131 | # downgrade to first revision when there's no history | ||||
132 | 26327 | 84.6ms | 26327 | 1.27s | unless ( $handler->revisionHistoryExists() ) { # spent 1.27s making 26327 calls to Foswiki::Store::Rcs::Handler::revisionHistoryExists, avg 48µs/call |
133 | $version = 1; | ||||
134 | } | ||||
135 | |||||
136 | 26327 | 7.85ms | my $gotRev = $version; | ||
137 | 26327 | 9.48ms | unless ( defined $gotRev ) { | ||
138 | |||||
139 | # First try the just-loaded for the revision. | ||||
140 | 26304 | 40.8ms | 26304 | 78.5ms | my $ri = $topicObject->get('TOPICINFO'); # spent 78.5ms making 26304 calls to Foswiki::Meta::get, avg 3µs/call |
141 | 26304 | 21.3ms | $gotRev = $ri->{version} if defined $ri; | ||
142 | } | ||||
143 | 26327 | 2.94ms | if ( !defined $gotRev ) { | ||
144 | |||||
145 | # No revision from any other source; must be latest | ||||
146 | $gotRev = $handler->getLatestRevisionID(); | ||||
147 | ASSERT( defined $gotRev ) if DEBUG; | ||||
148 | } | ||||
149 | |||||
150 | # Add attachments that are new from reading the pub directory. | ||||
151 | # Only check the currently requested topic. | ||||
152 | 26327 | 14.3ms | if ( $Foswiki::cfg{RCS}{AutoAttachPubFiles} | ||
153 | && $topicObject->isSessionTopic() ) | ||||
154 | { | ||||
155 | my @knownAttachments = $topicObject->find('FILEATTACHMENT'); | ||||
156 | my @attachmentsFoundInPub = | ||||
157 | $handler->synchroniseAttachmentsList( \@knownAttachments ); | ||||
158 | my @validAttachmentsFound; | ||||
159 | foreach my $foundAttachment (@attachmentsFoundInPub) { | ||||
160 | |||||
161 | # test if the attachment filename is valid without having to | ||||
162 | # be sanitized. If not, ignore it. | ||||
163 | my $validated = Foswiki::Sandbox::validateAttachmentName( | ||||
164 | $foundAttachment->{name} ); | ||||
165 | unless ( defined $validated | ||||
166 | && $validated eq $foundAttachment->{name} ) | ||||
167 | { | ||||
168 | |||||
169 | print STDERR 'AutoAttachPubFiles ignoring ' | ||||
170 | . $foundAttachment->{name} . ' in ' | ||||
171 | . $topicObject->getPath() | ||||
172 | . ' - not a valid Foswiki Attachment filename'; | ||||
173 | } | ||||
174 | else { | ||||
175 | push @validAttachmentsFound, $foundAttachment; | ||||
176 | |||||
177 | # SMELL: how do we tell Meta what happened? | ||||
178 | } | ||||
179 | } | ||||
180 | |||||
181 | $topicObject->putAll( 'FILEATTACHMENT', @validAttachmentsFound ) | ||||
182 | if @validAttachmentsFound; | ||||
183 | } | ||||
184 | |||||
185 | 26327 | 3.24ms | $gotRev ||= 1; # anything going out here must be > 0 | ||
186 | |||||
187 | 26327 | 40.6ms | 26327 | 57.6ms | $topicObject->setLoadStatus( $gotRev, $isLatest ); # spent 57.6ms making 26327 calls to Foswiki::Meta::setLoadStatus, avg 2µs/call |
188 | 26327 | 180ms | return ( $gotRev, $isLatest ); | ||
189 | } | ||||
190 | |||||
191 | sub moveAttachment { | ||||
192 | my ( $this, $oldTopicObject, $oldAttachment, $newTopicObject, | ||||
193 | $newAttachment, $cUID ) | ||||
194 | = @_; | ||||
195 | |||||
196 | ASSERT($oldAttachment) if DEBUG; | ||||
197 | ASSERT($newAttachment) if DEBUG; | ||||
198 | |||||
199 | my $handler = | ||||
200 | $this->getHandler( $oldTopicObject->web, $oldTopicObject->topic, | ||||
201 | $oldAttachment ); | ||||
202 | if ( $handler->storedDataExists() ) { | ||||
203 | $handler->moveAttachment( $this, $newTopicObject->web, | ||||
204 | $newTopicObject->topic, $newAttachment ); | ||||
205 | } | ||||
206 | } | ||||
207 | |||||
208 | sub copyAttachment { | ||||
209 | my ( $this, $oldTopicObject, $oldAttachment, $newTopicObject, | ||||
210 | $newAttachment, $cUID ) | ||||
211 | = @_; | ||||
212 | |||||
213 | ASSERT($oldAttachment) if DEBUG; | ||||
214 | ASSERT($newAttachment) if DEBUG; | ||||
215 | |||||
216 | my $handler = | ||||
217 | $this->getHandler( $oldTopicObject->web, $oldTopicObject->topic, | ||||
218 | $oldAttachment ); | ||||
219 | return undef unless $handler->storedDataExists(); | ||||
220 | |||||
221 | my $rev = | ||||
222 | $handler->copyAttachment( $this, $newTopicObject->web, | ||||
223 | $newTopicObject->topic, $newAttachment ); | ||||
224 | return $rev; | ||||
225 | } | ||||
226 | |||||
227 | # spent 93µs (19+74) within Foswiki::Store::Rcs::Store::attachmentExists which was called:
# once (19µs+74µs) by Foswiki::Meta::hasAttachment at line 3052 of /var/www/foswikidev/core/lib/Foswiki/Meta.pm | ||||
228 | 1 | 1µs | my ( $this, $topicObject, $att ) = @_; | ||
229 | ASSERT($att) if DEBUG; | ||||
230 | 1 | 4µs | 3 | 37µs | my $handler = # spent 34µs making 1 call to Foswiki::Store::RcsWrap::getHandler
# spent 2µs making 1 call to Foswiki::Meta::topic
# spent 2µs making 1 call to Foswiki::Meta::web |
231 | $this->getHandler( $topicObject->web, $topicObject->topic, $att ); | ||||
232 | 1 | 8µs | 1 | 37µs | return $handler->storedDataExists(); # spent 37µs making 1 call to Foswiki::Store::Rcs::Handler::storedDataExists |
233 | } | ||||
234 | |||||
235 | sub moveTopic { | ||||
236 | my ( $this, $oldTopicObject, $newTopicObject, $cUID ) = @_; | ||||
237 | ASSERT($cUID) if DEBUG; | ||||
238 | |||||
239 | my $handler = | ||||
240 | $this->getHandler( $oldTopicObject->web, $oldTopicObject->topic ); | ||||
241 | my $rev = $handler->getLatestRevisionID(); | ||||
242 | |||||
243 | $handler->moveTopic( $this, $newTopicObject->web, $newTopicObject->topic ); | ||||
244 | } | ||||
245 | |||||
246 | sub moveWeb { | ||||
247 | my ( $this, $oldWebObject, $newWebObject, $cUID ) = @_; | ||||
248 | ASSERT($cUID) if DEBUG; | ||||
249 | |||||
250 | my $handler = $this->getHandler( $oldWebObject->web ); | ||||
251 | $handler->moveWeb( $newWebObject->web ); | ||||
252 | } | ||||
253 | |||||
254 | sub testAttachment { | ||||
255 | my ( $this, $topicObject, $attachment, $test ) = @_; | ||||
256 | ASSERT($attachment) if DEBUG; | ||||
257 | my $handler = | ||||
258 | $this->getHandler( $topicObject->web, $topicObject->topic, $attachment ); | ||||
259 | return $handler->test($test); | ||||
260 | } | ||||
261 | |||||
262 | sub openAttachment { | ||||
263 | my ( $this, $topicObject, $att, $mode, @opts ) = @_; | ||||
264 | ASSERT($att) if DEBUG; | ||||
265 | |||||
266 | my $handler = | ||||
267 | $this->getHandler( $topicObject->web, $topicObject->topic, $att ); | ||||
268 | return $handler->openStream( $mode, @opts ); | ||||
269 | } | ||||
270 | |||||
271 | # spent 731µs (31+700) within Foswiki::Store::Rcs::Store::getRevisionHistory which was called 2 times, avg 366µs/call:
# 2 times (31µs+700µs) by Foswiki::Meta::getRevisionHistory at line 2503 of /var/www/foswikidev/core/lib/Foswiki/Meta.pm, avg 366µs/call | ||||
272 | 2 | 2µs | my ( $this, $topicObject, $attachment ) = @_; | ||
273 | |||||
274 | 2 | 8µs | 6 | 48µs | my $handler = # spent 42µs making 2 calls to Foswiki::Store::RcsWrap::getHandler, avg 21µs/call
# spent 3µs making 2 calls to Foswiki::Meta::web, avg 2µs/call
# spent 3µs making 2 calls to Foswiki::Meta::topic, avg 2µs/call |
275 | $this->getHandler( $topicObject->web, $topicObject->topic, $attachment ); | ||||
276 | 2 | 14µs | 2 | 652µs | return $handler->getRevisionHistory(); # spent 652µs making 2 calls to Foswiki::Store::Rcs::Handler::getRevisionHistory, avg 326µs/call |
277 | } | ||||
278 | |||||
279 | sub getNextRevision { | ||||
280 | my ( $this, $topicObject ) = @_; | ||||
281 | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
282 | return $handler->getNextRevisionID(); | ||||
283 | } | ||||
284 | |||||
285 | sub getRevisionDiff { | ||||
286 | my ( $this, $topicObject, $rev2, $contextLines ) = @_; | ||||
287 | ASSERT( defined($contextLines) ) if DEBUG; | ||||
288 | |||||
289 | my $rcs = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
290 | my $diffs = | ||||
291 | $rcs->revisionDiff( $topicObject->getLoadedRev(), $rev2, $contextLines ); | ||||
292 | foreach my $d (@$diffs) { | ||||
293 | foreach my $i ( 1, 2 ) { | ||||
294 | _decode( $d->[$i] ); | ||||
295 | } | ||||
296 | } | ||||
297 | return $diffs; | ||||
298 | } | ||||
299 | |||||
300 | sub _getAttachmentVersionInfo { | ||||
301 | my ( $this, $topicObject, $rev, $attachment ) = @_; | ||||
302 | ASSERT($attachment) if DEBUG; | ||||
303 | |||||
304 | my $info; | ||||
305 | |||||
306 | if ( !defined($rev) ) { | ||||
307 | my $attachInfo = $topicObject->get('FILEATTACHMENT'); | ||||
308 | |||||
309 | # rewrite to info format similar to TOPICINFO | ||||
310 | if ( defined $attachInfo ) { | ||||
311 | $info->{date} = | ||||
312 | $attachInfo->{date} | ||||
313 | || $attachInfo->{movedwhen} | ||||
314 | || time(); | ||||
315 | |||||
316 | $info->{author} = | ||||
317 | $attachInfo->{user} | ||||
318 | || $attachInfo->{moveby} | ||||
319 | || $Foswiki::Users::BaseUserMapping::UNKNOWN_USER_CUID; | ||||
320 | |||||
321 | $info->{version} = 1 | ||||
322 | unless defined $attachInfo->{version}; | ||||
323 | |||||
324 | $info->{comment} = $attachInfo->{comment} | ||||
325 | if defined $attachInfo->{comment}; | ||||
326 | } | ||||
327 | } | ||||
328 | |||||
329 | if ( !defined($info) ) { | ||||
330 | my $handler = | ||||
331 | $this->getHandler( $topicObject->web, $topicObject->topic, | ||||
332 | $attachment ); | ||||
333 | $info = $handler->getInfo( $rev || 0 ); | ||||
334 | _decode( $info->{author} ); | ||||
335 | _decode( $info->{comment} ); | ||||
336 | } | ||||
337 | |||||
338 | return $info; | ||||
339 | } | ||||
340 | |||||
341 | # spent 14.9ms (94µs+14.8) within Foswiki::Store::Rcs::Store::getVersionInfo which was called 3 times, avg 4.98ms/call:
# 3 times (94µs+14.8ms) by Foswiki::Meta::getRevisionInfo at line 1603 of /var/www/foswikidev/core/lib/Foswiki/Meta.pm, avg 4.98ms/call | ||||
342 | 3 | 4µs | my ( $this, $topicObject, $rev, $attachment ) = @_; | ||
343 | 3 | 300ns | my $info; | ||
344 | |||||
345 | 3 | 600ns | return $this->_getAttachmentVersionInfo( $topicObject, $rev, $attachment ) | ||
346 | if ($attachment); | ||||
347 | |||||
348 | 3 | 4µs | 3 | 4µs | my $loadedRev = $topicObject->getLoadedRev(); # spent 4µs making 3 calls to Foswiki::Meta::getLoadedRev, avg 1µs/call |
349 | |||||
350 | # loadedRev may be undef even after a successful topic load in | ||||
351 | # META:TOPICINFO is missing from the topic. | ||||
352 | 3 | 3µs | if ( !defined($rev) || $loadedRev eq $rev ) { | ||
353 | 3 | 7µs | 3 | 8µs | if ( $topicObject->latestIsLoaded() ) { # spent 8µs making 3 calls to Foswiki::Meta::latestIsLoaded, avg 3µs/call |
354 | $info = $topicObject->get('TOPICINFO'); | ||||
355 | } | ||||
356 | else { | ||||
357 | # Load into a new object to avoid blowing away the object we | ||||
358 | # were passed; then selectively get the bits we want. | ||||
359 | 3 | 8µs | 3 | 99µs | my $dummy = Foswiki::Meta->new($topicObject); # spent 99µs making 3 calls to Foswiki::Meta::new, avg 33µs/call |
360 | 3 | 4µs | 3 | 1.68ms | $dummy->loadVersion(); # spent 1.68ms making 3 calls to Foswiki::Meta::loadVersion, avg 560µs/call |
361 | 3 | 4µs | 3 | 6µs | $info = $dummy->get('TOPICINFO'); # spent 6µs making 3 calls to Foswiki::Meta::get, avg 2µs/call |
362 | 3 | 4µs | 3 | 18µs | $topicObject->put( 'TOPICINFO', $info ); # spent 18µs making 3 calls to Foswiki::Meta::put, avg 6µs/call |
363 | 3 | 12µs | 3 | 13.0ms | $dummy->finish(); # spent 13.0ms making 3 calls to Foswiki::Meta::finish, avg 4.35ms/call |
364 | } | ||||
365 | } | ||||
366 | |||||
367 | 3 | 1µs | if ( not defined $info ) { | ||
368 | my $handler = | ||||
369 | $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
370 | $info = $handler->getInfo($rev); | ||||
371 | _decode( $info->{author} ); | ||||
372 | _decode( $info->{comment} ); | ||||
373 | } | ||||
374 | |||||
375 | # make sure there's at least author, date and version | ||||
376 | 3 | 2µs | $info->{author} = $Foswiki::Users::BaseUserMapping::UNKNOWN_USER_CUID | ||
377 | unless defined $info->{author}; | ||||
378 | 3 | 2µs | $info->{date} = time() unless defined $info->{date}; | ||
379 | 3 | 600ns | $info->{version} = 1 unless defined $info->{version}; | ||
380 | |||||
381 | 3 | 8µs | return $info; | ||
382 | } | ||||
383 | |||||
384 | sub saveAttachment { | ||||
385 | my ( $this, $topicObject, $name, $stream, $cUID, $options ) = @_; | ||||
386 | ASSERT($name) if DEBUG; | ||||
387 | |||||
388 | my $handler = | ||||
389 | $this->getHandler( $topicObject->web, $topicObject->topic, $name ); | ||||
390 | my $verb = ( $topicObject->hasAttachment($name) ) ? 'update' : 'insert'; | ||||
391 | my $comment = $options->{comment} || ''; | ||||
392 | |||||
393 | $comment = _encode($comment); | ||||
394 | $cUID = _encode($cUID); | ||||
395 | |||||
396 | $handler->addRevisionFromStream( $stream, $comment, $cUID, | ||||
397 | $options->{forcedate} ); | ||||
398 | |||||
399 | my $rev = $handler->getLatestRevisionID(); | ||||
400 | |||||
401 | return $rev; | ||||
402 | } | ||||
403 | |||||
404 | sub saveTopic { | ||||
405 | my ( $this, $topicObject, $cUID, $options ) = @_; | ||||
406 | ASSERT( $topicObject->isa('Foswiki::Meta') ) if DEBUG; | ||||
407 | ASSERT($cUID) if DEBUG; | ||||
408 | |||||
409 | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
410 | my $verb = ( $topicObject->existsInStore() ) ? 'update' : 'insert'; | ||||
411 | |||||
412 | # just in case they are not sequential | ||||
413 | my $nextRev = $handler->getNextRevisionID(); | ||||
414 | my $ti = $topicObject->get('TOPICINFO'); | ||||
415 | |||||
416 | if ( defined $ti ) { | ||||
417 | $ti->{version} = $nextRev; | ||||
418 | $ti->{author} = $cUID; | ||||
419 | } | ||||
420 | else { | ||||
421 | $topicObject->setRevisionInfo( | ||||
422 | version => $nextRev, | ||||
423 | author => $cUID, | ||||
424 | ); | ||||
425 | } | ||||
426 | my $comment = $options->{comment} || ''; | ||||
427 | |||||
428 | my $text = Foswiki::Serialise::serialise( $topicObject, 'Embedded' ); | ||||
429 | $text = _encode($text); | ||||
430 | $cUID = _encode($cUID); | ||||
431 | $comment = _encode($comment); | ||||
432 | $handler->addRevisionFromText( $text, $comment, $cUID, | ||||
433 | $options->{forcedate} ); | ||||
434 | |||||
435 | # reload the topic object | ||||
436 | $topicObject->unload(); | ||||
437 | $topicObject->loadVersion(); | ||||
438 | |||||
439 | return $nextRev; | ||||
440 | } | ||||
441 | |||||
442 | sub repRev { | ||||
443 | my ( $this, $topicObject, $cUID, %options ) = @_; | ||||
444 | |||||
445 | ASSERT( $topicObject->isa('Foswiki::Meta') ) if DEBUG; | ||||
446 | ASSERT($cUID) if DEBUG; | ||||
447 | my $info = $topicObject->getRevisionInfo(); | ||||
448 | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
449 | my $text = Foswiki::Serialise::serialise( $topicObject, 'Embedded' ); | ||||
450 | $text = _encode($text); | ||||
451 | |||||
452 | $handler->replaceRevision( $text, 'reprev', $cUID, | ||||
453 | defined $options{forcedate} ? $options{forcedate} : $info->{date} ); | ||||
454 | |||||
455 | my $rev = $handler->getLatestRevisionID(); | ||||
456 | |||||
457 | # reload the topic object | ||||
458 | $topicObject->unload(); | ||||
459 | $topicObject->loadVersion(); | ||||
460 | |||||
461 | return $rev; | ||||
462 | } | ||||
463 | |||||
464 | sub delRev { | ||||
465 | my ( $this, $topicObject, $cUID ) = @_; | ||||
466 | ASSERT( $topicObject->isa('Foswiki::Meta') ) if DEBUG; | ||||
467 | ASSERT($cUID) if DEBUG; | ||||
468 | |||||
469 | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
470 | my $rev = $handler->getLatestRevisionID(); | ||||
471 | if ( $rev <= 1 ) { | ||||
472 | throw Error::Simple( 'Cannot delete initial revision of ' | ||||
473 | . $topicObject->web . '.' | ||||
474 | . $topicObject->topic ); | ||||
475 | } | ||||
476 | $handler->deleteRevision(); | ||||
477 | |||||
478 | # restore last topic from repository | ||||
479 | $handler->restoreLatestRevision($cUID); | ||||
480 | |||||
481 | # reload the topic object | ||||
482 | $topicObject->unload(); | ||||
483 | $topicObject->loadVersion(); | ||||
484 | |||||
485 | return $rev; | ||||
486 | } | ||||
487 | |||||
488 | sub atomicLockInfo { | ||||
489 | my ( $this, $topicObject ) = @_; | ||||
490 | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
491 | return $handler->isLocked(); | ||||
492 | } | ||||
493 | |||||
494 | # It would be nice to use flock to do this, but the API is unreliable | ||||
495 | # (doesn't work on all platforms) | ||||
496 | sub atomicLock { | ||||
497 | my ( $this, $topicObject, $cUID ) = @_; | ||||
498 | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
499 | $handler->setLock( 1, $cUID ); | ||||
500 | } | ||||
501 | |||||
502 | sub atomicUnlock { | ||||
503 | my ( $this, $topicObject, $cUID ) = @_; | ||||
504 | |||||
505 | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
506 | $handler->setLock( 0, $cUID ); | ||||
507 | } | ||||
508 | |||||
509 | # A web _has_ to have a preferences topic to be a web. | ||||
510 | # spent 6.90ms (906µs+6.00) within Foswiki::Store::Rcs::Store::webExists which was called 101 times, avg 68µs/call:
# 101 times (906µs+6.00ms) by Foswiki::webExists at line 4035 of /var/www/foswikidev/core/lib/Foswiki.pm, avg 68µs/call | ||||
511 | 101 | 48µs | my ( $this, $web ) = @_; | ||
512 | |||||
513 | 101 | 25µs | return 0 unless defined $web; | ||
514 | 101 | 101µs | $web =~ s#\.#/#go; | ||
515 | |||||
516 | # Foswiki ships with TWikiCompatibilityPlugin but if it is disabled we | ||||
517 | # do not want the TWiki web to appear as a valid web to anyone. | ||||
518 | 101 | 50µs | if ( $web eq 'TWiki' ) { | ||
519 | unless ( exists $Foswiki::cfg{Plugins}{TWikiCompatibilityPlugin} | ||||
520 | && defined $Foswiki::cfg{Plugins}{TWikiCompatibilityPlugin}{Enabled} | ||||
521 | && $Foswiki::cfg{Plugins}{TWikiCompatibilityPlugin}{Enabled} == 1 ) | ||||
522 | { | ||||
523 | return 0; | ||||
524 | } | ||||
525 | } | ||||
526 | 100 | 196µs | 100 | 2.38ms | my $handler = $this->getHandler( $web, $Foswiki::cfg{WebPrefsTopicName} ); # spent 2.38ms making 100 calls to Foswiki::Store::RcsWrap::getHandler, avg 24µs/call |
527 | 100 | 331µs | 100 | 3.62ms | return $handler->storedDataExists(); # spent 3.62ms making 100 calls to Foswiki::Store::Rcs::Handler::storedDataExists, avg 36µs/call |
528 | } | ||||
529 | |||||
530 | # spent 13.0ms (1.44+11.6) within Foswiki::Store::Rcs::Store::topicExists which was called 197 times, avg 66µs/call:
# 156 times (1.17ms+9.19ms) by Foswiki::topicExists at line 4052 of /var/www/foswikidev/core/lib/Foswiki.pm, avg 66µs/call
# 29 times (191µs+1.59ms) by Foswiki::Meta::existsInStore at line 722 of /var/www/foswikidev/core/lib/Foswiki/Meta.pm, avg 61µs/call
# 12 times (78µs+817µs) by Foswiki::_includeTopic at line 155 of /var/www/foswikidev/core/lib/Foswiki/Macros/INCLUDE.pm, avg 75µs/call | ||||
531 | 197 | 145µs | my ( $this, $web, $topic ) = @_; | ||
532 | |||||
533 | 197 | 82µs | return 0 unless defined $web && $web ne ''; | ||
534 | 197 | 85µs | $web =~ s#\.#/#go; | ||
535 | 197 | 42µs | return 0 unless defined $topic && $topic ne ''; | ||
536 | |||||
537 | 197 | 226µs | 197 | 4.93ms | my $handler = $this->getHandler( $web, $topic ); # spent 4.93ms making 197 calls to Foswiki::Store::RcsWrap::getHandler, avg 25µs/call |
538 | 197 | 599µs | 197 | 6.67ms | return $handler->storedDataExists(); # spent 6.67ms making 197 calls to Foswiki::Store::Rcs::Handler::storedDataExists, avg 34µs/call |
539 | } | ||||
540 | |||||
541 | # Record a change in the web history | ||||
542 | sub recordChange { | ||||
543 | my $this = shift; | ||||
544 | my %args = @_; | ||||
545 | |||||
546 | my $web = $args{path}; | ||||
547 | |||||
548 | # Support for Foswiki < 2 | ||||
549 | my $topic = '.'; | ||||
550 | if ( $web =~ /\./ ) { | ||||
551 | ( $web, $topic ) = Foswiki->normalizeWebTopicName( undef, $web ); | ||||
552 | } | ||||
553 | |||||
554 | my $handler = $this->getHandler($web); | ||||
555 | $handler->recordChange(%args); | ||||
556 | } | ||||
557 | |||||
558 | # Implement Foswiki::Store | ||||
559 | sub eachChange { | ||||
560 | my ( $this, $meta, $since ) = @_; | ||||
561 | |||||
562 | my $handler = $this->getHandler( $meta->web ); | ||||
563 | require Foswiki::ListIterator; | ||||
564 | |||||
565 | my @changes; | ||||
566 | @changes = reverse grep { $_->{time} >= $since } $handler->readChanges(); | ||||
567 | return Foswiki::ListIterator->new( \@changes ); | ||||
568 | } | ||||
569 | |||||
570 | sub getApproxRevTime { | ||||
571 | my ( $this, $web, $topic ) = @_; | ||||
572 | |||||
573 | my $handler = $this->getHandler( $web, $topic ); | ||||
574 | return $handler->getLatestRevisionTime(); | ||||
575 | } | ||||
576 | |||||
577 | sub eachAttachment { | ||||
578 | my ( $this, $topicObject ) = @_; | ||||
579 | |||||
580 | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
581 | my @list = $handler->getAttachmentList(); | ||||
582 | require Foswiki::ListIterator; | ||||
583 | return new Foswiki::ListIterator( \@list ); | ||||
584 | } | ||||
585 | |||||
586 | # spent 2.79s (7.10ms+2.78) within Foswiki::Store::Rcs::Store::eachTopic which was called 40 times, avg 69.8ms/call:
# 40 times (7.10ms+2.78s) by Foswiki::Meta::eachTopic at line 1026 of /var/www/foswikidev/core/lib/Foswiki/Meta.pm, avg 69.8ms/call | ||||
587 | 40 | 28µs | my ( $this, $webObject ) = @_; | ||
588 | |||||
589 | 40 | 106µs | 80 | 874µs | my $handler = $this->getHandler( $webObject->web ); # spent 816µs making 40 calls to Foswiki::Store::RcsWrap::getHandler, avg 20µs/call
# spent 58µs making 40 calls to Foswiki::Meta::web, avg 1µs/call |
590 | 40 | 6.30ms | 40 | 2.78s | my @list = $handler->getTopicNames(); # spent 2.78s making 40 calls to Foswiki::Store::Rcs::Handler::getTopicNames, avg 69.6ms/call |
591 | |||||
592 | 40 | 48µs | require Foswiki::ListIterator; | ||
593 | 40 | 400µs | 40 | 282µs | return new Foswiki::ListIterator( \@list ); # spent 282µs making 40 calls to Foswiki::ListIterator::new, avg 7µs/call |
594 | } | ||||
595 | |||||
596 | # spent 17.9ms (641µs+17.3) within Foswiki::Store::Rcs::Store::eachWeb which was called 26 times, avg 688µs/call:
# 24 times (459µs+-459µs) by Foswiki::Store::Rcs::Store::eachWeb at line 610, avg 0s/call
# 2 times (182µs+17.7ms) by Foswiki::Meta::eachWeb at line 1005 of /var/www/foswikidev/core/lib/Foswiki/Meta.pm, avg 8.95ms/call | ||||
597 | 26 | 17µs | my ( $this, $webObject, $all ) = @_; | ||
598 | |||||
599 | # Undocumented; this fn actually accepts a web name as well. This is | ||||
600 | # to make the recursion more efficient. | ||||
601 | 26 | 12µs | 2 | 3µs | my $web = ref($webObject) ? $webObject->web : $webObject; # spent 3µs making 2 calls to Foswiki::Meta::web, avg 2µs/call |
602 | |||||
603 | 26 | 31µs | 26 | 645µs | my $handler = $this->getHandler($web); # spent 645µs making 26 calls to Foswiki::Store::RcsWrap::getHandler, avg 25µs/call |
604 | 26 | 54µs | 26 | 16.4ms | my @list = $handler->getWebNames(); # spent 16.4ms making 26 calls to Foswiki::Store::Rcs::Handler::getWebNames, avg 632µs/call |
605 | 26 | 7µs | if ($all) { | ||
606 | 26 | 33µs | my $root = $web ? "$web/" : ''; | ||
607 | 26 | 3µs | my @expandedList; | ||
608 | 26 | 37µs | while ( my $wp = shift(@list) ) { | ||
609 | 24 | 12µs | push( @expandedList, $wp ); | ||
610 | 24 | 46µs | 24 | 0s | my $it = $this->eachWeb( $root . $wp, $all ); # spent 19.9ms making 24 calls to Foswiki::Store::Rcs::Store::eachWeb, avg 828µs/call, recursion: max depth 2, sum of overlapping time 19.9ms |
611 | 24 | 68µs | 24 | 57µs | push( @expandedList, map { "$wp/$_" } $it->all() ); # spent 57µs making 24 calls to Foswiki::ListIterator::all, avg 2µs/call |
612 | } | ||||
613 | 26 | 20µs | @list = @expandedList; | ||
614 | } | ||||
615 | 26 | 38µs | @list = sort(@list); | ||
616 | 26 | 10µs | require Foswiki::ListIterator; | ||
617 | 26 | 131µs | 26 | 132µs | return new Foswiki::ListIterator( \@list ); # spent 132µs making 26 calls to Foswiki::ListIterator::new, avg 5µs/call |
618 | } | ||||
619 | |||||
620 | sub remove { | ||||
621 | my ( $this, $cUID, $topicObject, $attachment ) = @_; | ||||
622 | ASSERT( $topicObject->web ) if DEBUG; | ||||
623 | |||||
624 | my $handler = | ||||
625 | $this->getHandler( $topicObject->web, $topicObject->topic, $attachment ); | ||||
626 | $handler->remove(); | ||||
627 | |||||
628 | my $more = 'Deleted ' . $topicObject->web; | ||||
629 | if ( my $topic = $topicObject->topic ) { | ||||
630 | $more .= '.' . $topic; | ||||
631 | } | ||||
632 | if ($attachment) { | ||||
633 | $more .= ': ' . $attachment; | ||||
634 | } | ||||
635 | } | ||||
636 | |||||
637 | # spent 108s (3.74ms+108) within Foswiki::Store::Rcs::Store::query which was called 80 times, avg 1.35s/call:
# 40 times (1.72ms+108s) by Foswiki::Meta::query at line 984 of /var/www/foswikidev/core/lib/Foswiki/Meta.pm, avg 2.71s/call
# 40 times (2.02ms+-2.02ms) by Foswiki::Store::QueryAlgorithms::BruteForce::_webQuery at line 166 of /var/www/foswikidev/core/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm, avg 0s/call | ||||
638 | 80 | 82µs | my ( $this, $query, $inputTopicSet, $session, $options ) = @_; | ||
639 | |||||
640 | 80 | 18µs | my $engine; | ||
641 | 80 | 385µs | 80 | 137µs | if ( $query->isa('Foswiki::Query::Node') ) { # spent 137µs making 80 calls to UNIVERSAL::isa, avg 2µs/call |
642 | 40 | 42µs | unless ( $this->{queryObj} ) { | ||
643 | 1 | 1µs | my $module = $Foswiki::cfg{Store}{QueryAlgorithm}; | ||
644 | 1 | 28µs | eval "require $module"; # spent 85µs executing statements in string eval | ||
645 | 1 | 700ns | die | ||
646 | "Bad {Store}{QueryAlgorithm}; suggest you run configure and select a different algorithm\n$@" | ||||
647 | if $@; | ||||
648 | 1 | 6µs | 1 | 32µs | $this->{queryObj} = $module->new(); # spent 32µs making 1 call to Foswiki::Store::QueryAlgorithms::BruteForce::new |
649 | } | ||||
650 | 40 | 26µs | $engine = $this->{queryObj}; | ||
651 | } | ||||
652 | else { | ||||
653 | ASSERT( $query->isa('Foswiki::Search::Node') ) if DEBUG; | ||||
654 | 40 | 36µs | unless ( $this->{searchQueryObj} ) { | ||
655 | 1 | 2µs | my $module = $Foswiki::cfg{Store}{SearchAlgorithm}; | ||
656 | 1 | 27µs | eval "require $module"; # spent 70µs executing statements in string eval | ||
657 | 1 | 400ns | die | ||
658 | "Bad {Store}{SearchAlgorithm}; suggest you run configure and select a different algorithm\n$@" | ||||
659 | if $@; | ||||
660 | 1 | 5µs | 1 | 31µs | $this->{searchQueryObj} = $module->new(); # spent 31µs making 1 call to Foswiki::Store::SearchAlgorithms::Forking::new |
661 | } | ||||
662 | 40 | 25µs | $engine = $this->{searchQueryObj}; | ||
663 | } | ||||
664 | |||||
665 | 2 | 40µs | 2 | 35µs | # spent 23µs (10+12) within Foswiki::Store::Rcs::Store::BEGIN@665 which was called:
# once (10µs+12µs) by Foswiki::Store::RcsWrap::BEGIN@23 at line 665 # spent 23µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@665
# spent 12µs making 1 call to strict::unimport |
666 | 80 | 796µs | 80 | 108s | return $engine->query( $query, $inputTopicSet, $session, $options ); # spent 157s making 80 calls to Foswiki::Store::Interfaces::QueryAlgorithm::query, avg 1.97s/call, recursion: max depth 1, sum of overlapping time 49.2s |
667 | 2 | 181µs | 2 | 27µs | # spent 18µs (8+9) within Foswiki::Store::Rcs::Store::BEGIN@667 which was called:
# once (8µs+9µs) by Foswiki::Store::RcsWrap::BEGIN@23 at line 667 # spent 18µs making 1 call to Foswiki::Store::Rcs::Store::BEGIN@667
# spent 9µs making 1 call to strict::import |
668 | } | ||||
669 | |||||
670 | sub getRevisionAtTime { | ||||
671 | my ( $this, $topicObject, $time ) = @_; | ||||
672 | |||||
673 | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
674 | return $handler->getRevisionAtTime($time); | ||||
675 | } | ||||
676 | |||||
677 | sub getLease { | ||||
678 | my ( $this, $topicObject ) = @_; | ||||
679 | |||||
680 | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
681 | my $lease = $handler->getLease(); | ||||
682 | return $lease; | ||||
683 | } | ||||
684 | |||||
685 | sub setLease { | ||||
686 | my ( $this, $topicObject, $lease ) = @_; | ||||
687 | |||||
688 | my $handler = $this->getHandler( $topicObject->web, $topicObject->topic ); | ||||
689 | $handler->setLease($lease); | ||||
690 | } | ||||
691 | |||||
692 | sub removeSpuriousLeases { | ||||
693 | my ( $this, $web ) = @_; | ||||
694 | my $handler = $this->getHandler($web); | ||||
695 | $handler->removeSpuriousLeases(); | ||||
696 | } | ||||
697 | |||||
698 | 1 | 3µs | 1; | ||
699 | __END__ |