1 package Graph
::AdjacencyMap
::Light
;
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.
9 use Graph
::AdjacencyMap
qw(:flags :fields);
10 use base
'Graph::AdjacencyMap';
12 use Scalar
::Util
qw(weaken);
14 use Graph
::AdjacencyMap
::Heavy
;
15 use Graph
::AdjacencyMap
::Vertex
;
17 sub _V
() { 2 } # Graph::_V
18 sub _E
() { 3 } # Graph::_E
19 sub _F
() { 0 } # Graph::_F
22 my ($class, $graph, $flags, $arity) = @_;
23 my $m = bless [ ], $class;
25 $m->[ _f
] = $flags | _LIGHT
;
31 weaken
$m->[ _g
]; # So that DESTROY finds us earlier.
37 my ($n, $f, $a, $i, $s, $p) = @
$m;
39 @_ = sort @_ if ($f & _UNORD
);
44 unless (exists $s->{ $e0 } && exists $s->{ $e0 }->{ $e1 }) {
46 $i->{ $n } = [ $e0, $e1 ];
47 $s->{ $e0 }->{ $e1 } = $n;
48 $p->{ $e1 }->{ $e0 } = $n;
51 unless (exists $s->{ $e0 }) {
61 my ($n, $f, $a, $i, $s) = @
$m;
62 return 0 unless $a == @_;
65 @_ = sort @_ if ($f & _UNORD
);
67 return 0 unless exists $s->{ $e };
76 my ($n, $f, $a, $i, $s) = @
$m;
77 return undef unless $a == @_;
80 @_ = sort @_ if ($f & _UNORD
);
82 return undef unless exists $s->{ $e };
91 my ($n, $f, $a, $i, $s) = @
$m;
94 @_ = sort @_ if ($f & _UNORD
);
96 return undef unless exists $s->{ $e };
100 return exists $s->{ $e } ?
1 : 0;
105 my ($n, $f, $a, $i, $s) = @
$m;
111 my ($n, $f, $a, $i) = @
$m;
113 my ($k, $v) = each %$i;
115 return values %{ $i };
117 return map { [ $_ ] } values %{ $i };
126 my ($n, $f, $a, $i) = @
$m;
127 my $p = $i->{ $_[ 0 ] };
128 defined $p ?
( ref $p eq 'ARRAY' ? @
$p : $p ) : ( );
133 my ($n, $f, $a, $i, $s, $p) = @
$m;
135 @_ = sort @_ if ($f & _UNORD
);
137 return 0 unless exists $s->{ $e0 };
139 if (defined($n = $s->{ $e0 }->{ $e1 })) {
141 delete $s->{ $e0 }->{ $e1 };
142 delete $p->{ $e1 }->{ $e0 };
143 delete $s->{ $e0 } unless keys %{ $s->{ $e0 } };
144 delete $p->{ $e1 } unless keys %{ $p->{ $e1 } };
149 if (defined($n = $s->{ $e })) {
160 return wantarray ?
() : 0 unless defined $E->[ _s
];
163 return wantarray ?
() : 0 unless defined $V && defined $V->[ _s
];
164 # my $i = $V->_get_path_id( $_[0] );
166 ($V->[ _f
] & _LIGHT
) ?
167 $V->[ _s
]->{ $_[0] } :
168 $V->_get_path_id( $_[0] );
169 return wantarray ?
() : 0 unless defined $i && defined $E->[ _s
]->{ $i };
170 return keys %{ $E->[ _s
]->{ $i } };
176 my @s = $E->__successors($g, @_);
177 if (($E->[ _f
] & _UNORD
)) {
178 push @s, $E->__predecessors($g, @_);
179 my %s; @s{ @s } = ();
183 return wantarray ?
map { $V->[ _i
]->{ $_ } } @s : @s;
188 return wantarray ?
() : 0 unless defined $E->[ _p
];
191 return wantarray ?
() : 0 unless defined $V && defined $V->[ _s
];
192 # my $i = $V->_get_path_id( $_[0] );
194 ($V->[ _f
] & _LIGHT
) ?
195 $V->[ _s
]->{ $_[0] } :
196 $V->_get_path_id( $_[0] );
197 return wantarray ?
() : 0 unless defined $i && defined $E->[ _p
]->{ $i };
198 return keys %{ $E->[ _p
]->{ $i } };
204 my @p = $E->__predecessors($g, @_);
205 if ($E->[ _f
] & _UNORD
) {
206 push @p, $E->__successors($g, @_);
207 my %p; @p{ @p } = ();
211 return wantarray ?
map { $V->[ _i
]->{ $_ } } @p : @p;
215 # Major magic takes place here: we rebless the appropriate 'light'
216 # map into a more complex map and then redispatch the method.
218 my ($n, $f, $a, $i, $s, $p, $g) = @
$m;
219 my ($k, $v) = each %$i;
220 my @V = @
{ $g->[ _V
] };
221 my @E = $g->edges; # TODO: Both these (ZZZ) lines are mysteriously needed!
222 # ZZZ: an example of failing tests is t/52_edge_attributes.t.
223 if (ref $v eq 'ARRAY') { # Edges, then.
224 # print "Reedging.\n";
225 @E = $g->edges; # TODO: Both these (ZZZ) lines are mysteriously needed!
226 $g->[ _E
] = $m = Graph
::AdjacencyMap
::Heavy
->_new($f, 2);
229 # print "Revertexing.\n";
230 $m = Graph
::AdjacencyMap
::Vertex
->_new(($f & ~_LIGHT
), 1);
231 $m->[ _n
] = $V[ _n
];
232 $m->[ _i
] = $V[ _i
];
233 $m->[ _s
] = $V[ _s
];
234 $m->[ _p
] = $V[ _p
];
238 goto &{ ref($m) . "::__attr" }; # Redispatch.
241 sub _is_COUNT
() { 0 }
242 sub _is_MULTI
() { 0 }
243 sub _is_HYPER
() { 0 }
244 sub _is_UNIQ
() { 0 }