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   1354 use strict;
  77         184  
  77         2335  
8 77     77   445 use warnings;
  77         231  
  77         2308  
9              
10 77     77   427 use Graph::AdjacencyMap qw(:flags :fields);
  77         207  
  77         16825  
11 77     77   560 use base 'Graph::AdjacencyMap';
  77         170  
  77         39798  
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   4225 my ($class, $flags, $arity) = @_;
24 1624         5370 (my $m = $class->SUPER::_new($flags | _LIGHT, $arity))->[ _attr ] = {};
25 1624 100       7518 @$m[ @LOCAL_OVERRIDE ] = map $m->[ $_ ] ? [] : undef, @LOCAL_OVERRIDE;
26 1624         4656 $m;
27             }
28              
29             sub set_paths {
30 30428     30428 1 54775 my ($m, @paths) = @_;
31 30428         64759 my ($f, $a, $i, $pi, $map_s, $map_p, @ids) = (@$m[ _f, _arity, _i, _pi, _s, _p ]);
32 30428         52327 for (@paths) {
33 45660         65734 my $k = $_;
34 45660 50 66     130065 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
35 45660 100       108931 my $l = $a == 1 ? $k : join ' ', @$k;
36 45660 100       114009 push(@ids, $pi->{ $l }), next if defined $pi->{ $l };
37 33765         62461 $i->[ my $n = $m->[ _n ]++ ] = $_;
38 33765         80782 $pi->{ $l } = $n;
39 33765         48758 push @ids, $n;
40 33765 100       74674 _successors_add($f, $map_s, $map_p, $n, $_) if $map_s;
41             }
42 30428         65151 @ids;
43             }
44              
45             sub _successors_set {
46 26477     26477   37144 my $val = pop;
47 26477         46146 my ($f, $map_s, $map_p, $id, $path) = @_;
48 26477         58917 my $pairs = Graph::AdjacencyMap::_successors_cartesian(($f & _UNORD), 0, $path);
49 77     77   668 no warnings 'uninitialized'; # needed 5.8
  77         208  
  77         125427  
50 26477         120226 vec($map_s->[ $_->[0] ], $_->[1], 1) = $val for @$pairs; # row-major
51 26477 100       66671 return if !$map_p;
52 14634         50388 vec($map_p->[ $_->[1] ], $_->[0], 1) = $val for @$pairs;
53             }
54 25966     25966   40382 sub _successors_add { push @_, 1; goto &_successors_set }
  25966         57809  
55 511     511   848 sub _successors_del { push @_, 0; goto &_successors_set }
  511         1237  
