Bug 293084: perf improvement in nsMsgSearchNews::DuplicateHit; p=Bruno 'Aqualon' Escherl <aqualon@aquachan.de>, r=me, sr=bienvenu

This commit is contained in:
mnyromyr%tprac.de 2007-11-29 20:58:51 +00:00
Родитель 277f1659af
Коммит cab5d2542d
1 изменённых файлов: 29 добавлений и 21 удалений

Просмотреть файл

@ -349,64 +349,71 @@ void nsMsgSearchNews::PreExitFunction (URL_Struct * /*url*/, int status, MWConte
}
}
#endif // 0
PRBool nsMsgSearchNews::DuplicateHit(PRUint32 artNum)
// ASSUMES m_hits is sorted!!
{
PRUint32 index;
for (index = 0; index < m_hits.GetSize(); index++)
// Assert that m_hits is sorted!
PRUint32 size = m_hits.GetSize();
for (PRUint32 index = 0; index < size; ++index)
if (artNum == m_hits.ElementAt(index))
return PR_TRUE;
return PR_FALSE;
}
void nsMsgSearchNews::CollateHits ()
void nsMsgSearchNews::CollateHits()
{
// Since the XPAT commands are processed one at a time, the result set for the
// entire query is the intersection of results for each XPAT command if an AND Search
// otherwise we want the union of all the search hits (minus the duplicates of course)
// entire query is the intersection of results for each XPAT command if an AND search,
// otherwise we want the union of all the search hits (minus the duplicates of course).
if (m_candidateHits.GetSize() == 0)
PRUint32 size = m_candidateHits.GetSize();
if (!size)
return;
// Sort the article numbers first, so it's easy to tell how many hits
// on a given article we got
m_candidateHits.QuickSort(CompareArticleNumbers);
int size = m_candidateHits.GetSize();
int index = 0;
PRUint32 candidate = m_candidateHits.ElementAt(index);
PRUint32 candidate = m_candidateHits.ElementAt(0);
if (m_ORSearch)
{
for (index = 0; index < size; index++)
// first candidate, so just add it
m_hits.Add(candidate);
for (PRUint32 index = 1; index < size; ++index)
{
candidate = m_candidateHits.ElementAt(index);
if (!DuplicateHit(candidate)) // if not a dup, add it to the hit list
m_hits.Add (candidate);
m_hits.Add(candidate);
}
return;
}
// otherwise we have a traditional and search which must be collated
// otherwise we have a traditional AND search which must be collated
// In order to get promoted into the hits list, a candidate article number
// must appear in the results of each XPAT command. So if we fire 3 XPAT
// commands (one per search term), the article number must appear 3 times.
// If it appears less than 3 times, it matched some search terms, but not all
// If it appears less than 3 times, it matched some search terms, but not all.
PRUint32 termCount;
m_searchTerms->Count(&termCount);
PRUint32 candidateCount = 0;
while (index < size)
for (PRUint32 index = 0; index < size; ++index)
{
if (candidate == m_candidateHits.ElementAt(index))
candidateCount++;
PRUint32 possibleCandidate = m_candidateHits.ElementAt(index);
if (candidate == possibleCandidate)
{
++candidateCount;
}
else
{
candidateCount = 1;
candidate = possibleCandidate;
}
if (candidateCount == termCount)
m_hits.Add (m_candidateHits.ElementAt(index));
candidate = m_candidateHits.ElementAt(index++);
m_hits.Add(candidate);
}
}
@ -424,7 +431,8 @@ void nsMsgSearchNews::ReportHits ()
if (db)
{
for (PRUint32 i = 0; i < m_hits.GetSize(); i++)
PRUint32 size = m_hits.GetSize();
for (PRUint32 i = 0; i < size; ++i)
{
nsCOMPtr <nsIMsgDBHdr> header;