AtteanX-Query-Cache
view release on metacpan or search on metacpan
lib/AtteanX/Query/Cache/Analyzer.pm view on Meta::CPAN
sub best_cost_improvement {
my $self = shift;
# First, we find the cost of the plan with the current cache:
my $algebra = $self->algebra;
my $curplanner = AtteanX::QueryPlanner::Cache::LDF->new;
my $curplan = $curplanner->plan_for_algebra($algebra, $self->model, [$self->graph]);
my $curcost = $curplanner->cost_for_plan($curplan, $self->model);
$self->log->trace("Cost of incumbent plan: $curcost");
my %costs;
my %triples;
my $percentage = 1-($self->improvement_threshold/100);
my $planner = AtteanX::Query::Cache::Analyzer::QueryPlanner->new;
foreach my $bgp ($algebra->subpatterns_of_type('Attean::Algebra::BGP')) { # TODO: Parallelize
foreach my $triple (@{ $bgp->triples }) { # TODO: May need quads
my $key = $triple->canonicalize->tuples_string;
next if ($self->model->is_cached($key));
next if ($self->model->ldf_store->count_triples_estimate($triple->values) > $self->max_triples);
$self->model->try($key);
if ($self->log->is_trace) {
foreach my $plan ($planner->plans_for_algebra($algebra, $self->model, [$self->graph])) {
my $cost = $planner->cost_for_plan($plan, $self->model);
$self->log->trace("Cost $cost for:\n" . $plan->as_string);
}
}
my $plan = $planner->plan_for_algebra($algebra, $self->model, [$self->graph]);
$self->log->debug("Alternative plan after fetching $key:\n" . $plan->as_string);
$costs{$key} = $planner->cost_for_plan($plan, $self->model);
$self->log->info("Triple $key has cost $costs{$key}, current $curcost");
if ($costs{$key} < $curcost * $percentage) {
$triples{$key} = $triple;
}
}
}
no sort 'stable';
my @worthy = map { $triples{$_} } sort {$costs{$a} <=> $costs{$b}} keys(%triples);
return splice(@worthy,0, $self->improvement_top-1);
}
( run in 0.371 second using v1.01-cache-2.11-cpan-05162d3a2b1 )