PageRenderTime 28ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/3rdparty/clucene/src/CLucene/search/Sort.cpp

https://bitbucket.org/kasimling/qt
C++ | 345 lines | 186 code | 78 blank | 81 comment | 26 complexity | 8b69482f59dc16d375092b3ce0c44042 MD5 | raw file
  1. /*------------------------------------------------------------------------------
  2. * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
  3. *
  4. * Distributable under the terms of either the Apache License (Version 2.0) or
  5. * the GNU Lesser General Public License, as specified in the COPYING file.
  6. ------------------------------------------------------------------------------*/
  7. #include "CLucene/StdHeader.h"
  8. #include "Sort.h"
  9. #include "Compare.h"
  10. CL_NS_USE(util)
  11. CL_NS_DEF(search)
  12. /** Represents sorting by document score (relevancy). */
  13. SortField* SortField::FIELD_SCORE = _CLNEW SortField (NULL, DOCSCORE,false);
  14. /** Represents sorting by document number (index order). */
  15. SortField* SortField::FIELD_DOC = _CLNEW SortField (NULL, DOC,false);
  16. /** Represents sorting by computed relevance. Using this sort criteria
  17. * returns the same results as calling {@link Searcher#search(Query) Searcher#search()}
  18. * without a sort criteria, only with slightly more overhead. */
  19. Sort* Sort::RELEVANCE = _CLNEW Sort();
  20. /** Represents sorting by index order. */
  21. Sort* Sort::INDEXORDER = _CLNEW Sort (SortField::FIELD_DOC);
  22. /** Creates a sort by terms in the given field where the type of term value
  23. * is determined dynamically ({@link #AUTO AUTO}).
  24. * @param field Name of field to sort by, cannot be <code>null</code>.
  25. */
  26. SortField::SortField (const TCHAR* field) {
  27. this->type = AUTO;
  28. this->reverse = false;
  29. this->field = CLStringIntern::intern(field CL_FILELINE);
  30. this->factory = NULL;
  31. }
  32. /** Creates a sort, possibly in reverse, by terms in the given field where
  33. * the type of term value is determined dynamically ({@link #AUTO AUTO}).
  34. * @param field Name of field to sort by, cannot be <code>null</code>.
  35. * @param reverse True if natural order should be reversed.
  36. SortField::SortField (const TCHAR* field, bool reverse) {
  37. this->field = CLStringIntern::intern(field CL_FILELINE);
  38. this->reverse = reverse;
  39. this->type = AUTO;
  40. this->factory = NULL;
  41. }*/
  42. /** Creates a sort, possibly in reverse, by terms in the given field with the
  43. * type of term values explicitly given.
  44. * @param field Name of field to sort by. Can be <code>null</code> if
  45. * <code>type</code> is SCORE or DOC.
  46. * @param type Type of values in the terms.
  47. * @param reverse True if natural order should be reversed (default=false).
  48. */
  49. SortField::SortField (const TCHAR* field, int32_t type, bool reverse) {
  50. this->field = (field != NULL) ? CLStringIntern::intern(field CL_FILELINE) : field;
  51. this->type = type;
  52. this->reverse = reverse;
  53. this->factory = NULL;
  54. }
  55. SortField::SortField(const SortField& clone){
  56. this->field = (clone.field != NULL) ? CLStringIntern::intern(clone.field CL_FILELINE) : clone.field;
  57. this->type = clone.type;
  58. this->reverse = clone.reverse;
  59. this->factory = clone.factory;
  60. }
  61. SortField* SortField::clone() const{
  62. return _CLNEW SortField(*this);
  63. }
  64. /** Creates a sort by terms in the given field sorted
  65. * according to the given locale.
  66. * @param field Name of field to sort by, cannot be <code>null</code>.
  67. * @param locale Locale of values in the field.
  68. */
  69. /*SortField::SortField (TCHAR* field, Locale* locale) {
  70. this->field = (field != NULL) ? CLStringIntern::intern(field): field;
  71. this->type = STRING;
  72. this->locale = locale;
  73. }*/
  74. /** Creates a sort, possibly in reverse, by terms in the given field sorted
  75. * according to the given locale.
  76. * @param field Name of field to sort by, cannot be <code>null</code>.
  77. * @param locale Locale of values in the field.
  78. */
  79. /*SortField::SortField (TCHAR* field, Locale* locale, bool reverse) {
  80. this->field = (field != NULL) ? CLStringIntern::intern(field): field;
  81. this->type = STRING;
  82. this->locale = locale;
  83. this->reverse = reverse;
  84. }*/
  85. /** Creates a sort, possibly in reverse, with a custom comparison function.
  86. * @param field Name of field to sort by; cannot be <code>null</code>.
  87. * @param comparator Returns a comparator for sorting hits.
  88. * @param reverse True if natural order should be reversed (default=false).
  89. */
  90. SortField::SortField (const TCHAR* field, SortComparatorSource* comparator, bool reverse) {
  91. this->field = (field != NULL) ? CLStringIntern::intern(field CL_FILELINE): field;
  92. this->type = CUSTOM;
  93. this->reverse = reverse;
  94. this->factory = comparator;
  95. }
  96. SortField::~SortField(){
  97. CLStringIntern::unintern(field);
  98. }
  99. TCHAR* SortField::toString() const {
  100. CL_NS(util)::StringBuffer buffer;
  101. switch (type) {
  102. case DOCSCORE: buffer.append(_T("<score>"));
  103. break;
  104. case DOC: buffer.append(_T("<doc>"));
  105. break;
  106. case CUSTOM: buffer.append (_T("<custom:\""));
  107. buffer.append( field );
  108. buffer.append( _T("\": "));
  109. buffer.append(factory->getName());
  110. buffer.append(_T(">"));
  111. break;
  112. default: buffer.append( _T("\""));
  113. buffer.append( field );
  114. buffer.append( _T("\"") );
  115. break;
  116. }
  117. //if (locale != null) buffer.append ("("+locale+")"); todo:
  118. if (reverse) buffer.appendChar('!');
  119. return buffer.toString();
  120. }
  121. /** Sorts by computed relevance. This is the same sort criteria as
  122. * calling {@link Searcher#search(Query) Searcher#search()} without a sort criteria, only with
  123. * slightly more overhead. */
  124. Sort::Sort() {
  125. fields=NULL;
  126. SortField** fields=_CL_NEWARRAY(SortField*,3);
  127. fields[0]=SortField::FIELD_SCORE;
  128. fields[1]=SortField::FIELD_DOC;
  129. fields[2]=NULL;
  130. setSort (fields);
  131. _CLDELETE_ARRAY(fields);
  132. }
  133. Sort::~Sort(){
  134. clear();
  135. }
  136. void Sort::clear(){
  137. if ( fields != NULL ){
  138. int32_t i=0;
  139. while ( fields[i] != NULL ){
  140. if ( fields[i] != SortField::FIELD_SCORE &&
  141. fields[i] != SortField::FIELD_DOC ){
  142. _CLDELETE(fields[i]);
  143. }
  144. i++;
  145. }
  146. _CLDELETE_ARRAY(fields);
  147. }
  148. }
  149. /** Sorts possibly in reverse by the terms in <code>field</code> then by
  150. * index order (document number). The type of value in <code>field</code> is determined
  151. * automatically.
  152. * @see SortField#AUTO
  153. */
  154. Sort::Sort (const TCHAR* field, bool reverse) {
  155. this->fields=NULL;
  156. setSort (field, reverse);
  157. }
  158. /** Sorts in succession by the terms in each field.
  159. * The type of value in <code>field</code> is determined
  160. * automatically.
  161. * @see SortField#AUTO
  162. */
  163. Sort::Sort (const TCHAR** fields) {
  164. this->fields=NULL;
  165. setSort (fields);
  166. }
  167. /** Sorts by the criteria in the given SortField. */
  168. Sort::Sort (SortField* field) {
  169. this->fields=NULL;
  170. setSort (field);
  171. }
  172. /** Sorts in succession by the criteria in each SortField. */
  173. Sort::Sort (SortField** fields) {
  174. this->fields=NULL;
  175. setSort (fields);
  176. }
  177. /** Sets the sort to the terms in <code>field</code> possibly in reverse,
  178. * then by index order (document number). */
  179. void Sort::setSort (const TCHAR* field, bool reverse) {
  180. clear();
  181. fields = _CL_NEWARRAY(SortField*,3);
  182. fields[0] = _CLNEW SortField (field, SortField::AUTO, reverse);
  183. fields[1] = SortField::FIELD_DOC;
  184. fields[2] = NULL;
  185. }
  186. /** Sets the sort to the terms in each field in succession. */
  187. void Sort::setSort (const TCHAR** fieldnames) {
  188. clear();
  189. int32_t n = 0;
  190. while ( fieldnames[n] != NULL )
  191. n++;
  192. fields = _CL_NEWARRAY(SortField*,n+1);
  193. for (int32_t i = 0; i < n; ++i) {
  194. fields[i] = _CLNEW SortField (fieldnames[i], SortField::AUTO,false);
  195. }
  196. fields[n]=NULL;
  197. }
  198. /** Sets the sort to the given criteria. */
  199. void Sort::setSort (SortField* field) {
  200. clear();
  201. this->fields = _CL_NEWARRAY(SortField*,2);
  202. this->fields[0] = field;
  203. this->fields[1] = NULL;
  204. }
  205. /** Sets the sort to the given criteria in succession. */
  206. void Sort::setSort (SortField** fields) {
  207. clear();
  208. int n=0;
  209. while ( fields[n] != NULL )
  210. n++;
  211. this->fields = _CL_NEWARRAY(SortField*,n+1);
  212. for (int i=0;i<n+1;i++)
  213. this->fields[i]=fields[i];
  214. }
  215. TCHAR* Sort::toString() const {
  216. CL_NS(util)::StringBuffer buffer;
  217. int32_t i = 0;
  218. while ( fields[i] != NULL ){
  219. if (i>0)
  220. buffer.appendChar(',');
  221. const TCHAR* p = fields[i]->toString();
  222. buffer.append(p);
  223. _CLDELETE_CARRAY(p);
  224. i++;
  225. }
  226. return buffer.toString();
  227. }
  228. ScoreDocComparator* ScoreDocComparator::INDEXORDER = _CLNEW ScoreDocComparators::IndexOrder;
  229. ScoreDocComparator* ScoreDocComparator::RELEVANCE = _CLNEW ScoreDocComparators::Relevance;
  230. ScoreDocComparator::~ScoreDocComparator(){
  231. }
  232. class ScoreDocComparatorImpl: public ScoreDocComparator{
  233. Comparable** cachedValues;
  234. FieldCacheAuto* fca;
  235. int32_t cachedValuesLen;
  236. public:
  237. ScoreDocComparatorImpl(FieldCacheAuto* fca){
  238. this->fca = fca;
  239. if ( fca->contentType != FieldCacheAuto::COMPARABLE_ARRAY )
  240. _CLTHROWA(CL_ERR_InvalidCast,"Invalid field cache auto type");
  241. this->cachedValues = fca->comparableArray;
  242. this->cachedValuesLen = fca->contentLen;
  243. }
  244. ~ScoreDocComparatorImpl(){
  245. }
  246. int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j){
  247. CND_PRECONDITION(i->doc >= 0 && i->doc < cachedValuesLen, "i->doc out of range")
  248. CND_PRECONDITION(j->doc >= 0 && j->doc < cachedValuesLen, "j->doc out of range")
  249. return cachedValues[i->doc]->compareTo (cachedValues[j->doc]);
  250. }
  251. CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i){
  252. CND_PRECONDITION(i->doc >= 0 && i->doc < cachedValuesLen, "i->doc out of range")
  253. return cachedValues[i->doc];
  254. }
  255. int32_t sortType(){
  256. return SortField::CUSTOM;
  257. }
  258. };
  259. ScoreDocComparator* SortComparator::newComparator (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname){
  260. return _CLNEW ScoreDocComparatorImpl(FieldCache::DEFAULT->getCustom (reader, fieldname, this));
  261. }
  262. SortComparator::SortComparator(){
  263. }
  264. SortComparator::~SortComparator(){
  265. }
  266. CL_NS_END