/*------------------------------------------------------------------------------ * 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) /** Represents sorting by document score (relevancy). */ SortField* SortField::FIELD_SCORE = _CLNEW SortField (NULL, DOCSCORE,false); /** Represents sorting by document number (index order). */ SortField* SortField::FIELD_DOC = _CLNEW SortField (NULL, DOC,false); /** Represents sorting by computed relevance. Using this sort criteria * returns the same results as calling {@link Searcher#search(Query) Searcher#search()} * without a sort criteria, only with slightly more overhead. */ Sort* Sort::RELEVANCE = _CLNEW Sort(); /** Represents sorting by index order. */ Sort* Sort::INDEXORDER = _CLNEW Sort (SortField::FIELD_DOC); /** Creates a sort by terms in the given field where the type of term value * is determined dynamically ({@link #AUTO AUTO}). * @param field Name of field to sort by, cannot be null. */ SortField::SortField (const TCHAR* field) { this->type = AUTO; this->reverse = false; this->field = CLStringIntern::intern(field CL_FILELINE); this->factory = NULL; } /** Creates a sort, possibly in reverse, by terms in the given field where * the type of term value is determined dynamically ({@link #AUTO AUTO}). * @param field Name of field to sort by, cannot be null. * @param reverse True if natural order should be reversed. SortField::SortField (const TCHAR* field, bool reverse) { this->field = CLStringIntern::intern(field CL_FILELINE); this->reverse = reverse; this->type = AUTO; this->factory = NULL; }*/ /** Creates a sort, possibly in reverse, by terms in the given field with the * type of term values explicitly given. * @param field Name of field to sort by. Can be null if * type is SCORE or DOC. * @param type Type of values in the terms. * @param reverse True if natural order should be reversed (default=false). */ 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; }*/ /** Creates a sort, possibly in reverse, with a custom comparison function. * @param field Name of field to sort by; cannot be null. * @param comparator Returns a comparator for sorting hits. * @param reverse True if natural order should be reversed (default=false). */ 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); } const 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(); } /** Sorts by computed relevance. This is the same sort criteria as * calling {@link Searcher#search(Query) Searcher#search()} without a sort criteria, only with * slightly more overhead. */ 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); } } /** Sorts possibly in reverse by the terms in field then by * index order (document number). The type of value in field is determined * automatically. * @see SortField#AUTO */ Sort::Sort (const TCHAR* field, bool reverse) { this->fields=NULL; setSort (field, reverse); } /** Sorts in succession by the terms in each field. * The type of value in field is determined * automatically. * @see SortField#AUTO */ Sort::Sort (const TCHAR** fields) { this->fields=NULL; setSort (fields); } /** Sorts by the criteria in the given SortField. */ Sort::Sort (SortField* field) { this->fields=NULL; setSort (field); } /** Sorts in succession by the criteria in each SortField. */ Sort::Sort (SortField** fields) { this->fields=NULL; setSort (fields); } /** Sets the sort to the terms in field possibly in reverse, * then by index order (document number). */ 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; } /** Sets the sort to the terms in each field in succession. */ 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; } /** Sets the sort to the given criteria. */ void Sort::setSort (SortField* field) { clear(); this->fields = _CL_NEWARRAY(SortField*,2); this->fields[0] = field; this->fields[1] = NULL; } /** Sets the sort to the given criteria in succession. */ 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]; } const 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(){ } // inherit javadocs /*ScoreDocComparator* SortComparator::newComparator (CL_NS(index)::IndexReader* reader, TCHAR* fieldname){ TCHAR* field = CLStringIntern::intern(fieldname); Comparable** cachedValues = FieldCache::DEFAULT().getCustom (reader, field, _this); return _CLNEW ScoreDocComparator(cachedValues); }*/ SortComparator::SortComparator(ScoreDocComparator* _this):SortComparatorSource(){ this->_this = _this; } SortComparator::~SortComparator(){ } CL_NS_END