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   1282 use strict;
  77         185  
  77         2798  
8 77     77   423 use warnings;
  77         171  
  77         2347  
9              
10 77     77   426 use Graph::AdjacencyMap qw(:flags :fields);
  77         183  
  77         17045  
11 77     77   581 use base 'Graph::AdjacencyMap';
  77         224  
  77         40259  
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 1624     1624   4189 my ($class, $flags, $arity) = @_;
24 1624         5418 (my $m = $class->SUPER::_new($flags | _LIGHT, $arity))->[ _attr ] = {};
25 1624 100       7359 @$m[ @LOCAL_OVERRIDE ] = map $m->[ $_ ] ? [] : undef, @LOCAL_OVERRIDE;
26 1624         4748 $m;
27             }
28              
29             sub set_paths {
30 30446     30446 1 53991 my ($m, @paths) = @_;
31 30446         63091 my ($f, $a, $i, $pi, $map_s, $map_p, @ids) = (@$m[ _f, _arity, _i, _pi, _s, _p ]);
32 30446         53578 for (@paths) {
33 46068         65331 my $k = $_;
34 46068 50 66     133786 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
35 46068 100       114109 my $l = $a == 1 ? $k : join ' ', @$k;
36 46068 100       110398 push(@ids, $pi->{ $l }), next if defined $pi->{ $l };
37 34189         64570 $i->[ my $n = $m->[ _n ]++ ] = $_;
38 34189         80641 $pi->{ $l } = $n;
39 34189         49174 push @ids, $n;
40 34189 100       75855 _successors_add($f, $map_s, $map_p, $n, $_) if $map_s;
41             }
42 30446         65086 @ids;
43             }
44              
45             sub _successors_set {
46 26899     26899   38371 my $val = pop;
47 26899         46045 my ($f, $map_s, $map_p, $id, $path) = @_;
48 26899         60311 my $pairs = Graph::AdjacencyMap::_successors_cartesian(($f & _UNORD), 0, $path);
49 77     77   683 no warnings 'uninitialized'; # needed 5.8
  77         225  
  77         129534  
50 26899         122018 vec($map_s->[ $_->[0] ], $_->[1], 1) = $val for @$pairs; # row-major
51 26899 100       67337 return if !$map_p;
52 15056         51444 vec($map_p->[ $_->[1] ], $_->[0], 1) = $val for @$pairs;
53             }
54 26372     26372   43824 sub _successors_add { push @_, 1; goto &_successors_set }
  26372         60283  
55 527     527   954 sub _successors_del { push @_, 0; goto &_successors_set }
  527         1295  
