diff options
Diffstat (limited to 'src/3rdparty/clucene/src/CLucene/search/Hits.cpp')
-rw-r--r-- | src/3rdparty/clucene/src/CLucene/search/Hits.cpp | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/src/3rdparty/clucene/src/CLucene/search/Hits.cpp b/src/3rdparty/clucene/src/CLucene/search/Hits.cpp new file mode 100644 index 0000000..38c489f --- /dev/null +++ b/src/3rdparty/clucene/src/CLucene/search/Hits.cpp @@ -0,0 +1,174 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/StdHeader.h" + +#include "SearchHeader.h" +#include "CLucene/document/Document.h" +#include "CLucene/index/IndexReader.h" +#include "Filter.h" +#include "CLucene/search/SearchHeader.h" + +CL_NS_USE(document) +CL_NS_USE(util) +CL_NS_USE(index) + +CL_NS_DEF(search) + + HitDoc::HitDoc(const qreal s, const int32_t i) + { + //Func - Constructor + //Pre - true + //Post - The instance has been created + + next = NULL; + prev = NULL; + doc = NULL; + score = s; + id = i; + } + + HitDoc::~HitDoc(){ + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + + _CLDELETE(doc); + } + + + Hits::Hits(Searcher* s, Query* q, Filter* f, const Sort* _sort): + query(q), searcher(s), filter(f), sort(_sort) + { + //Func - Constructor + //Pre - s contains a valid reference to a searcher s + // q contains a valid reference to a Query + // f is NULL or contains a pointer to a filter + //Post - The instance has been created + + _length = 0; + first = NULL; + last = NULL; + numDocs = 0; + maxDocs = 200; + + //retrieve 100 initially + getMoreDocs(50); + } + + Hits::~Hits(){ + + } + int32_t Hits::length() const { + return _length; + } + + Document& Hits::doc(const int32_t n){ + HitDoc* hitDoc = getHitDoc(n); + + // Update LRU cache of documents + remove(hitDoc); // remove from list, if there + addToFront(hitDoc); // add to front of list + if (numDocs > maxDocs) { // if cache is full + HitDoc* oldLast = last; + remove(last); // flush last + + _CLDELETE( oldLast->doc ); + oldLast->doc = NULL; + } + + if (hitDoc->doc == NULL){ + hitDoc->doc = _CLNEW Document; + searcher->doc(hitDoc->id, hitDoc->doc); // cache miss: read document + } + + return *hitDoc->doc; + } + + int32_t Hits::id (const int32_t n){ + return getHitDoc(n)->id; + } + + qreal Hits::score(const int32_t n){ + return getHitDoc(n)->score; + } + + void Hits::getMoreDocs(const size_t m){ + size_t _min = m; + { + size_t nHits = hitDocs.size(); + if ( nHits > _min) + _min = nHits; + } + + size_t n = _min * 2; // double # retrieved + TopDocs* topDocs = NULL; + if ( sort==NULL ) + topDocs = (TopDocs*)((Searchable*)searcher)->_search(query, filter, n); + else + topDocs = (TopDocs*)((Searchable*)searcher)->_search(query, filter, n, sort); + _length = topDocs->totalHits; + ScoreDoc* scoreDocs = topDocs->scoreDocs; + int32_t scoreDocsLength = topDocs->scoreDocsLength; + + qreal scoreNorm = 1.0f; + //Check that scoreDocs is a valid pointer before using it + if (scoreDocs != NULL){ + if (_length > 0 && scoreDocs[0].score > 1.0f){ + scoreNorm = 1.0f / scoreDocs[0].score; + } + + int32_t end = scoreDocsLength < _length ? scoreDocsLength : _length; + for (int32_t i = hitDocs.size(); i < end; i++) { + hitDocs.push_back(_CLNEW HitDoc(scoreDocs[i].score*scoreNorm, scoreDocs[i].doc)); + } + } + + _CLDELETE(topDocs); + } + + HitDoc* Hits::getHitDoc(const size_t n){ + if (n >= _length){ + TCHAR buf[100]; + _sntprintf(buf, 100,_T("Not a valid hit number: %d"),n); + _CLTHROWT(CL_ERR_IndexOutOfBounds, buf ); + } + if (n >= hitDocs.size()) + getMoreDocs(n); + + return hitDocs[n]; + } + + void Hits::addToFront(HitDoc* hitDoc) { // insert at front of cache + if (first == NULL) + last = hitDoc; + else + first->prev = hitDoc; + + hitDoc->next = first; + first = hitDoc; + hitDoc->prev = NULL; + + numDocs++; + } + + void Hits::remove(const HitDoc* hitDoc) { // remove from cache + if (hitDoc->doc == NULL) // it's not in the list + return; // abort + + if (hitDoc->next == NULL) + last = hitDoc->prev; + else + hitDoc->next->prev = hitDoc->prev; + + if (hitDoc->prev == NULL) + first = hitDoc->next; + else + hitDoc->prev->next = hitDoc->next; + + numDocs--; + } +CL_NS_END |