public QueryResults processQuery(Query query) { rheap.reset(); QueryEntry[] qEntries = query.getEntries(); int numTerms = qEntries.length; if (numTerms == 0) return new QueryResults(null, null, 0, 0); boolean lp = doLP && numTerms > 2 && numTerms <= LPSolver.MAX_QUERY_TERM_COUNT; DefaultPostingListIterator iterators[] = new DefaultPostingListIterator[numTerms]; double[] maxScores = new double[numTerms]; double[] accScores = new double[numTerms]; int[] ids = new int[numTerms]; // double maxKeyFreq = query.getMaxKeyFrequency(); double numOfDocs = stats.getNumberOfDocuments(); double avgDocLength = stats.getAverageDocumentLength(); double _accScore = 0.0d, _kf; // System.out.println("==="); QueryEntry _qE; LexiconEntry _lE; for (int i = 0; i < numTerms; i++) { _qE = qEntries[i]; _lE = _qE.getLexiconEntry(); iterators[i] = (DefaultPostingListIterator) index.getPostingListIterator(_lE); _kf = 1.0; // _qE.getKeyFrequency()/maxKeyFreq; maxScores[i] = FastMaxScore.getMaxScore(_lE.getTermId(), _kf); ids[i] = _lE.getTermId(); // System.out.println(_lE.getN_t()+" "+maxScores[i]); iterators[i].prepareForScoring(_kf, _lE.getN_t(), _lE.getTF(), numOfDocs, avgDocLength); } /*NOTE: in LP case, we calculate scores only for (numTerms-1) last terms. Since the first one is never used anyway. */ double[] lpHelperTable = null; int _ids[] = null; _ids = Arrays.copyOf(ids, ids.length); accScoreTime = System.nanoTime(); if (lp) { lpHelperTable = AccScorePredictor.getAccScoresORTable(ids, maxScores); for (int i = 0; i < numTerms; i++) accScores[i] = lpHelperTable[AccScorePredictor.getAccScoresORIndex(ids, _ids, i, numTerms)]; // for (double ms : maxScores) _accScore += ms; // if (accScores[0] > _accScore){ // for (QueryEntry qE : qEntries) System.out.print(qE.getLexiconEntry().getTerm()+" "); // System.out.println(":" + accScores[0]+" "+_accScore); // } } else { for (int i = numTerms - 1; i >= 0; i--) { _accScore += maxScores[i]; accScores[i] = _accScore; } } procLoopTime = System.nanoTime(); accScoreTime = procLoopTime - accScoreTime; int numberOfResults = 0, numReqTerms = numTerms, lastdoc, canddoc = -1, i; double score, reqScore = 0.0d, _decscore; oloop: while (numReqTerms > 0) { // find the least pointer among OR-terms lastdoc = canddoc; canddoc = Integer.MAX_VALUE; for (i = 0; i < numReqTerms; i++) { if (iterators[i].getDocId() == lastdoc && !iterators[i].next()) { // close iterator, update scores above, move those from below up iterators[i].close(); numTerms--; // move those on the right side for (int j = i; j < numTerms; j++) { iterators[j] = iterators[j + 1]; maxScores[j] = maxScores[j + 1]; accScores[j] = accScores[j + 1]; _ids[j] = _ids[j + 1]; } // update those on the left side if (lp) { for (int j = 0; j < i; j++) accScores[j] = lpHelperTable[AccScorePredictor.getAccScoresORIndex(ids, _ids, j, numTerms)]; } else { _decscore = maxScores[i]; for (int j = 0; j < i; j++) accScores[j] -= _decscore; } i--; // if no OrTerms right now - suspend processing! numReqTerms--; while (numReqTerms > 0 && accScores[numReqTerms - 1] < reqScore) numReqTerms--; if (numReqTerms <= 0) break oloop; } else if (canddoc > iterators[i].getDocId()) { canddoc = iterators[i].getDocId(); } } // accumulate corresponding postings. Be ready to prune half-evaluated score = 0.0d; for (i = 0; i < numTerms && score + accScores[i] >= reqScore; i++) { if (i >= numReqTerms && !iterators[i].skipTo(canddoc)) { // AND terms iterators[i].close(); numTerms--; // move those on the right side for (int j = i; j < numTerms; j++) { maxScores[j] = maxScores[j + 1]; accScores[j] = accScores[j + 1]; _ids[j] = _ids[j + 1]; iterators[j] = iterators[j + 1]; } // update those on the left side if (lp) { for (int j = 0; j < i; j++) accScores[j] = lpHelperTable[AccScorePredictor.getAccScoresORIndex(ids, _ids, j, numTerms)]; } else { _decscore = maxScores[i]; for (int j = 0; j < i; j++) { accScores[j] -= _decscore; _ids[j] = _ids[j + 1]; } } i--; } else if (iterators[i].getDocId() == canddoc) { score += iterators[i].getScore(); } } if (score < reqScore) continue; if (rheap.insertIfGreaterThanLeast(canddoc, score)) { // SimpleMultiStats.addDescription(3, 1); reqScore = rheap.minScore(); while (numReqTerms > 0 && accScores[numReqTerms - 1] < reqScore) numReqTerms--; } numberOfResults++; } for (i = 0; i < numTerms; i++) iterators[i].close(); numberOfResults = rheap.size(); int resdocids[] = new int[numberOfResults]; double resscores[] = new double[numberOfResults]; rheap.decrSortResults(resdocids, resscores); procLoopTime = System.nanoTime() - procLoopTime; numQueries++; // System.out.println(accScoreTime + " " + procLoopTime + " " + numQueries); return new QueryResults(resdocids, resscores, numberOfResults, numberOfResults); }