← Index
NYTProf Performance Profile   « line view »
For /usr/local/bin/sa-learn
  Run on Tue Nov 7 05:38:10 2017
Reported on Tue Nov 7 06:16:01 2017

Filename/usr/local/lib/perl5/site_perl/Mail/SpamAssassin/NetSet.pm
StatementsExecuted 264 statements in 6.71ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1115.32ms23.3msMail::SpamAssassin::NetSet::::BEGIN@35Mail::SpamAssassin::NetSet::BEGIN@35
4211.04ms7.97msMail::SpamAssassin::NetSet::::add_cidrMail::SpamAssassin::NetSet::add_cidr
211298µs2.14msMail::SpamAssassin::NetSet::::_convert_ipv4_cidr_to_ipv6Mail::SpamAssassin::NetSet::_convert_ipv4_cidr_to_ipv6
411138µs1.74msMail::SpamAssassin::NetSet::::is_net_declaredMail::SpamAssassin::NetSet::is_net_declared
311128µs268µsMail::SpamAssassin::NetSet::::newMail::SpamAssassin::NetSet::new
411119µs263µsMail::SpamAssassin::NetSet::::_nets_contains_networkMail::SpamAssassin::NetSet::_nets_contains_network
187190µs356µsMail::SpamAssassin::NetSet::::CORE:matchMail::SpamAssassin::NetSet::CORE:match (opcode)
164174µs74µsMail::SpamAssassin::NetSet::::CORE:substMail::SpamAssassin::NetSet::CORE:subst (opcode)
11148µs69µsMail::SpamAssassin::NetSet::::BEGIN@21Mail::SpamAssassin::NetSet::BEGIN@21
11146µs496µsMail::SpamAssassin::NetSet::::BEGIN@26Mail::SpamAssassin::NetSet::BEGIN@26
11132µs64µsMail::SpamAssassin::NetSet::::BEGIN@22Mail::SpamAssassin::NetSet::BEGIN@22
11130µs205µsMail::SpamAssassin::NetSet::::BEGIN@29Mail::SpamAssassin::NetSet::BEGIN@29
11128µs270µsMail::SpamAssassin::NetSet::::BEGIN@31Mail::SpamAssassin::NetSet::BEGIN@31
11124µs31µsMail::SpamAssassin::NetSet::::BEGIN@23Mail::SpamAssassin::NetSet::BEGIN@23
11124µs89µsMail::SpamAssassin::NetSet::::BEGIN@24Mail::SpamAssassin::NetSet::BEGIN@24
11123µs918µsMail::SpamAssassin::NetSet::::BEGIN@25Mail::SpamAssassin::NetSet::BEGIN@25
11120µs76µsMail::SpamAssassin::NetSet::::BEGIN@28Mail::SpamAssassin::NetSet::BEGIN@28
0000s0sMail::SpamAssassin::NetSet::::DESTROYMail::SpamAssassin::NetSet::DESTROY
0000s0sMail::SpamAssassin::NetSet::::__ANON__[:332]Mail::SpamAssassin::NetSet::__ANON__[:332]
0000s0sMail::SpamAssassin::NetSet::::cloneMail::SpamAssassin::NetSet::clone
0000s0sMail::SpamAssassin::NetSet::::contains_ipMail::SpamAssassin::NetSet::contains_ip
0000s0sMail::SpamAssassin::NetSet::::contains_netMail::SpamAssassin::NetSet::contains_net
0000s0sMail::SpamAssassin::NetSet::::ditch_cacheMail::SpamAssassin::NetSet::ditch_cache
0000s0sMail::SpamAssassin::NetSet::::get_num_netsMail::SpamAssassin::NetSet::get_num_nets
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# Mail::SpamAssassin::NetSet - object to manipulate CIDR net IP addrs
2# <@LICENSE>
3# Licensed to the Apache Software Foundation (ASF) under one or more
4# contributor license agreements. See the NOTICE file distributed with
5# this work for additional information regarding copyright ownership.
6# The ASF licenses this file to you under the Apache License, Version 2.0
7# (the "License"); you may not use this file except in compliance with
8# the License. You may obtain a copy of the License at:
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17# </@LICENSE>
18
19package Mail::SpamAssassin::NetSet;
20
21261µs291µs
# spent 69µs (48+22) within Mail::SpamAssassin::NetSet::BEGIN@21 which was called: # once (48µs+22µs) by Mail::SpamAssassin::Conf::BEGIN@86 at line 21
use strict;
# spent 69µs making 1 call to Mail::SpamAssassin::NetSet::BEGIN@21 # spent 22µs making 1 call to strict::import
22271µs296µs
# spent 64µs (32+32) within Mail::SpamAssassin::NetSet::BEGIN@22 which was called: # once (32µs+32µs) by Mail::SpamAssassin::Conf::BEGIN@86 at line 22
use warnings;
# spent 64µs making 1 call to Mail::SpamAssassin::NetSet::BEGIN@22 # spent 32µs making 1 call to warnings::import
23275µs237µs
# spent 31µs (24+6) within Mail::SpamAssassin::NetSet::BEGIN@23 which was called: # once (24µs+6µs) by Mail::SpamAssassin::Conf::BEGIN@86 at line 23
use bytes;
# spent 31µs making 1 call to Mail::SpamAssassin::NetSet::BEGIN@23 # spent 6µs making 1 call to bytes::import
24264µs2154µs
# spent 89µs (24+65) within Mail::SpamAssassin::NetSet::BEGIN@24 which was called: # once (24µs+65µs) by Mail::SpamAssassin::Conf::BEGIN@86 at line 24
use re 'taint';
# spent 89µs making 1 call to Mail::SpamAssassin::NetSet::BEGIN@24 # spent 65µs making 1 call to re::import
25284µs21.81ms
# spent 918µs (23+895) within Mail::SpamAssassin::NetSet::BEGIN@25 which was called: # once (23µs+895µs) by Mail::SpamAssassin::Conf::BEGIN@86 at line 25
use Time::HiRes qw(time);
# spent 918µs making 1 call to Mail::SpamAssassin::NetSet::BEGIN@25 # spent 895µs making 1 call to Time::HiRes::import
263100µs3947µs
# spent 496µs (46+451) within Mail::SpamAssassin::NetSet::BEGIN@26 which was called: # once (46µs+451µs) by Mail::SpamAssassin::Conf::BEGIN@86 at line 26
use NetAddr::IP 4.000;
# spent 496µs making 1 call to Mail::SpamAssassin::NetSet::BEGIN@26 # spent 433µs making 1 call to NetAddr::IP::import # spent 18µs making 1 call to UNIVERSAL::VERSION
27
28262µs2132µs
# spent 76µs (20+56) within Mail::SpamAssassin::NetSet::BEGIN@28 which was called: # once (20µs+56µs) by Mail::SpamAssassin::Conf::BEGIN@86 at line 28
use Mail::SpamAssassin::Util;
# spent 76µs making 1 call to Mail::SpamAssassin::NetSet::BEGIN@28 # spent 56µs making 1 call to Exporter::import
29287µs2379µs
# spent 205µs (30+174) within Mail::SpamAssassin::NetSet::BEGIN@29 which was called: # once (30µs+174µs) by Mail::SpamAssassin::Conf::BEGIN@86 at line 29
use Mail::SpamAssassin::Logger;
# spent 205µs making 1 call to Mail::SpamAssassin::NetSet::BEGIN@29 # spent 174µs making 1 call to Exporter::import
30
3112µs
# spent 270µs (28+242) within Mail::SpamAssassin::NetSet::BEGIN@31 which was called: # once (28µs+242µs) by Mail::SpamAssassin::Conf::BEGIN@86 at line 33
use vars qw{
32 @ISA $TESTCODE $NUMTESTS $have_patricia
331126µs2512µs};
# spent 270µs making 1 call to Mail::SpamAssassin::NetSet::BEGIN@31 # spent 242µs making 1 call to vars::import
34
35
# spent 23.3ms (5.32+18.0) within Mail::SpamAssassin::NetSet::BEGIN@35 which was called: # once (5.32ms+18.0ms) by Mail::SpamAssassin::Conf::BEGIN@86 at line 42
BEGIN {
36111µs eval {
371284µs require Net::Patricia;
38134µs116µs Net::Patricia->VERSION(1.16); # need AF_INET6 support
# spent 16µs making 1 call to version::_VERSION
39113µs1190µs import Net::Patricia;
# spent 190µs making 1 call to Exporter::import
4013µs $have_patricia = 1;
41 };
4213.85ms123.3ms}
# spent 23.3ms making 1 call to Mail::SpamAssassin::NetSet::BEGIN@35
43
44###########################################################################
45
46
# spent 268µs (128+140) within Mail::SpamAssassin::NetSet::new which was called 3 times, avg 89µs/call: # 3 times (128µs+140µs) by Mail::SpamAssassin::Conf::new_netset at line 5096 of Mail/SpamAssassin/Conf.pm, avg 89µs/call
sub new {
4737µs my ($class,$netset_name) = @_;
4837µs $class = ref($class) || $class;
49
5036µs $netset_name = '' if !defined $netset_name; # object name for debugging
51326µs my $self = {
52 name => $netset_name, num_nets => 0,
53 cache_hits => 0, cache_attempts => 0,
54 };
55361µs6140µs $self->{pt} = Net::Patricia->new(&AF_INET6) if $have_patricia;
# spent 128µs making 3 calls to Net::Patricia::new, avg 43µs/call # spent 11µs making 3 calls to Socket::AF_INET6, avg 4µs/call
56
5736µs bless $self, $class;
58331µs $self;
59}
60
61###########################################################################
62
63sub DESTROY {
64 my($self) = shift;
65 if (exists $self->{cache}) {
66 local($@, $!, $_); # protect outer layers from a potential surprise
67 my($hits, $attempts) = ($self->{cache_hits}, $self->{cache_attempts});
68 dbg("netset: cache %s hits/attempts: %d/%d, %.1f %%",
69 $self->{name}, $hits, $attempts, 100*$hits/$attempts) if $attempts > 0;
70 }
71}
72
73###########################################################################
74
75
# spent 7.97ms (1.04+6.93) within Mail::SpamAssassin::NetSet::add_cidr which was called 4 times, avg 1.99ms/call: # 2 times (605µs+4.95ms) by Mail::SpamAssassin::Conf::new_netset at line 5098 of Mail/SpamAssassin/Conf.pm, avg 2.78ms/call # 2 times (437µs+1.98ms) by Mail::SpamAssassin::Conf::new_netset at line 5099 of Mail/SpamAssassin/Conf.pm, avg 1.21ms/call
sub add_cidr {
76421µs my ($self, @nets) = @_;
77
78415µs $self->{nets} ||= [ ];
7947µs my $numadded = 0;
8047µs delete $self->{cache}; # invalidate cache (in case of late additions)
81
82414µs foreach my $cidr_orig (@nets) {
8347µs my $cidr = $cidr_orig; # leave original unchanged, useful for logging
84
85 # recognizes syntax:
86 # [IPaddr%scope]/len or IPaddr%scope/len or IPv4addr/mask
87 # optionally prefixed by a '!' to indicate negation (exclusion);
88 # the %scope (i.e. interface), /len or /mask are optional
89
90445µs local($1,$2,$3,$4);
91475µs425µs $cidr =~ s/^\s+//;
# spent 25µs making 4 calls to Mail::SpamAssassin::NetSet::CORE:subst, avg 6µs/call
92444µs48µs my $exclude = ($cidr =~ s/^!\s*//) ? 1 : 0;
# spent 8µs making 4 calls to Mail::SpamAssassin::NetSet::CORE:subst, avg 2µs/call
93
9447µs my $masklen; # netmask or a prefix length
95490µs433µs $masklen = $1 if $cidr =~ s{ / (.*) \z }{}xs;
# spent 33µs making 4 calls to Mail::SpamAssassin::NetSet::CORE:subst, avg 8µs/call
96
97 # discard optional brackets
98456µs49µs $cidr = $1 if $cidr =~ /^ \[ ( [^\]]* ) \] \z/xs;
# spent 9µs making 4 calls to Mail::SpamAssassin::NetSet::CORE:match, avg 2µs/call
99
10047µs my $scope;
101 # IPv6 Scoped Address (RFC 4007, RFC 6874, RFC 3986 "unreserved" charset)
102451µs47µs if ($cidr =~ s/ % ( [A-Z0-9._~-]* ) \z //xsi) { # scope <zone_id> ?
# spent 7µs making 4 calls to Mail::SpamAssassin::NetSet::CORE:subst, avg 2µs/call
103 $scope = $1; # interface specification
104 # discard interface specification, currently just ignored
105 info("netset: ignoring interface scope '%%%s' in IP address %s",
106 $scope, $cidr_orig);
107 }
108
10947µs my $is_ip4 = 0;
110455µs412µs if ($cidr =~ /^ \d+ (\. | \z) /x) { # looks like an IPv4 address
# spent 12µs making 4 calls to Mail::SpamAssassin::NetSet::CORE:match, avg 3µs/call
111232µs216µs if ($cidr =~ /^ (\d+) \. (\d+) \. (\d+) \. (\d+) \z/x) {
# spent 16µs making 2 calls to Mail::SpamAssassin::NetSet::CORE:match, avg 8µs/call
112 # also strips leading zeroes, not liked by inet_pton
113223µs $cidr = sprintf('%d.%d.%d.%d', $1,$2,$3,$4);
11424µs $masklen = 32 if !defined $masklen;
115 } elsif ($cidr =~ /^ (\d+) \. (\d+) \. (\d+) \.? \z/x) {
116 $cidr = sprintf('%d.%d.%d.0', $1,$2,$3);
117 $masklen = 24 if !defined $masklen;
118 } elsif ($cidr =~ /^ (\d+) \. (\d+) \.? \z/x) {
119 $cidr = sprintf('%d.%d.0.0', $1,$2);
120 $masklen = 16 if !defined $masklen;
121 } elsif ($cidr =~ /^ (\d+) \.? \z/x) {
122 $cidr = sprintf('%d.0.0.0', $1);
123 $masklen = 8 if !defined $masklen;
124 } else {
125 warn "netset: illegal IPv4 address given: '$cidr_orig'\n";
126 next;
127 }
128212µs $is_ip4 = 1;
129 }
130
131437µs if ($self->{pt}) {
132411µs if (defined $masklen) {
133236µs29µs $masklen =~ /^\d{1,3}\z/
# spent 9µs making 2 calls to Mail::SpamAssassin::NetSet::CORE:match, avg 4µs/call
134 or die "Network mask not supported, use a CIDR syntax: '$cidr_orig'";
135 }
13649µs my $key = $cidr;
13747µs my $prefix_len = $masklen;
138410µs if ($is_ip4) {
13928µs $key = '::ffff:' . $key; # turn it into an IPv4-mapped IPv6 addresses
14026µs $prefix_len += 96 if defined $prefix_len;
141 }
142418µs $prefix_len = 128 if !defined $prefix_len;
143410µs $key .= '/' . $prefix_len;
144 # dbg("netset: add_cidr (patricia trie) %s => %s",
145 # $cidr_orig, $exclude ? '!'.$key : $key);
146416µs defined eval {
147442µs4788µs $self->{pt}->add_string($key, $exclude ? '!'.$key : $key)
# spent 788µs making 4 calls to Net::Patricia::add_string, avg 197µs/call
148 } or warn "netset: illegal IP address given (patricia trie): ".
149 "'$key': $@\n";
150 }
151
152410µs $cidr .= '/' . $masklen if defined $masklen;
153
154440µs434µs my $ip = NetAddr::IP->new($cidr);
# spent 34µs making 4 calls to NetAddr::IP::Lite::new, avg 9µs/call
15547µs if (!defined $ip) {
156 warn "netset: illegal IP address given: '$cidr_orig'\n";
157 next;
158 }
159 # dbg("netset: add_cidr %s => %s => %s", $cidr_orig, $cidr, $ip);
160
161 # if this is an IPv4 address, create an IPv6 representation, too
16247µs my ($ip4, $ip6);
163414µs if ($is_ip4) {
16424µs $ip4 = $ip;
165216µs22.14ms $ip6 = $self->_convert_ipv4_cidr_to_ipv6($cidr);
# spent 2.14ms making 2 calls to Mail::SpamAssassin::NetSet::_convert_ipv4_cidr_to_ipv6, avg 1.07ms/call
166 } else {
16723µs $ip6 = $ip;
168 }
169
170 # bug 5931: this is O(n^2). bad if there are lots of nets. There are good
171 # reasons to keep it for linting purposes, though, so don't start skipping
172 # it until we have over 200 nets in our list
173831µs if (scalar @{$self->{nets}} < 200) {
174429µs41.74ms next if ($self->is_net_declared($ip4, $ip6, $exclude, 0));
# spent 1.74ms making 4 calls to Mail::SpamAssassin::NetSet::is_net_declared, avg 436µs/call
175 }
176
177 # note: it appears a NetAddr::IP object takes up about 279 bytes
178868µs push @{$self->{nets}}, {
179 exclude => $exclude,
180 ip4 => $ip4,
181 ip6 => $ip6,
182 as_string => $cidr_orig,
183 };
184443µs $numadded++;
185 }
186
18748µs $self->{num_nets} += $numadded;
188460µs $numadded;
189}
190
191sub get_num_nets {
192 my ($self) = @_;
193 return $self->{num_nets};
194}
195
196
# spent 2.14ms (298µs+1.84) within Mail::SpamAssassin::NetSet::_convert_ipv4_cidr_to_ipv6 which was called 2 times, avg 1.07ms/call: # 2 times (298µs+1.84ms) by Mail::SpamAssassin::NetSet::add_cidr at line 165, avg 1.07ms/call
sub _convert_ipv4_cidr_to_ipv6 {
19725µs my ($self, $cidr) = @_;
198
199 # only do this for IPv4 addresses
200222µs27µs return unless $cidr =~ /^\d+[.\/]/;
# spent 7µs making 2 calls to Mail::SpamAssassin::NetSet::CORE:match, avg 4µs/call
201
202230µs26µs if ($cidr !~ /\//) { # no mask
# spent 6µs making 2 calls to Mail::SpamAssassin::NetSet::CORE:match, avg 3µs/call
203 return NetAddr::IP->new6("::ffff:".$cidr);
204 }
205
206 # else we have a CIDR mask specified. use new6() to do this
207 #
2082116µs437µs my $ip6 = ""+(NetAddr::IP->new6($cidr));
# spent 20µs making 2 calls to NetAddr::IP::Lite::plus, avg 10µs/call # spent 16µs making 2 calls to NetAddr::IP::Lite::new6, avg 8µs/call
209 # 127.0.0.1 -> 0:0:0:0:0:0:7F00:0001/128
210 # 127/8 -> 0:0:0:0:0:0:7F00:0/104
211
212 # now, move that from 0:0:0:0:0:0: space to 0:0:0:0:0:ffff: space
213252µs4564µs if (!defined $ip6 || $ip6 !~ /^0:0:0:0:0:0:(.*)$/) {
# spent 298µs making 2 calls to Mail::SpamAssassin::NetSet::CORE:match, avg 149µs/call # spent 266µs making 2 calls to NetAddr::IP::Lite::__ANON__[NetAddr/IP/Lite.pm:238], avg 133µs/call
214 warn "oops! unparseable IPv6 address for $cidr: $ip6";
215 return;
216 }
217
218238µs215µs return NetAddr::IP->new6("::ffff:$1");
# spent 15µs making 2 calls to NetAddr::IP::Lite::new6, avg 8µs/call
219}
220
221
# spent 263µs (119+144) within Mail::SpamAssassin::NetSet::_nets_contains_network which was called 4 times, avg 66µs/call: # 4 times (119µs+144µs) by Mail::SpamAssassin::NetSet::is_net_declared at line 246, avg 66µs/call
sub _nets_contains_network {
22249µs my ($self, $net4, $net6, $exclude, $quiet, $netname, $declared) = @_;
223
22448µs return 0 unless (defined $self->{nets});
225
226840µs foreach my $net (@{$self->{nets}}) {
227 # check to see if the new network is contained by the old network
22825µs my $in4 = defined $net4 && defined $net->{ip4} && $net->{ip4}->contains($net4);
229223µs2144µs my $in6 = defined $net6 && defined $net->{ip6} && $net->{ip6}->contains($net6);
# spent 144µs making 2 calls to NetAddr::IP::Lite::contains, avg 72µs/call
23028µs if ($in4 || $in6) {
231 warn sprintf("netset: cannot %s %s as it has already been %s\n",
232 $exclude ? "exclude" : "include",
233 $netname,
234 $net->{exclude} ? "excluded" : "included") unless $quiet;
235 # a network that matches an excluded network isn't contained by "nets"
236 # return 0 if we're not just looking to see if the network was declared
237 return 0 if (!$declared && $net->{exclude});
238 return 1;
239 }
240 }
241451µs return 0;
242}
243
244
# spent 1.74ms (138µs+1.61) within Mail::SpamAssassin::NetSet::is_net_declared which was called 4 times, avg 436µs/call: # 4 times (138µs+1.61ms) by Mail::SpamAssassin::NetSet::add_cidr at line 174, avg 436µs/call
sub is_net_declared {
24549µs my ($self, $net4, $net6, $exclude, $quiet) = @_;
246486µs61.61ms return $self->_nets_contains_network($net4, $net6, $exclude,
# spent 1.34ms making 2 calls to NetAddr::IP::Lite::__ANON__[NetAddr/IP/Lite.pm:238], avg 672µs/call # spent 263µs making 4 calls to Mail::SpamAssassin::NetSet::_nets_contains_network, avg 66µs/call
247 $quiet, $net4 || $net6, 1);
248}
249
250sub contains_ip {
251 my ($self, $ip) = @_;
252 my $result = 0;
253
254 if (!$self->{num_nets}) { return 0 }
255
256 $self->{cache_attempts}++;
257 if ($self->{cache} && exists $self->{cache}{$ip}) {
258 dbg("netset: %s cached lookup on %s, %d networks, result: %s",
259 $self->{name}, $ip, $self->{num_nets}, $self->{cache}{$ip});
260 $self->{cache_hits}++;
261 return $self->{cache}{$ip};
262
263 } elsif ($self->{pt}) {
264 # do a quick lookup on a Patricia Trie
265 my $t0 = time;
266 local($1,$2,$3,$4); local $_ = $ip;
267 $_ = $1 if /^ \[ ( [^\]]* ) \] \z/xs; # discard optional brackets
268 s/%[A-Z0-9:._-]+\z//si; # discard interface specification
269 if (m{^ (\d+) \. (\d+) \. (\d+) \. (\d+) \z}x) {
270 $_ = sprintf('::ffff:%d.%d.%d.%d', $1,$2,$3,$4);
271 } else {
272 s/^IPv6://si; # discard optional 'IPv6:' prefix
273 }
274 eval { $result = $self->{pt}->match_string($_); 1 } or undef $result;
275 $result = defined $result && $result !~ /^!/ ? 1 : 0;
276 dbg("netset: %s patricia lookup on %s, %d networks, result: %s, %.3f ms",
277 $self->{name}, $ip, $self->{num_nets}, $result, 1000*(time - $t0));
278 } else {
279 # do a sequential search on a list of NetAddr::IP objects
280 my $t0 = time;
281 my ($ip4, $ip6);
282 if ($ip =~ /^\d+\./) {
283 $ip4 = NetAddr::IP->new($ip);
284 $ip6 = $self->_convert_ipv4_cidr_to_ipv6($ip);
285 } else {
286 $ip6 = NetAddr::IP->new($ip);
287 }
288 foreach my $net (@{$self->{nets}}) {
289 if ((defined $ip4 && defined $net->{ip4} && $net->{ip4}->contains($ip4))
290 || (defined $ip6 && defined $net->{ip6} && $net->{ip6}->contains($ip6))){
291 $result = !$net->{exclude};
292 last;
293 }
294 }
295 dbg("netset: %s lookup on %s, %d networks, result: %s, %.3f ms",
296 $self->{name}, $ip, $self->{num_nets}, $result, 1000*(time - $t0));
297 }
298
299 $self->{cache}{$ip} = $result;
300 return $result;
301}
302
303sub contains_net {
304 my ($self, $net) = @_;
305 my $exclude = $net->{exclude};
306 my $net4 = $net->{ip4};
307 my $net6 = $net->{ip6};
308 return $self->_nets_contains_network($net4, $net6, $exclude, 1, "", 0);
309}
310
311sub ditch_cache {
312 my ($self) = @_;
313 if (exists $self->{cache}) {
314 dbg("netset: ditch cache on %s", $self->{name});
315 delete $self->{cache};
316 }
317}
318
319sub clone {
320 my ($self) = @_;
321 my $dup = Mail::SpamAssassin::NetSet->new($self->{name});
322 if ($self->{nets}) {
323 @{$dup->{nets}} = @{$self->{nets}};
324 }
325 if ($self->{pt}) {
326 my $dup_pt = $dup->{pt};
327 $self->{pt}->climb(sub {
328 my $key = $_[0]; $key =~ s/^!//;
329 defined eval { $dup_pt->add_string($key, $_[0]) }
330 or die "Adding a network $_[0] to a patricia trie failed: $@";
331 1;
332 });
333 }
334 $dup->{num_nets} = $self->{num_nets};
335 return $dup;
336}
337
338###########################################################################
339
34018µs1;
 
