File Coverage

blib/lib/Graph/AdjacencyMap/Light.pm
Criterion Covered Total %
statement 121 121 100.0
branch 56 66 84.8
condition 12 16 75.0
subroutine 25 25 100.0
pod 10 10 100.0
total 224 238 94.1


line stmt bran cond sub pod time code
1             package Graph::AdjacencyMap::Light;
2              
3             # THIS IS INTERNAL IMPLEMENTATION ONLY, NOT TO BE USED DIRECTLY.
4             # THE INTERFACE IS HARD TO USE AND GOING TO STAY THAT WAY AND
5             # ALMOST GUARANTEED TO CHANGE OR GO AWAY IN FUTURE RELEASES.
6              
7 77     77   1156 use strict;
  77         168  
  77         2223  
8 77     77   347 use warnings;
  77         132  
  77         2242  
9              
10 77     77   367 use Graph::AdjacencyMap qw(:flags :fields);
  77         144  
  77         14146  
11 77     77   497 use base 'Graph::AdjacencyMap';
  77         135  
  77         37689  
12              
13             # $SIG{__DIE__ } = \&Graph::__carp_confess;
14             # $SIG{__WARN__} = \&Graph::__carp_confess;
15              
16             my @LOCAL_OVERRIDE = (_s, _p);
17              
18             sub _is_COUNT () { 0 }
19             sub _is_MULTI () { 0 }
20             sub _is_REF () { 0 }
21              
22             sub _new {
23 1618     1618   3788 my ($class, $flags, $arity) = @_;
24 1618         5494 (my $m = $class->SUPER::_new($flags | _LIGHT, $arity))->[ _attr ] = {};
25 1618 100       6800 @$m[ @LOCAL_OVERRIDE ] = map $m->[ $_ ] ? [] : undef, @LOCAL_OVERRIDE;
26 1618         4085 $m;
27             }
28              
29             sub set_paths {
30 30303     30303 1 45379 my ($m, @paths) = @_;
31 30303         54714 my ($f, $a, $i, $pi, $map_s, $map_p, @ids) = (@$m[ _f, _arity, _i, _pi, _s, _p ]);
32 30303         45336 for (@paths) {
33 45737         53200 my $k = $_;
34 45737 50 66     110449 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
35 45737 100       93418 my $l = $a == 1 ? $k : join ' ', @$k;
36 45737 100       93199 push(@ids, $pi->{ $l }), next if defined $pi->{ $l };
37 33886         52935 $i->[ my $n = $m->[ _n ]++ ] = $_;
38 33886         60993 $pi->{ $l } = $n;
39 33886         40672 push @ids, $n;
40 33886 100       62421 _successors_add($f, $map_s, $map_p, $n, $_) if $map_s;
41             }
42 30303         55415 @ids;
43             }
44              
45             sub _successors_set {
46 26635     26635   30599 my $val = pop;
47 26635         38109 my ($f, $map_s, $map_p, $id, $path) = @_;
48 26635         53676 my $pairs = Graph::AdjacencyMap::_successors_cartesian(($f & _UNORD), 0, $path);
49 77     77   575 no warnings 'uninitialized'; # needed 5.8
  77         151  
  77         110719  
50 26635         99785 vec($map_s->[ $_->[0] ], $_->[1], 1) = $val for @$pairs; # row-major
51 26635 100       59126 return if !$map_p;
52 14828         42394 vec($map_p->[ $_->[1] ], $_->[0], 1) = $val for @$pairs;
53             }
54 26121     26121   32309 sub _successors_add { push @_, 1; goto &_successors_set }
  26121         50270  
55 514     514   1011 sub _successors_del { push @_, 0; goto &_successors_set }
  514         1118  
