/*------------------------------------------------------------------------------ * 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 "Sort.h" #include "Compare.h" CL_NS_USE(util) CL_NS_DEF(search) SortField* SortField::FIELD_SCORE = _CLNEW SortField (NULL, DOCSCORE,false); SortField* SortField::FIELD_DOC = _CLNEW SortField (NULL, DOC,false); Sort* Sort::RELEVANCE = _CLNEW Sort(); Sort* Sort::INDEXORDER = _CLNEW Sort (SortField::FIELD_DOC); SortField::SortField (const TCHAR* field) { this->type = AUTO; this->reverse = false; this->field = CLStringIntern::intern(field CL_FILELINE); this->factory = NULL; } SortField::SortField (const TCHAR* field, int32_t type, bool reverse) { this->field = (field != NULL) ? CLStringIntern::intern(field CL_FILELINE) : field; this->type = type; this->reverse = reverse; this->factory = NULL; } SortField::SortField(const SortField& clone){ this->field = (clone.field != NULL) ? CLStringIntern::intern(clone.field CL_FILELINE) : clone.field; this->type = clone.type; this->reverse = clone.reverse; this->factory = clone.factory; } SortField* SortField::clone() const{ return _CLNEW SortField(*this); } /** Creates a sort by terms in the given field sorted * according to the given locale. * @param field Name of field to sort by, cannot be null. * @param locale Locale of values in the field. */ /*SortField::SortField (TCHAR* field, Locale* locale) { this->field = (field != NULL) ? CLStringIntern::intern(field): field; this->type = STRING; this->locale = locale; }*/ /** Creates a sort, possibly in reverse, by terms in the given field sorted * according to the given locale. * @param field Name of field to sort by, cannot be null. * @param locale Locale of values in the field. */ /*SortField::SortField (TCHAR* field, Locale* locale, bool reverse) { this->field = (field != NULL) ? CLStringIntern::intern(field): field; this->type = STRING; this->locale = locale; this->reverse = reverse; }*/ SortField::SortField (const TCHAR* field, SortComparatorSource* comparator, bool reverse) { this->field = (field != NULL) ? CLStringIntern::intern(field CL_FILELINE): field; this->type = CUSTOM; this->reverse = reverse; this->factory = comparator; } SortField::~SortField(){ CLStringIntern::unintern(field); } TCHAR* SortField::toString() const { CL_NS(util)::StringBuffer buffer; switch (type) { case DOCSCORE: buffer.append(_T("")); break; case DOC: buffer.append(_T("")); break; case CUSTOM: buffer.append (_T("getName()); buffer.append(_T(">")); break; default: buffer.append( _T("\"")); buffer.append( field ); buffer.append( _T("\"") ); break; } //if (locale != null) buffer.append ("("+locale+")"); todo: if (reverse) buffer.appendChar('!'); return buffer.toString(); } Sort::Sort() { fields=NULL; SortField** fields=_CL_NEWARRAY(SortField*,3); fields[0]=SortField::FIELD_SCORE; fields[1]=SortField::FIELD_DOC; fields[2]=NULL; setSort (fields); _CLDELETE_ARRAY(fields); } Sort::~Sort(){ clear(); } void Sort::clear(){ if ( fields != NULL ){ int32_t i=0; while ( fields[i] != NULL ){ if ( fields[i] != SortField::FIELD_SCORE && fields[i] != SortField::FIELD_DOC ){ _CLDELETE(fields[i]); } i++; } _CLDELETE_ARRAY(fields); } } Sort::Sort (const TCHAR* field, bool reverse) { this->fields=NULL; setSort (field, reverse); } Sort::Sort (const TCHAR** fields) { this->fields=NULL; setSort (fields); } Sort::Sort (SortField* field) { this->fields=NULL; setSort (field); } Sort::Sort (SortField** fields) { this->fields=NULL; setSort (fields); } void Sort::setSort (const TCHAR* field, bool reverse) { clear(); fields = _CL_NEWARRAY(SortField*,3); fields[0] = _CLNEW SortField (field, SortField::AUTO, reverse); fields[1] = SortField::FIELD_DOC; fields[2] = NULL; } void Sort::setSort (const TCHAR** fieldnames) { clear(); int32_t n = 0; while ( fieldnames[n] != NULL ) n++; fields = _CL_NEWARRAY(SortField*,n+1); for (int32_t i = 0; i < n; ++i) { fields[i] = _CLNEW SortField (fieldnames[i], SortField::AUTO,false); } fields[n]=NULL; } void Sort::setSort (SortField* field) { clear(); this->fields = _CL_NEWARRAY(SortField*,2); this->fields[0] = field; this->fields[1] = NULL; } void Sort::setSort (SortField** fields) { clear(); int n=0; while ( fields[n] != NULL ) n++; this->fields = _CL_NEWARRAY(SortField*,n+1); for (int i=0;ifields[i]=fields[i]; } TCHAR* Sort::toString() const { CL_NS(util)::StringBuffer buffer; int32_t i = 0; while ( fields[i] != NULL ){ if (i>0) buffer.appendChar(','); const TCHAR* p = fields[i]->toString(); buffer.append(p); _CLDELETE_CARRAY(p); i++; } return buffer.toString(); } ScoreDocComparator* ScoreDocComparator::INDEXORDER = _CLNEW ScoreDocComparators::IndexOrder; ScoreDocComparator* ScoreDocComparator::RELEVANCE = _CLNEW ScoreDocComparators::Relevance; ScoreDocComparator::~ScoreDocComparator(){ } class ScoreDocComparatorImpl: public ScoreDocComparator{ Comparable** cachedValues; FieldCacheAuto* fca; int32_t cachedValuesLen; public: ScoreDocComparatorImpl(FieldCacheAuto* fca){ this->fca = fca; if ( fca->contentType != FieldCacheAuto::COMPARABLE_ARRAY ) _CLTHROWA(CL_ERR_InvalidCast,"Invalid field cache auto type"); this->cachedValues = fca->comparableArray; this->cachedValuesLen = fca->contentLen; } ~ScoreDocComparatorImpl(){ } int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j){ CND_PRECONDITION(i->doc >= 0 && i->doc < cachedValuesLen, "i->doc out of range") CND_PRECONDITION(j->doc >= 0 && j->doc < cachedValuesLen, "j->doc out of range") return cachedValues[i->doc]->compareTo (cachedValues[j->doc]); } CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i){ CND_PRECONDITION(i->doc >= 0 && i->doc < cachedValuesLen, "i->doc out of range") return cachedValues[i->doc]; } int32_t sortType(){ return SortField::CUSTOM; } }; ScoreDocComparator* SortComparator::newComparator (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname){ return _CLNEW ScoreDocComparatorImpl(FieldCache::DEFAULT->getCustom (reader, fieldname, this)); } SortComparator::SortComparator(){ } SortComparator::~SortComparator(){ } CL_NS_END