| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package AtteanX::Model::SPARQLCache; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  |  | 
| 4 | 11 |  |  | 11 |  | 21736 | use v5.14; | 
|  | 11 |  |  |  |  | 32 |  | 
| 5 | 11 |  |  | 11 |  | 38 | use warnings; | 
|  | 11 |  |  |  |  | 15 |  | 
|  | 11 |  |  |  |  | 238 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 11 |  |  | 11 |  | 35 | use Moo; | 
|  | 11 |  |  |  |  | 11 |  | 
|  | 11 |  |  |  |  | 43 |  | 
| 8 | 11 |  |  | 11 |  | 7505 | use Types::Standard qw(InstanceOf); | 
|  | 11 |  |  |  |  | 12 |  | 
|  | 11 |  |  |  |  | 64 |  | 
| 9 | 11 |  |  | 11 |  | 3216 | use namespace::clean; | 
|  | 11 |  |  |  |  | 11 |  | 
|  | 11 |  |  |  |  | 53 |  | 
| 10 | 11 |  |  | 11 |  | 1505 | use List::Util qw(min); | 
|  | 11 |  |  |  |  | 14 |  | 
|  | 11 |  |  |  |  | 4849 |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | extends 'AtteanX::Model::SPARQL'; | 
| 13 |  |  |  |  |  |  | with 'MooX::Log::Any'; | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | has 'cache' => ( | 
| 16 |  |  |  |  |  |  | is => 'ro', | 
| 17 |  |  |  |  |  |  | isa => InstanceOf['CHI::Driver'], | 
| 18 |  |  |  |  |  |  | required => 1 | 
| 19 |  |  |  |  |  |  | ); | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | # Override the store's planner, to take back control | 
| 22 |  |  |  |  |  |  | sub plans_for_algebra { | 
| 23 | 12 |  |  | 12 | 0 | 166796 | return; | 
| 24 |  |  |  |  |  |  | } | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | sub cost_for_plan { | 
| 27 | 21294 |  |  | 21294 | 0 | 2489053 | my $self	= shift; | 
| 28 | 21294 |  |  |  |  | 17443 | my $plan	= shift; | 
| 29 | 21294 |  |  |  |  | 15354 | my $planner	= shift; | 
| 30 |  |  |  |  |  |  | #	warn $plan->as_string; | 
| 31 | 21294 | 100 |  |  |  | 148876 | if ($plan->isa('Attean::Plan::Iterator')) { | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 32 | 14 |  |  |  |  | 19 | my $cost = 2; | 
| 33 | 14 | 50 |  |  |  | 240 | $cost += int(log($plan->size_estimate+1)/log(10)) if ($plan->has_size_estimate); | 
| 34 | 14 |  |  |  |  | 154 | return $cost; | 
| 35 |  |  |  |  |  |  | } elsif ($plan->isa('Attean::Plan::Quad')) { | 
| 36 | 0 |  |  |  |  | 0 | return 100000; | 
| 37 |  |  |  |  |  |  | } elsif ($plan->isa('AtteanX::Plan::SPARQLBGP')) { | 
| 38 |  |  |  |  |  |  | # BGPs should have a cost proportional to the number of triple patterns, | 
| 39 |  |  |  |  |  |  | # but be much more costly if they contain a cartesian product. | 
| 40 | 1845 |  |  |  |  | 3910 | $self->log->trace('Estimating cost for single BGP'); | 
| 41 | 1845 | 50 |  |  |  | 57164 | if ($plan->children_are_variable_connected) { | 
| 42 | 1845 |  |  |  |  | 73292 | return 20 * scalar(@{ $plan->children }); | 
|  | 1845 |  |  |  |  | 5241 |  | 
| 43 |  |  |  |  |  |  | } else { | 
| 44 | 0 |  |  |  |  | 0 | return 200 * scalar(@{ $plan->children }); | 
|  | 0 |  |  |  |  | 0 |  | 
| 45 |  |  |  |  |  |  | } | 
| 46 |  |  |  |  |  |  | } elsif ($plan->does('Attean::API::Plan::Join')) { | 
| 47 | 19435 |  |  |  |  | 188803 | my @bgps = $plan->subpatterns_of_type('AtteanX::Plan::SPARQLBGP'); | 
| 48 | 19435 |  |  |  |  | 2810254 | my $countbgps = scalar(@bgps); | 
| 49 | 19435 | 100 |  |  |  | 31344 | return unless $countbgps; | 
| 50 |  |  |  |  |  |  | # Now, we have SPARQLBGPs as subplans, which is usually not wanted | 
| 51 | 19428 |  |  |  |  | 13572 | my @children	= @{ $plan->children }; | 
|  | 19428 |  |  |  |  | 26479 |  | 
| 52 | 19428 | 50 |  |  |  | 45907 | if ($self->log->is_trace) { | 
| 53 | 0 |  |  |  |  | 0 | $self->log->trace("Found $countbgps SPARQL BGP subplans, immediate children are of type " . join(', ', map {ref} @children)) | 
|  | 0 |  |  |  |  | 0 |  | 
| 54 |  |  |  |  |  |  | } | 
| 55 | 19428 |  |  |  |  | 533818 | my $cost = 0; | 
| 56 |  |  |  |  |  |  | # The below code is from Attean::API::SimpleCostPlanner | 
| 57 | 19428 | 100 |  |  |  | 68005 | if ($plan->isa('Attean::Plan::NestedLoopJoin')) { | 
|  |  | 50 |  |  |  |  |  | 
| 58 | 9862 |  |  |  |  | 152547 | my $lcost		= $planner->cost_for_plan($children[0], $self); | 
| 59 | 9862 |  |  |  |  | 765034 | my $rcost		= $planner->cost_for_plan($children[1], $self); | 
| 60 | 9862 | 50 |  |  |  | 589206 | if ($lcost == 0) { | 
|  |  | 50 |  |  |  |  |  | 
| 61 | 0 |  |  |  |  | 0 | $cost	= $rcost; | 
| 62 |  |  |  |  |  |  | } elsif ($rcost == 0) { | 
| 63 | 0 |  |  |  |  | 0 | $cost	= $lcost; | 
| 64 |  |  |  |  |  |  | } else { | 
| 65 | 9862 |  |  |  |  | 10600 | $cost	= $lcost * $rcost; | 
| 66 |  |  |  |  |  |  | } | 
| 67 | 9862 | 100 |  |  |  | 15725 | $cost++ if ($rcost > $lcost); | 
| 68 | 9862 | 100 |  |  |  | 20348 | $cost	*= 10 unless ($plan->children_are_variable_connected); | 
| 69 |  |  |  |  |  |  | } elsif ($plan->isa('Attean::Plan::HashJoin')) { | 
| 70 | 9566 |  |  |  |  | 18850 | my $joined		= $plan->children_are_variable_connected; | 
| 71 | 9566 |  |  |  |  | 487238 | my $lcost		= $planner->cost_for_plan($children[0], $self); | 
| 72 | 9566 |  |  |  |  | 752289 | my $rcost		= $planner->cost_for_plan($children[1], $self); | 
| 73 | 9566 |  |  |  |  | 583791 | $cost	= ($lcost + $rcost); | 
| 74 | 9566 | 100 |  |  |  | 18395 | $cost++ if ($rcost > $lcost); | 
| 75 | 9566 | 50 |  |  |  | 19122 | $cost	*= 100 unless ($plan->children_are_variable_connected); | 
| 76 |  |  |  |  |  |  | } | 
| 77 | 19428 | 50 |  |  |  | 672885 | if ($cost) { | 
| 78 | 19428 |  |  |  |  | 22134 | $cost *= $countbgps * 1.2; | 
| 79 | 19428 |  |  |  |  | 27190 | $cost = min($cost, 1_000_000_000); | 
| 80 | 19428 |  |  |  |  | 42766 | return int($cost); | 
| 81 |  |  |  |  |  |  | } | 
| 82 |  |  |  |  |  |  | } | 
| 83 | 0 |  |  |  |  | 0 | return; | 
| 84 |  |  |  |  |  |  | }; | 
| 85 |  |  |  |  |  |  |  | 
| 86 |  |  |  |  |  |  | sub is_cached { | 
| 87 | 3 |  |  | 3 | 0 | 132468 | my $self = shift; | 
| 88 | 3 |  |  |  |  | 4 | my $keypattern = shift; | 
| 89 | 3 |  |  |  |  | 35 | return $self->cache->is_valid($keypattern); | 
| 90 |  |  |  |  |  |  | } | 
| 91 |  |  |  |  |  |  |  | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | 1; |