56              
57             sub _paths_fromto {
58 784     784   984 my $offset = pop;
59 784         990 my ($i, $pi, $f, $map_x, @v) = ( @{ $_[0] }[ _i, _pi, _f, $offset ], @_[1..$#_] );
  784         1902  
60 784 50       1845 Graph::__carp_confess("undefined vertex") if grep !defined, @v;
61 784         5699 require Set::Object;
62 784         36559 my ($paths, $invert, $unord) = (Set::Object->new, $offset == _p, $f & _UNORD);
63 784         2622 for my $tuple (grep defined $_->[1], map [$_, $map_x->[$_]], @v) {
64 509         1574 my ($v, $s) = ($tuple->[0], scalar unpack("b*", $tuple->[1]));
65 509 100       4318 $paths->insert(join ' ', (
    100          
66             $unord ? sort($v, pos($s) - 1) :
67             $invert ? (pos($s) - 1, $v) : ($v, pos($s) - 1)
68             )) while $s =~ /1/g;
69             }
70 784         5117 map $i->[ $pi->{ $_ } ], $paths->members;
71             }
72 461     461 1 1964 sub paths_from { push @_, _s; goto &_paths_fromto }
  461         1052  
73 323     323 1 1368 sub paths_to { push @_, _p; goto &_paths_fromto }
  323         656  
74              
75             sub _cessors {
76 27015     27015   33001 my $offset = pop;
77 27015         31313 my ($map_x, @v) = ( @{ $_[0] }[ $offset ], @_[1..$#_] );
  27015         57778  
78 27015 50       58818 Graph::__carp_confess("undefined vertex") if grep !defined, @v;
79 27015         100236 require Set::Object;
80 27015         153558 my $c = Set::Object->new;
81 27015         55324 for my $row (grep defined, @$map_x[ @v ]) {
82             # 10x quicker than: grep vec($row, $_, 1), 0..$#$m
83 26242         55856 my $s = unpack("b*", $row);
84 26242         229512 $c->insert(pos($s) - 1) while $s =~ /1/g;
85             }
86 27015         152732 $c->members;
87             }
88 25451     25451 1 38615 sub successors { push @_, _s; goto &_cessors }
  25451         50656  
89 1564     1564 1 3385 sub predecessors { push @_, _p; goto &_cessors }
  1564         3286  
90              
91             sub has_successor {
92 10     10 1 921 my ($map_s, $u, $v) = ( @{ $_[0] }[ _s ], @_[1, 2] );
  10         27  
93 10 50       31 Graph::__carp_confess("undefined vertex") if grep !defined, $u, $v;
94 10   100     50 vec(($map_s->[ $u ] || return 0), $v, 1);
95             }
96              
97             sub get_ids_by_paths {
98 44924     44924 1 58301 my ($pi, $m, $list, $ensure, $deep) = ( @{ $_[0] }[ _pi ], @_ );
  44924         82125  
99 44924   100     116831 $deep ||= 0;
100             map {
101 44924         61908 my @ret = map {
102 59943 100       94640 my @ret2 = map {
103 92216 100       129302 my $id = $pi->{ $_ };
  92229         123543  
104 92229 100       169802 defined $id ? $id : $ensure ? $m->set_paths($_) : return;
    100          
105             } $deep > 1 ? @$_ : $_;
106 92178 100       163536 $deep > 1 ? \@ret2 : @ret2;
107             } $deep ? @$_ : $_;
108 59905 100       147842 $deep ? \@ret : @ret;
109             } @$list;
110             }
111              
112             sub has_path {
113 999     999 1 4299 my ($a, $pi, $k) = ( @{ $_[0] }[ _arity, _pi ], $_[1] );
  999         1793  
114 999 50 66     2577 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
115 999 100       4081 $pi->{ $a == 1 ? $k : join ' ', @$k };
116             }
117              
118             sub _get_path_count {
119 870 100   870   2531 defined(my $dummy = &has_path) ? 1 : 0; # defined &x asks if func defined
120             }
121              
122             sub del_path {
123 543     543 1 768 my ($f, $a, $i, $pi, $map_s, $map_p, $attr, $k) = ( @{ my $m = $_[0] }[ _f, _arity, _i, _pi, _s, _p, _attr ], $_[1] );
  543         1222  
124 543 50 66     1577 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
125 543 100       1399 my $l = $a == 1 ? $k : join ' ', @$k;
126 543 100       1072 return 0 if !exists $pi->{ $l };
127 536         828 my $id = delete $pi->{ $l };
128 536         1638 delete $attr->{ $l };
129 536         761 my $path = delete $i->[ $id ];
130 536 100       1402 _successors_del($f, $map_s, $map_p, $id, $path) if $map_s;
131 536         1593 return 1;
132             }
133              
134             sub rename_path {
135 12     12 1 504 my ($m, $from, $to) = @_;
136 12         24 my ($a, $i, $pi, $attr) = @$m[ _arity, _i, _pi, _attr ];
137 12 50       23 return 1 if $a > 1; # arity > 1, all integers, no names
138 12 50       26 return 0 unless exists $pi->{ $from };
139 12 100       22 $attr->{ $to } = delete $attr->{ $from } if $attr->{ $from };
140 12         30 $i->[ $pi->{ $to } = delete $pi->{ $from } ] = $to;
141 12         30 return 1;
142             }
143              
144             sub _set_path_attr_common {
145 5718     5718   12205 (my $m = $_[0])->set_paths($_[1]);
146 5718         9451 my ($a, $attr, $k) = ( @$m[ _arity, _attr ], $_[1] );
147 5718 100       10677 my $l = $a == 1 ? $k : join ' ', @$k;
148 5718         23394 \$attr->{ $l };
149             }
150              
151             sub _get_path_attrs {
152 12101     12101   16229 my ($a, $attr, $k) = ( @{ $_[0] }[ _arity, _attr ], $_[1] );
  12101         21717  
153 12101 50 66     33623 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
154 12101 100       25026 my $l = $a == 1 ? $k : join ' ', @$k;
155 12101         51172 $attr->{ $l };
156             }
157              
158             sub _del_path_attrs {
159 13 50   13   38 return undef unless defined &has_path;
160 13         22 my ($a, $attr, $k) = ( @{ $_[0] }[ _arity, _attr ], $_[1] );
  13         33  
161 13 100       40 my $l = $a == 1 ? $k : join ' ', @$k;
162 13 100       43 return 0 unless exists $attr->{ $l };
163 11         22 delete $attr->{ $l };
164 11         33 1;
165             }
166              
167             1;