56              
57             sub _paths_fromto {
58 787     787   1215 my $offset = pop;
59 787         1223 my ($i, $pi, $f, $map_x, @v) = ( @{ $_[0] }[ _i, _pi, _f, $offset ], @_[1..$#_] );
  787         2221  
60 787 50       2218 Graph::__carp_confess("undefined vertex") if grep !defined, @v;
61 787         6615 require Set::Object;
62 787         43147 my ($paths, $invert, $unord) = (Set::Object->new, $offset == _p, $f & _UNORD);
63 787         3190 for my $tuple (grep defined $_->[1], map [$_, $map_x->[$_]], @v) {
64 516         1817 my ($v, $s) = ($tuple->[0], scalar unpack("b*", $tuple->[1]));
65 516 100       5154 $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 787         6334 map $i->[ $pi->{ $_ } ], $paths->members;
71             }
72 464     464 1 2576 sub paths_from { push @_, _s; goto &_paths_fromto }
  464         1210  
73 323     323 1 1674 sub paths_to { push @_, _p; goto &_paths_fromto }
  323         776  
74              
75             sub _cessors {
76 27144     27144   38884 my $offset = pop;
77 27144         37276 my ($map_x, @v) = ( @{ $_[0] }[ $offset ], @_[1..$#_] );
  27144         72753  
78 27144 50       71851 Graph::__carp_confess("undefined vertex") if grep !defined, @v;
79 27144         107424 require Set::Object;
80 27144         171655 my $c = Set::Object->new;
81 27144         69239 for my $row (grep defined, @$map_x[ @v ]) {
82             # 10x quicker than: grep vec($row, $_, 1), 0..$#$m
83 26366         64662 my $s = unpack("b*", $row);
84 26366         235018 $c->insert(pos($s) - 1) while $s =~ /1/g;
85             }
86 27144         160861 $c->members;
87             }
88 25575     25575 1 41737 sub successors { push @_, _s; goto &_cessors }
  25575         59027  
89 1569     1569 1 4007 sub predecessors { push @_, _p; goto &_cessors }
  1569         3969  
90              
91             sub has_successor {
92 10     10 1 1101 my ($map_s, $u, $v) = ( @{ $_[0] }[ _s ], @_[1, 2] );
  10         60  
93 10 50       41 Graph::__carp_confess("undefined vertex") if grep !defined, $u, $v;
94 10   100     69 vec(($map_s->[ $u ] || return 0), $v, 1);
95             }
96              
97             sub get_ids_by_paths {
98 27525     27525 1 43618 my ($pi, $m, $list, $ensure, $deep) = ( @{ $_[0] }[ _pi ], @_ );
  27525         59158  
99 27525   100     72619 $deep ||= 0;
100             map {
101 27525         45276 my @ret = map {
102 42729 100       79098 my @ret2 = map {
103 75245 100       124903 my $id = $pi->{ $_ };
  75258         117826  
104 75258 100       158201 defined $id ? $id : $ensure ? $m->set_paths($_) : return;
    100          
105             } $deep > 1 ? @$_ : $_;
106 75207 100       156704 $deep > 1 ? \@ret2 : @ret2;
107             } $deep ? @$_ : $_;
108 42691 100       115639 $deep ? \@ret : @ret;
109             } @$list;
110             }
111              
112             sub has_path {
113 1004     1004 1 5414 my ($a, $pi, $k) = ( @{ $_[0] }[ _arity, _pi ], $_[1] );
  1004         2218  
114 1004 50 66     3198 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
115 1004 100       4896 $pi->{ $a == 1 ? $k : join ' ', @$k };
116             }
117              
118             sub _get_path_count {
119 875 100   875   2993 defined(my $dummy = &has_path) ? 1 : 0; # defined &x asks if func defined
120             }
121              
122             sub del_path {
123 556     556 1 2610 my ($f, $a, $i, $pi, $map_s, $map_p, $attr, $k) = ( @{ my $m = $_[0] }[ _f, _arity, _i, _pi, _s, _p, _attr ], $_[1] );
  556         1515  
124 556 50 66     1985 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
125 556 100       1593 my $l = $a == 1 ? $k : join ' ', @$k;
126 556 100       1349 return 0 if !exists $pi->{ $l };
127 549         2099 my $id = delete $pi->{ $l };
128 549         924 delete $attr->{ $l };
129 549         915 my $path = delete $i->[ $id ];
130 549 100       1787 _successors_del($f, $map_s, $map_p, $id, $path) if $map_s;
131 549         2071 return 1;
132             }
133              
134             sub rename_path {
135 12     12 1 630 my ($m, $from, $to) = @_;
136 12         29 my ($a, $i, $pi, $attr) = @$m[ _arity, _i, _pi, _attr ];
137 12 50       28 return 1 if $a > 1; # arity > 1, all integers, no names
138 12 50       28 return 0 unless exists $pi->{ $from };
139 12 100       64 $attr->{ $to } = delete $attr->{ $from } if $attr->{ $from };
140 12         36 $i->[ $pi->{ $to } = delete $pi->{ $from } ] = $to;
141 12         36 return 1;
142             }
143              
144             sub _set_path_attr_common {
145 5754     5754   14439 (my $m = $_[0])->set_paths($_[1]);
146 5754         11089 my ($a, $attr, $k) = ( @$m[ _arity, _attr ], $_[1] );
147 5754 100       12073 my $l = $a == 1 ? $k : join ' ', @$k;
148 5754         27734 \$attr->{ $l };
149             }
150              
151             sub _get_path_attrs {
152 12191     12191   18797 my ($a, $attr, $k) = ( @{ $_[0] }[ _arity, _attr ], $_[1] );
  12191         26904  
153 12191 50 66     39588 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
154 12191 100       31131 my $l = $a == 1 ? $k : join ' ', @$k;
155 12191         61475 $attr->{ $l };
156             }
157              
158             sub _del_path_attrs {
159 13 50   13   38 return undef unless defined &has_path;
160 13         20 my ($a, $attr, $k) = ( @{ $_[0] }[ _arity, _attr ], $_[1] );
  13         32  
161 13 100       46 my $l = $a == 1 ? $k : join ' ', @$k;
162 13 100       36 return 0 unless exists $attr->{ $l };
163 11         25 delete $attr->{ $l };
164 11         37 1;
165             }
166              
167             1;