# spent 356µs (90+266) within Mail::SpamAssassin::NetSet::CORE:match which was called 18 times, avg 20µs/call: # 4 times (12µs+0s) by Mail::SpamAssassin::NetSet::add_cidr at line 110, avg 3µs/call # 4 times (9µs+0s) by Mail::SpamAssassin::NetSet::add_cidr at line 98, avg 2µs/call # 2 times (31µs+266µs) by Mail::SpamAssassin::NetSet::_convert_ipv4_cidr_to_ipv6 at line 213, avg 149µs/call # 2 times (16µs+0s) by Mail::SpamAssassin::NetSet::add_cidr at line 111, avg 8µs/call # 2 times (9µs+0s) by Mail::SpamAssassin::NetSet::add_cidr at line 133, avg 4µs/call # 2 times (7µs+0s) by Mail::SpamAssassin::NetSet::_convert_ipv4_cidr_to_ipv6 at line 200, avg 4µs/call # 2 times (6µs+0s) by Mail::SpamAssassin::NetSet::_convert_ipv4_cidr_to_ipv6 at line 202, avg 3µs/call
sub Mail::SpamAssassin::NetSet::CORE:match; # opcode
# spent 74µs within Mail::SpamAssassin::NetSet::CORE:subst which was called 16 times, avg 5µs/call: # 4 times (33µs+0s) by Mail::SpamAssassin::NetSet::add_cidr at line 95, avg 8µs/call # 4 times (25µs+0s) by Mail::SpamAssassin::NetSet::add_cidr at line 91, avg 6µs/call # 4 times (8µs+0s) by Mail::SpamAssassin::NetSet::add_cidr at line 92, avg 2µs/call # 4 times (7µs+0s) by Mail::SpamAssassin::NetSet::add_cidr at line 102, avg 2µs/call
sub Mail::SpamAssassin::NetSet::CORE:subst; # opcode