RDF-LDF
view release on metacpan or search on metacpan
lib/RDF/LDF.pm view on Meta::CPAN
}
# Public method
# Optimized method to find all bindings matching a pattern
# See:
# Verborgh, Ruben, et al. Querying Datasets on the Web with High Availability. ISWC2014
# http://linkeddatafragments.org/publications/iswc2014.pdf
sub get_pattern {
my ($self,$bgp,$context,%args) = @_;
unless (defined $bgp) {
RDF::LDF::Error->throw(text => "can't execute get_pattern for an empty pattern");
}
my (@triples) = ($bgp->isa('RDF::Trine::Statement') or $bgp->isa('RDF::Query::Algebra::Filter'))
? $bgp
: $bgp->triples;
unless (@triples) {
RDF::LDF::Error->throw(text => "can't execute get_pattern for an empty pattern");
}
my @vars = $bgp->referenced_variables;
my @bgps = map { $self->_parse_triple_pattern($_)} @triples;
my $sub = sub {
state $it = $self->_find_variable_bindings(\@bgps);
my $b = $it->();
return undef unless $b;
my $binding = RDF::Trine::VariableBindings->new({});
for my $key (keys %$b) {
my $val = $b->{$key};
$key =~ s{^\?}{};
$binding->set($key => $val);
}
$binding;
};
RDF::Trine::Iterator::Bindings->new($sub,\@vars);
}
sub _find_variable_bindings {
my $self = shift;
my $bgps = shift;
my $bindings = shift // {};
my $iterator = sub {
state $it;
state $results = sub {};
my $ret;
# Loop over all variabe bindings with multiple matches
while (!defined($ret = $results->())) {
unless (defined $it) {
# Find the an binding iterator for the best pattern from $bgpgs
($it,$bgps) = $self->_find_variable_bindings_($bgps);
return undef unless $it;
}
# Update all the other bgps with the current binding..
my $this_binding = $it->();
return undef unless $this_binding;
$bindings = { %$bindings , %$this_binding };
return $bindings unless @$bgps;
# Apply all the bindings to the rest of the bgps;
my $bgps_prime = $self->_apply_binding($this_binding,$bgps);
$results = $self->_find_variable_bindings($bgps_prime,$bindings);
}
$ret;
};
$iterator;
}
# Given an array ref of patterns return the variable bindings for the
# pattern with the least number of triples.
#
# my ($iterator, $rest) = $self->_find_variable_bindings([ {pattern} , {pattern} , ... ]);
#
# where:
#
# $iterator - Iterator for variable bindings for the winnnig pattern, or undef when no
# patterns are provided or we get zero results
#
# $rest - An array ref of patterns not containing the best pattern
sub _find_variable_bindings_ {
my ($self,$bgps) = @_;
return (undef, undef) unless _is_array_ref($bgps) && @$bgps > 0;
my ($pattern,$rest) = $self->_find_best_pattern($bgps);
return (undef,undef) unless defined $pattern;
my $it = $self->get_statements($pattern);
# Build a mapping of variable bindings to Triple nodes. E.g.
# {
# '?s' => 'subject' ,
# '?p' => 'predicate' ,
# '?o' => 'object' ,
#}
my %pattern_var_map = map { $pattern->{$_} =~ /^\?/ ? ($pattern->{$_} , $_) : () } keys %$pattern;
my $num_of_bindings = keys %pattern_var_map;
my $sub = sub {
my $triple = $it->();
( run in 0.720 second using v1.01-cache-2.11-cpan-df04353d9ac )