56              
57             sub _paths_fromto {
58 787     787   1247 my $offset = pop;
59 787         1233 my ($i, $pi, $f, $map_x, @v) = ( @{ $_[0] }[ _i, _pi, _f, $offset ], @_[1..$#_] );
  787         2248  
60 787 50       2151 Graph::__carp_confess("undefined vertex") if grep !defined, @v;
61 787         6330 require Set::Object;
62 787         41713 my ($paths, $invert, $unord) = (Set::Object->new, $offset == _p, $f & _UNORD);
63 787         3215 for my $tuple (grep defined $_->[1], map [$_, $map_x->[$_]], @v) {
64 516         1801 my ($v, $s) = ($tuple->[0], scalar unpack("b*", $tuple->[1]));
65 516 100       5136 $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         6623 map $i->[ $pi->{ $_ } ], $paths->members;
71             }
72 464     464 1 2860 sub paths_from { push @_, _s; goto &_paths_fromto }
  464         1169  
73 323     323 1 1874 sub paths_to { push @_, _p; goto &_paths_fromto }
  323         770  
74              
75             sub _cessors {
76 27057     27057   39872 my $offset = pop;
77 27057         37400 my ($map_x, @v) = ( @{ $_[0] }[ $offset ], @_[1..$#_] );
  27057         65620  
78 27057 50       68511 Graph::__carp_confess("undefined vertex") if grep !defined, @v;
79 27057         110752 require Set::Object;
80 27057         171842 my $c = Set::Object->new;
81 27057         63583 for my $row (grep defined, @$map_x[ @v ]) {
82             # 10x quicker than: grep vec($row, $_, 1), 0..$#$m
83 26273         64025 my $s = unpack("b*", $row);
84 26273         244498 $c->insert(pos($s) - 1) while $s =~ /1/g;
85             }
86 27057         173233 $c->members;
87             }
88 25494     25494 1 43770 sub successors { push @_, _s; goto &_cessors }
  25494         58458  
89 1563     1563 1 4240 sub predecessors { push @_, _p; goto &_cessors }
  1563         3911  
90              
91             sub has_successor {
92 10     10 1 1405 my ($map_s, $u, $v) = ( @{ $_[0] }[ _s ], @_[1, 2] );
  10         28  
93 10 50       41 Graph::__carp_confess("undefined vertex") if grep !defined, $u, $v;
94 10   100     60 vec(($map_s->[ $u ] || return 0), $v, 1);
95             }
96              
97             sub get_ids_by_paths {
98 45040     45040 1 67456 my ($pi, $m, $list, $ensure, $deep) = ( @{ $_[0] }[ _pi ], @_ );
  45040         93637  
99 45040   100     133043 $deep ||= 0;
100             map {
101 45040         73255 my @ret = map {
102 59850 100       110358 my @ret2 = map {
103 91981 100       156659 my $id = $pi->{ $_ };
  91994         143684  
104 91994 100       198387 defined $id ? $id : $ensure ? $m->set_paths($_) : return;
    100          
105             } $deep > 1 ? @$_ : $_;
106 91943 100       193337 $deep > 1 ? \@ret2 : @ret2;
107             } $deep ? @$_ : $_;
108 59812 100       170332 $deep ? \@ret : @ret;
109             } @$list;
110             }
111              
112             sub has_path {
113 1009     1009 1 5471 my ($a, $pi, $k) = ( @{ $_[0] }[ _arity, _pi ], $_[1] );
  1009         2180  
114 1009 50 66     3192 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
115 1009 100       4793 $pi->{ $a == 1 ? $k : join ' ', @$k };
116             }
117              
118             sub _get_path_count {
119 880 100   880   3167 defined(my $dummy = &has_path) ? 1 : 0; # defined &x asks if func defined
120             }
121              
122             sub del_path {
123 540     540 1 921 my ($f, $a, $i, $pi, $map_s, $map_p, $attr, $k) = ( @{ my $m = $_[0] }[ _f, _arity, _i, _pi, _s, _p, _attr ], $_[1] );
  540         1480  
124 540 50 66     1872 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
125 540 100       1647 my $l = $a == 1 ? $k : join ' ', @$k;
126 540 100       1282 return 0 if !exists $pi->{ $l };
127 533         996 my $id = delete $pi->{ $l };
128 533         1840 delete $attr->{ $l };
129 533         845 my $path = delete $i->[ $id ];
130 533 100       1720 _successors_del($f, $map_s, $map_p, $id, $path) if $map_s;
131 533         1910 return 1;
132             }
133              
134             sub rename_path {
135 12     12 1 557 my ($m, $from, $to) = @_;
136 12         26 my ($a, $i, $pi, $attr) = @$m[ _arity, _i, _pi, _attr ];
137 12 50       30 return 1 if $a > 1; # arity > 1, all integers, no names
138 12 50       26 return 0 unless exists $pi->{ $from };
139 12 100       36 $attr->{ $to } = delete $attr->{ $from } if $attr->{ $from };
140 12         36 $i->[ $pi->{ $to } = delete $pi->{ $from } ] = $to;
141 12         37 return 1;
142             }
143              
144             sub _set_path_attr_common {
145 5749     5749   14846 (my $m = $_[0])->set_paths($_[1]);
146 5749         11369 my ($a, $attr, $k) = ( @$m[ _arity, _attr ], $_[1] );
147 5749 100       12197 my $l = $a == 1 ? $k : join ' ', @$k;
148 5749         26783 \$attr->{ $l };
149             }
150              
151             sub _get_path_attrs {
152 12203     12203   19864 my ($a, $attr, $k) = ( @{ $_[0] }[ _arity, _attr ], $_[1] );
  12203         26614  
153 12203 50 66     39381 Graph::__carp_confess("Wrong number of args, want $a, got (@$k)") if $a != 1 and $a != @$k;
154 12203 100       29491 my $l = $a == 1 ? $k : join ' ', @$k;
155 12203         62251 $attr->{ $l };
156             }
157              
158             sub _del_path_attrs {
159 13 50   13   39 return undef unless defined &has_path;
160 13         28 my ($a, $attr, $k) = ( @{ $_[0] }[ _arity, _attr ], $_[1] );
  13         39  
161 13 100       41 my $l = $a == 1 ? $k : join ' ', @$k;
162 13 100       42 return 0 unless exists $attr->{ $l };
163 11         25 delete $attr->{ $l };
164 11         38 1;
165             }
166              
167             1;