MyScoreDoc tmpScoreDoc = new MyScoreDoc(0, 0.0f, 0, null);
MyScoreDoc bottom = null;
boolean queueFull = false;
DocIDPriorityQueue docQueue = new DocIDPriorityQueue(MY_DOC_COMPARATOR, topHits, 0);
for (SenseiResult res : results)
{
SortCollector sortCollector = res.getSortCollector();
if (sortCollector == null)
continue;
int end = (res.getNumHits() % SortCollector.BLOCK_SIZE) - 1;
Iterator<CollectorContext> contextIter = sortCollector.contextList.descendingIterator();
// Populate dataCaches and contextLeft
CollectorContext currentContext = null;
int contextLeft = 0;
FacetDataCache[] dataCaches = new FacetDataCache[sortCollector.groupByMulti.length];
while (contextIter.hasNext()) {
currentContext = contextIter.next();
currentContext.restoreRuntimeFacets();
contextLeft = currentContext.length;
if (contextLeft > 0)
{
for (int j=0; j<sortCollector.groupByMulti.length; ++j)
dataCaches[j] = (FacetDataCache)sortCollector.groupByMulti[j].getFacetData(currentContext.reader);
break;
}
}
Iterator<float[]> scoreArrayIter = sortCollector.scorearraylist != null ? sortCollector.scorearraylist.descendingIterator():null;
if (contextLeft > 0)
{
Iterator<int[]> docArrayIter = sortCollector.docidarraylist.descendingIterator();
while (docArrayIter.hasNext())
{
int[] docs = docArrayIter.next();
float[] scores = scoreArrayIter != null ? scoreArrayIter.next():null;
for (int i = end; i >= 0; --i)
{
tmpScoreDoc.doc = docs[i];
tmpScoreDoc.score = scores != null ? scores[i] : 0.0f;
tmpScoreDoc.finalDoc = currentContext.base + totalDocs + tmpScoreDoc.doc;
tmpScoreDoc.reader = currentContext.reader;
tmpScoreDoc.sortValue = currentContext.comparator.value(tmpScoreDoc);
int j=0;
if (!queueFull || tmpScoreDoc.sortValue.compareTo(bottom.sortValue) < 0)
{
for (;; ++j)
{
rawGroupValue = dataCaches[j].valArray.getRawValue(dataCaches[j].orderArray.get(tmpScoreDoc.doc));
rawGroupValue = extractRawGroupValue(rawGroupValueType, j,
primitiveLongArrayWrapperTmp, rawGroupValue);
pre = valueDocMaps[j].get(rawGroupValue);
if (pre != null)
{
j = -1;
break;
}
if (j >= combinedFacetAccessibles.length) break;
if (rawGroupValueType[j] == LONG_ARRAY_GROUP_VALUE_TYPE)
{
if (combinedFacetAccessibles[j].getCappedFacetCount(primitiveLongArrayWrapperTmp.data, 2) != 1)
break;
}
else
{
if (combinedFacetAccessibles[j].getCappedFacetCount(rawGroupValue, 2) != 1)
break;
}
}
if (j < 0)
{
if (tmpScoreDoc.sortValue.compareTo(pre.sortValue) < 0)
{
tmpScoreDoc.groupPos = pre.groupPos;
tmpScoreDoc.rawGroupValue = pre.rawGroupValue;
// Pre has a higher score. Pop it in the queue!
bottom = (MyScoreDoc)docQueue.replace(tmpScoreDoc, pre);
valueDocMaps[tmpScoreDoc.groupPos].put(tmpScoreDoc.rawGroupValue, tmpScoreDoc);
tmpScoreDoc = pre;
}
}
else
{
if (queueFull)
{
tmpScoreDoc.groupPos = j;
tmpScoreDoc.rawGroupValue = rawGroupValue;
MyScoreDoc tmp = bottom;
valueDocMaps[tmp.groupPos].remove(tmp.rawGroupValue);
bottom = (MyScoreDoc)docQueue.replace(tmpScoreDoc);
valueDocMaps[j].put(rawGroupValue, tmpScoreDoc);
tmpScoreDoc = tmp;
if (rawGroupValueType[tmpScoreDoc.groupPos] == LONG_ARRAY_GROUP_VALUE_TYPE)
{
primitiveLongArrayWrapperTmp = (PrimitiveLongArrayWrapper)tmpScoreDoc.rawGroupValue;
}
else
{
primitiveLongArrayWrapperTmp = new PrimitiveLongArrayWrapper(null);
}
}
else
{
MyScoreDoc tmp = new MyScoreDoc(tmpScoreDoc.doc, tmpScoreDoc.score, currentContext.base + totalDocs + tmpScoreDoc.doc, currentContext.reader);
tmp.groupPos = j;
tmp.rawGroupValue = rawGroupValue;
tmp.sortValue = tmpScoreDoc.sortValue;
bottom = (MyScoreDoc)docQueue.add(tmp);
valueDocMaps[j].put(rawGroupValue, tmp);
queueFull = (docQueue.size >= topHits);
if (rawGroupValueType[j] == LONG_ARRAY_GROUP_VALUE_TYPE)
{
primitiveLongArrayWrapperTmp = new PrimitiveLongArrayWrapper(null);
}
}
}
}
--contextLeft;
if (contextLeft <= 0)
{
while (contextIter.hasNext())
{
currentContext = contextIter.next();
currentContext.restoreRuntimeFacets();
contextLeft = currentContext.length;
if (contextLeft > 0)
{
for (j=0; j<sortCollector.groupByMulti.length; ++j)
dataCaches[j] = (FacetDataCache)sortCollector.groupByMulti[j].getFacetData(currentContext.reader);
break;
}
}
if (contextLeft <= 0) // No more docs left.
break;
}
}
end = SortCollector.BLOCK_SIZE - 1;
}
}
totalDocs += res.getTotalDocs();
}
int len = docQueue.size() - req.getOffset();
if (len < 0) len = 0;
SenseiHit[] hitArray = new SenseiHit[len];
for (int i = hitArray.length-1; i>=0; --i)
{
tmpScoreDoc = (MyScoreDoc)docQueue.pop();
hitArray[i] = tmpScoreDoc.getSenseiHit(req);
}
for (int i=0; i<hitArray.length; ++i)
hitsList.add(hitArray[i]);