1 17 package org.alfresco.repo.search.impl.lucene.query; 18 19 import java.io.IOException ; 20 21 import org.apache.lucene.index.TermPositions; 22 import org.apache.lucene.search.Explanation; 23 import org.apache.lucene.search.Scorer; 24 import org.apache.lucene.search.Similarity; 25 import org.apache.lucene.search.Weight; 26 27 37 public class ContainerScorer extends Scorer 38 { 39 Weight weight; 41 42 TermPositions root; 46 47 StructuredFieldPosition[] positions; 49 50 byte[] norms; 52 53 int min = 0; 55 56 int max = 0; 58 59 int rootDoc = 0; 62 63 boolean more = true; 65 66 float freq = 0.0f; 68 69 private TermPositions containers; 71 72 91 public ContainerScorer(Weight weight, TermPositions root, StructuredFieldPosition[] positions, TermPositions containers, Similarity similarity, byte[] norms) 92 { 93 super(similarity); 94 this.weight = weight; 95 this.positions = positions; 96 this.norms = norms; 97 this.root = root; 98 this.containers = containers; 99 } 100 101 106 public boolean next() throws IOException 107 { 108 if (allContainers()) 110 { 111 while (more) 113 { 114 if (containers.next() && root.next()) 115 { 116 if (check(0, root.nextPosition())) 117 { 118 return true; 119 } 120 } 121 else 122 { 123 more = false; 124 return false; 125 } 126 } 127 } 128 129 if (!more) 130 { 131 return false; 133 } 134 135 if (max == 0) 136 { 137 doNextOnAll(); 140 if (found()) 141 { 142 return true; 143 } 144 } 146 147 return findNext(); 148 } 149 150 156 private boolean allContainers() 157 { 158 if (positions.length == 0) 159 { 160 return true; 161 } 162 for (StructuredFieldPosition sfp : positions) 163 { 164 if (sfp.getCachingTermPositions() != null) 165 { 166 return false; 167 } 168 } 169 return true; 170 } 171 172 176 private boolean findNext() throws IOException 177 { 178 180 while (more) 181 { 182 move(); if (found()) 184 { 185 return true; 186 } 187 } 188 189 return false; 191 } 192 193 199 200 private boolean found() throws IOException 201 { 202 if (positions.length == 0) 204 { 205 return true; 206 } 207 208 if (!more) 210 { 211 return false; 212 } 213 214 if (min != max) 216 { 217 return false; 218 } 219 220 if (rootDoc != max) 221 { 222 return false; 223 } 224 225 int count = root.freq(); 230 int start = 0; 231 int end = -1; 232 for (int i = 0; i < count; i++) 233 { 234 if (i == 0) 235 { 236 start = 0; 238 end = root.nextPosition() ; 239 } 240 else 241 { 242 start = end + 1; 243 end = root.nextPosition() ; 244 } 245 246 if (check(start, end)) 247 { 248 return true; 249 } 250 } 251 252 return false; 254 } 255 256 260 261 private boolean check(int start, int end) throws IOException 262 { 263 int offset = checkTail(start, end, 0, 0); 264 if (offset == -1) 266 { 267 return false; 268 } 269 else 270 { 271 if (positions[positions.length - 1].isTerminal()) 273 { 274 return ((offset+1) == end); 275 } 276 else 277 { 278 return true; 279 } 280 } 281 } 282 283 294 private int checkTail(int start, int end, int currentPosition, int currentOffset) throws IOException 295 { 296 int offset = currentOffset; 297 for (int i = currentPosition, l = positions.length; i < l; i++) 298 { 299 offset = positions[i].matches(start, end, offset); 300 if (offset == -1) 301 { 302 return -1; 303 } 304 if (positions[i].isDescendant()) 305 { 306 for (int j = offset; j < end; j++) 307 { 308 int newOffset = checkTail(start, end, i + 1, j); 309 if (newOffset != -1) 310 { 311 return newOffset; 312 } 313 } 314 return -1; 315 } 316 } 317 return offset; 318 } 319 320 323 324 private void move() throws IOException 325 { 326 if (min == max) 327 { 328 doNextOnAll(); 331 } 332 else 333 { 334 skipToMax(); 337 } 338 } 339 340 350 private void doNextOnAll() throws IOException 351 { 352 int current; 354 boolean first = true; 355 for (int i = 0, l = positions.length; i < l; i++) 356 { 357 if (positions[i].getCachingTermPositions() != null) 358 { 359 if (positions[i].getCachingTermPositions().next()) 360 361 { 362 current = positions[i].getCachingTermPositions().doc(); 363 adjustMinMax(current, first); 364 first = false; 365 } 366 else 367 { 368 more = false; 369 return; 370 } 371 } 372 } 373 374 if (root.next()) 377 { 378 rootDoc = root.doc(); 379 } 380 else 381 { 382 more = false; 383 return; 384 } 385 if (root.doc() < max) 386 { 387 if (root.skipTo(max)) 388 { 389 rootDoc = root.doc(); 390 } 391 else 392 { 393 more = false; 394 return; 395 } 396 } 397 } 398 399 407 private void skipToMax() throws IOException 408 { 409 int current; 411 for (int i = 0, l = positions.length; i < l; i++) 412 { 413 if (i == 0) 414 { 415 min = max; 416 } 417 if (positions[i].getCachingTermPositions() != null) 418 { 419 if (positions[i].getCachingTermPositions().doc() < max) 420 { 421 if (positions[i].getCachingTermPositions().skipTo(max)) 422 { 423 current = positions[i].getCachingTermPositions().doc(); 424 adjustMinMax(current, false); 425 } 426 else 427 { 428 more = false; 429 return; 430 } 431 } 432 } 433 } 434 435 if (root.doc() < max) 437 { 438 if (root.skipTo(max)) 439 { 440 rootDoc = root.doc(); 441 } 442 else 443 { 444 more = false; 445 return; 446 } 447 } 448 } 449 450 454 private void adjustMinMax(int doc, boolean setMin) 455 { 456 457 if (max < doc) 458 { 459 max = doc; 460 } 461 462 if (setMin) 463 { 464 min = doc; 465 } 466 else if (min > doc) 467 { 468 min = doc; 469 } 470 } 471 472 477 public int doc() 478 { 479 if (allContainers()) 480 { 481 return containers.doc(); 482 } 483 return max; 484 } 485 486 491 public float score() throws IOException 492 { 493 return 1.0f; 494 } 495 496 501 public boolean skipTo(int target) throws IOException 502 { 503 if (allContainers()) 504 { 505 containers.skipTo(target); 506 root.skipTo(containers.doc()); if (check(0, root.nextPosition())) 508 { 509 return true; 510 } 511 while (more) 512 { 513 if (containers.next() && root.next()) 514 { 515 if (check(0, root.nextPosition())) 516 { 517 return true; 518 } 519 } 520 else 521 { 522 more = false; 523 return false; 524 } 525 } 526 } 527 528 max = target; 529 return findNext(); 530 } 531 532 537 public Explanation explain(int doc) throws IOException 538 { 539 Explanation tfExplanation = new Explanation(); 541 542 while (next() && doc() < doc) 543 { 544 } 545 546 float phraseFreq = (doc() == doc) ? freq : 0.0f; 547 tfExplanation.setValue(getSimilarity().tf(phraseFreq)); 548 tfExplanation.setDescription("tf(phraseFreq=" + phraseFreq + ")"); 549 550 return tfExplanation; 551 } 552 553 } | Popular Tags |