| Akron | 5cf5fca | 2017-10-09 19:01:47 +0200 | [diff] [blame] | 1 | package Krawfish::Compile::Node; |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 2 | use Array::Queue::Priority; |
| 3 | use Krawfish::Util::Heap; |
| 4 | use Krawfish::Log; |
| Akron | 15f1bc9 | 2017-12-06 13:41:07 +0100 | [diff] [blame] | 5 | use Role::Tiny::With; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 6 | use strict; |
| 7 | use warnings; |
| 8 | |
| Akron | 15f1bc9 | 2017-12-06 13:41:07 +0100 | [diff] [blame] | 9 | with 'Krawfish::Compile'; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 10 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 11 | # This will sort the incoming results using a heap |
| 12 | # and the sort criteria. |
| 13 | # The priority queue will have n entries for n channels. |
| 14 | # When the list is full, the top entry is taken and the |
| 15 | # next entry of the channel of the top entry is enqueued. |
| Akron | 6648597 | 2017-12-07 19:53:14 +0100 | [diff] [blame] | 16 | # |
| 17 | # This may be less efficient than a dynamic |
| 18 | # mergesort, but for the moment, it's way simpler. |
| Akron | c84f00c | 2017-12-03 17:24:21 +0100 | [diff] [blame] | 19 | |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 20 | # TODO: |
| 21 | # Add a timeout! Just in case ...! |
| 22 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 23 | # TODO: |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 24 | # Merge warnings, errors, messages! |
| 25 | |
| 26 | # TODO: |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 27 | # Introduce max_rank_ref! |
| 28 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 29 | # TODO: |
| Akron | 6648597 | 2017-12-07 19:53:14 +0100 | [diff] [blame] | 30 | # This may use a concurrent priorityqueue |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 31 | |
| 32 | # May be renamed to |
| 33 | # - Krawfish::MultiSegment::* |
| 34 | # - Krawfish::MultiNodes::* |
| 35 | |
| 36 | |
| Akron | 405cba0 | 2018-03-02 20:18:30 +0100 | [diff] [blame] | 37 | use constant DEBUG => 0; |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 38 | |
| 39 | |
| 40 | # Constructor |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 41 | sub new { |
| 42 | my $class = shift; |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 43 | |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 44 | # top_k, query, queries |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 45 | my $self = bless { |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 46 | @_ |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 47 | }, $class; |
| 48 | |
| 49 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 50 | # Initialize match position |
| 51 | $self->{pos} = 0; |
| 52 | $self->{match} = undef; |
| 53 | |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 54 | return $self unless $self->{top_k}; |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 55 | |
| 56 | # Add criterion comparation method |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 57 | $self->{prio} = Array::Queue::Priority->new( |
| 58 | sort_cb => sub { |
| 59 | my ($match_a, $match_b) = @_; |
| 60 | |
| 61 | # List of criteria |
| 62 | my $crit_a = $match_a->[0]->sorted_by; |
| 63 | my $crit_b = $match_b->[0]->sorted_by; |
| 64 | |
| 65 | # If the criterion is not defined on any level, |
| 66 | # the entry is below any set entry |
| 67 | return $crit_a->compare($crit_b); |
| 68 | } |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 69 | ); |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 70 | |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 71 | return $self; |
| 72 | }; |
| 73 | |
| Akron | a588d07 | 2017-10-13 14:45:34 +0200 | [diff] [blame] | 74 | |
| Akron | 6648597 | 2017-12-07 19:53:14 +0100 | [diff] [blame] | 75 | # Get maximum frequency |
| 76 | sub max_freq { |
| 77 | my $self = shift; |
| 78 | my $max_freq; |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 79 | foreach (@{$self->{queries}}) { |
| Akron | 6648597 | 2017-12-07 19:53:14 +0100 | [diff] [blame] | 80 | $max_freq += $_->max_freq |
| 81 | }; |
| 82 | return $max_freq; |
| 83 | }; |
| 84 | |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 85 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 86 | # Initially fill up the heap |
| 87 | sub _init { |
| Akron | ef5931b | 2017-09-20 20:46:01 +0200 | [diff] [blame] | 88 | my $self = shift; |
| 89 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 90 | return if $self->{init}++; |
| 91 | |
| 92 | if (DEBUG) { |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 93 | print_log('cmp_node', 'Initialize node response'); |
| Akron | ef5931b | 2017-09-20 20:46:01 +0200 | [diff] [blame] | 94 | }; |
| 95 | |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 96 | # Priority queue if sorting is required, per default with size $n |
| 97 | my $prio = $self->{prio}; |
| 98 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 99 | my $i = 0; |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 100 | my $n = scalar @{$self->{queries}}; |
| Akron | ef5931b | 2017-09-20 20:46:01 +0200 | [diff] [blame] | 101 | |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 102 | # Iterate over all segments - either for grouping |
| 103 | # or (in case of sorting) until the prio is full |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 104 | # |
| 105 | # TODO: |
| 106 | # This needs to be done in parallel, as the initial |
| 107 | # querying (+ sorting) can take quite a lot of time! |
| 108 | for (my $i = 0; $i < $n; $i++) { |
| Akron | 8944098 | 2017-07-28 14:48:28 +0200 | [diff] [blame] | 109 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 110 | # Get query from segment |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 111 | my $seg_q = $self->{queries}->[$i]; |
| Akron | 8944098 | 2017-07-28 14:48:28 +0200 | [diff] [blame] | 112 | |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 113 | # Do grouping! |
| 114 | unless ($prio) { |
| 115 | |
| 116 | if (DEBUG) { |
| 117 | print_log('cmp_node', "Finalize query at channel $i"); |
| 118 | }; |
| 119 | |
| 120 | # Search through all results |
| 121 | $seg_q->finalize; |
| 122 | next; |
| 123 | }; |
| 124 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 125 | # There is a next item from the segment |
| 126 | if ($seg_q->next) { |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 127 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 128 | if (DEBUG) { |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 129 | print_log('cmp_node', "Init query at channel $i"); |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 130 | }; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 131 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 132 | # Enqueue and remember the segment/channel |
| 133 | # TODO: enqueue |
| 134 | $prio->add([$seg_q->current_match, $i]); |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 135 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 136 | if (DEBUG) { |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 137 | print_log('cmp_node', "Added match " . $seg_q->current_match->to_string); |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 138 | }; |
| 139 | } |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 140 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 141 | # No next segment - remove segment from query processing |
| 142 | else { |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 143 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 144 | if (DEBUG) { |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 145 | print_log('cmp_node', "Remove query at channel $i"); |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 146 | }; |
| 147 | |
| 148 | # Remove segment query |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 149 | splice(@{$self->{queries}}, $i, 1); |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 150 | # segment list is shortened |
| 151 | $i--; |
| 152 | $n--; |
| 153 | }; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 154 | }; |
| 155 | |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 156 | return unless $self->{prio}; |
| 157 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 158 | # Resize the priority queue |
| 159 | # $prio->size($n); |
| 160 | |
| 161 | if (DEBUG) { |
| 162 | print_log( |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 163 | 'cmp_node', |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 164 | 'Array: ' . join(',', map { $_->[0]->to_string } @{$prio->queue}) |
| 165 | ); |
| 166 | }; |
| 167 | |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 168 | # $self->{prio} = $prio; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 169 | }; |
| 170 | |
| 171 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 172 | # Get next match |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 173 | sub next { |
| 174 | my $self = shift; |
| 175 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 176 | $self->_init; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 177 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 178 | # There is no next |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 179 | return if !$self->{prio} || $self->{pos} > $self->{top_k} -1; |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 180 | |
| 181 | # Get next match from list |
| 182 | # TODO: dequeue |
| 183 | my $entry = $self->{prio}->remove; |
| 184 | |
| 185 | # No more entries |
| 186 | unless ($entry) { |
| 187 | |
| 188 | # Prevent further requests |
| 189 | $self->{pos} = $self->{top_k} + 1; |
| 190 | $self->{match} = undef; |
| 191 | return; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 192 | }; |
| 193 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 194 | # Set match |
| 195 | $self->{match} = $entry->[0]; |
| 196 | |
| 197 | # Get channel |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 198 | my $channel = $self->{queries}->[$entry->[1]]; |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 199 | |
| 200 | # If the channel has more entries to come, |
| 201 | # add them to the priority queue |
| 202 | if ($channel->next) { |
| 203 | $self->{prio}->add([$channel->current_match, $entry->[1]]); |
| 204 | }; |
| 205 | |
| 206 | if (DEBUG) { |
| 207 | print_log( |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 208 | 'cmp_node', |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 209 | 'Array: ' . join(',', map { $_->[0]->to_string } @{$self->{prio}->queue}) |
| 210 | ); |
| 211 | }; |
| 212 | |
| 213 | $self->{pos}++; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 214 | return 1; |
| 215 | }; |
| 216 | |
| 217 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 218 | # Return current match |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 219 | sub current_match { |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 220 | return $_[0]->{match}; |
| 221 | }; |
| 222 | |
| 223 | |
| 224 | # Get merged result match |
| 225 | # TODO: |
| 226 | # May not be necessary |
| 227 | sub compile { |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 228 | my $self = shift; |
| 229 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 230 | $self->_init; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 231 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 232 | my $result = $self->result; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 233 | |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 234 | print_log('cmp_node','Compile result') if DEBUG; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 235 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 236 | my $k = $self->{top_k}; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 237 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 238 | # Get next match from list |
| 239 | # TODO: dequeue |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 240 | while ($k-- > 0) { |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 241 | my $entry = $self->{prio}->remove; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 242 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 243 | # No more entries |
| 244 | last unless $entry; |
| 245 | |
| 246 | $result->add_match($entry->[0]); |
| 247 | |
| 248 | # Get channel |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 249 | my $channel = $self->{queries}->[$entry->[1]]; |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 250 | |
| 251 | # If the channel has more entries to come, |
| 252 | # add them to the priority queue |
| 253 | if ($channel->next) { |
| 254 | $self->{prio}->add( |
| 255 | [$channel->current_match, $entry->[1]] |
| 256 | ); |
| 257 | }; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 258 | }; |
| 259 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 260 | # Because all queries were sorted on a first pass, |
| 261 | # there is no need to next() to the end for aggregation |
| 262 | |
| 263 | # Merge all aggregation |
| 264 | $self->aggregate; |
| 265 | |
| 266 | return $result; |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 267 | }; |
| 268 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 269 | |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 270 | # Group data |
| 271 | sub group { |
| 272 | my $self = shift; |
| 273 | |
| 274 | $self->_init; |
| 275 | |
| 276 | if (DEBUG) { |
| 277 | print_log('cmp_node', 'Group data'); |
| 278 | }; |
| 279 | |
| 280 | my $result = $self->result; |
| 281 | |
| 282 | if (DEBUG && $result->{group}) { |
| 283 | print_log('cmp_node', 'Group is already done is already done'); |
| 284 | }; |
| 285 | |
| 286 | # Aggregation already collected |
| 287 | return $result if $result->group; |
| 288 | |
| 289 | # Iterate over all queries |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 290 | foreach my $seg_q (@{$self->{queries}}) { |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 291 | |
| 292 | # Check for compilation role |
| 293 | if (Role::Tiny::does_role($seg_q, 'Krawfish::Compile::Segment::Group')) { |
| 294 | if (DEBUG) { |
| 295 | print_log('cmp_node', 'Add result from ' . ref($seg_q)); |
| 296 | }; |
| 297 | |
| 298 | # Merge aggregations |
| 299 | my $group = $seg_q->group; |
| 300 | |
| 301 | if (DEBUG) { |
| 302 | use Data::Dumper; |
| 303 | print_log('cmp_node', 'Merge result: ' . ref($group) . ':' . $group->to_string); |
| 304 | }; |
| 305 | |
| 306 | # Merge group |
| 307 | $result->merge_group($group); |
| 308 | |
| 309 | if (DEBUG) { |
| 310 | print_log('cmp_node', 'Groups merged'); |
| 311 | }; |
| 312 | }; |
| 313 | }; |
| 314 | |
| 315 | return $result; |
| 316 | }; |
| 317 | |
| 318 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 319 | # Get aggregation data only |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 320 | sub aggregate { |
| 321 | my $self = shift; |
| 322 | |
| 323 | $self->_init; |
| 324 | |
| 325 | if (DEBUG) { |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 326 | print_log('cmp_node', 'Aggregate data'); |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 327 | }; |
| 328 | |
| 329 | my $result = $self->result; |
| 330 | |
| 331 | if (DEBUG && @{$result->{aggregation}}) { |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 332 | print_log('cmp_node', 'Aggregation is already done'); |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 333 | }; |
| 334 | |
| 335 | # Aggregation already collected |
| 336 | return $result if @{$result->{aggregation}}; |
| 337 | |
| 338 | # Iterate over all queries |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 339 | foreach my $seg_q (@{$self->{queries}}) { |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 340 | |
| 341 | # Check for compilation role |
| Akron | 15f1bc9 | 2017-12-06 13:41:07 +0100 | [diff] [blame] | 342 | if (Role::Tiny::does_role($seg_q, 'Krawfish::Compile::Segment')) { |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 343 | if (DEBUG) { |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 344 | print_log('cmp_node', 'Add result from ' . ref($seg_q)); |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 345 | }; |
| 346 | |
| 347 | # Merge aggregations |
| 348 | my $aggregate = $seg_q->aggregate; |
| 349 | if (DEBUG) { |
| 350 | use Data::Dumper; |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 351 | print_log('cmp_node', 'Merge result ' . $aggregate->to_string); |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 352 | }; |
| 353 | $result->merge_aggregation($aggregate); |
| 354 | |
| 355 | if (DEBUG) { |
| Akron | cb3a917 | 2017-12-06 17:58:05 +0100 | [diff] [blame] | 356 | print_log('cmp_node', 'Result merged'); |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 357 | }; |
| 358 | }; |
| 359 | }; |
| 360 | |
| 361 | return $result; |
| 362 | }; |
| 363 | |
| 364 | |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 365 | # Prefetch final results |
| 366 | sub prefetch { |
| 367 | # TODO: |
| 368 | # In case there are enrich methods, |
| 369 | # it can be beneficial to enrich the first x matches before |
| 370 | # the cluster resend the request to the nodes and the segments. |
| 371 | # so - the node may send the enrich request to the segments |
| 372 | # after the last successfull current_match with a certain number |
| 373 | # of matches to prefetch. When this is done, the segments |
| 374 | # can go through the top X results and prefetch snippets |
| 375 | # etc. while the node and the cluster is busy merging the result. |
| 376 | ... |
| 377 | }; |
| 378 | |
| 379 | |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 380 | # stringification |
| 381 | sub to_string { |
| 382 | my ($self, $id) = @_; |
| 383 | my $str = 'node('; |
| Akron | 4a6fbed | 2017-12-08 12:54:43 +0100 | [diff] [blame] | 384 | $str .= join(';', map { $_->to_string($id) } @{$self->{queries}}); |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 385 | $str .= ')'; |
| 386 | }; |
| 387 | |
| 388 | |
| Akron | 8323607 | 2017-06-21 15:54:16 +0200 | [diff] [blame] | 389 | 1; |
| Akron | e5166b0 | 2017-12-05 21:21:25 +0100 | [diff] [blame] | 390 | |
| 391 | |
| 392 | __END__ |