xapian-core  2.0.0
msetcmp.cc
Go to the documentation of this file.
1 
4 /* Copyright (C) 2006,2009,2013,2017 Olly Betts
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see
18  * <https://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 
23 #include "msetcmp.h"
24 
25 #include "api/result.h"
26 #include "omassert.h"
27 
28 /* We use templates to generate all the different comparison functions which we
29  * need, which avoids having to write them all out by hand.
30  */
31 
32 // Order by docid, inlined. Used as the last fallback by the others.
33 template<bool FORWARD_DID>
34 static inline bool
36 {
37  if (FORWARD_DID) {
38  return (a.get_docid() < b.get_docid());
39  } else {
40  return (a.get_docid() > b.get_docid());
41  }
42 }
43 
44 // Order by docid, used when relevance is always 0.
45 template<bool FORWARD_DID>
46 static bool
47 msetcmp_by_docid(const Result& a, const Result& b)
48 {
49  return msetcmp_by_docid_inline<FORWARD_DID>(a, b);
50 }
51 
52 // Order by relevance, then docid.
53 template<bool FORWARD_DID>
54 static bool
55 msetcmp_by_relevance(const Result& a, const Result& b)
56 {
57  if (a.get_weight() > b.get_weight()) return true;
58  if (a.get_weight() < b.get_weight()) return false;
59  return msetcmp_by_docid_inline<FORWARD_DID>(a, b);
60 }
61 
62 // Order by value, then docid.
63 template<bool FORWARD_VALUE, bool FORWARD_DID>
64 static bool
65 msetcmp_by_value(const Result& a, const Result& b)
66 {
67  int sort_cmp = a.get_sort_key().compare(b.get_sort_key());
68  if (sort_cmp > 0) return FORWARD_VALUE;
69  if (sort_cmp < 0) return !FORWARD_VALUE;
70  return msetcmp_by_docid_inline<FORWARD_DID>(a, b);
71 }
72 
73 // Order by value, then relevance, then docid.
74 template<bool FORWARD_VALUE, bool FORWARD_DID>
75 static bool
77 {
78  int sort_cmp = a.get_sort_key().compare(b.get_sort_key());
79  if (sort_cmp > 0) return FORWARD_VALUE;
80  if (sort_cmp < 0) return !FORWARD_VALUE;
81  if (a.get_weight() > b.get_weight()) return true;
82  if (a.get_weight() < b.get_weight()) return false;
83  return msetcmp_by_docid_inline<FORWARD_DID>(a, b);
84 }
85 
86 // Order by relevance, then value, then docid.
87 template<bool FORWARD_VALUE, bool FORWARD_DID>
88 static bool
90 {
91  if (a.get_weight() > b.get_weight()) return true;
92  if (a.get_weight() < b.get_weight()) return false;
93  int sort_cmp = a.get_sort_key().compare(b.get_sort_key());
94  if (sort_cmp > 0) return FORWARD_VALUE;
95  if (sort_cmp < 0) return !FORWARD_VALUE;
96  return msetcmp_by_docid_inline<FORWARD_DID>(a, b);
97 }
98 
99 MSetCmp
101  bool sort_forward,
102  bool sort_val_reverse)
103 {
104  switch (sort_by) {
106  if (sort_forward)
107  return msetcmp_by_docid<true>;
108  else
109  return msetcmp_by_docid<false>;
111  if (sort_forward)
112  return msetcmp_by_relevance<true>;
113  else
114  return msetcmp_by_relevance<false>;
116  if (sort_forward) {
117  if (sort_val_reverse) {
118  return msetcmp_by_value<true, true>;
119  } else {
120  return msetcmp_by_value<false, true>;
121  }
122  } else {
123  if (sort_val_reverse) {
124  return msetcmp_by_value<true, false>;
125  } else {
126  return msetcmp_by_value<false, false>;
127  }
128  }
130  if (sort_forward) {
131  if (sort_val_reverse) {
132  return msetcmp_by_value_then_relevance<true, true>;
133  } else {
134  return msetcmp_by_value_then_relevance<false, true>;
135  }
136  } else {
137  if (sort_val_reverse) {
138  return msetcmp_by_value_then_relevance<true, false>;
139  } else {
140  return msetcmp_by_value_then_relevance<false, false>;
141  }
142  }
143  default:
144  // Must be REL_VAL, but handle with "default" to avoid warnings
145  // about falling off the end of the function.
147  if (sort_forward) {
148  if (sort_val_reverse) {
149  return msetcmp_by_relevance_then_value<true, true>;
150  } else {
151  return msetcmp_by_relevance_then_value<false, true>;
152  }
153  } else {
154  if (sort_val_reverse) {
155  return msetcmp_by_relevance_then_value<true, false>;
156  } else {
157  return msetcmp_by_relevance_then_value<false, false>;
158  }
159  }
160  }
161 }
A result in an MSet.
Definition: result.h:30
const std::string & get_sort_key() const
Definition: result.h:76
double get_weight() const
Definition: result.h:70
Xapian::docid get_docid() const
Definition: result.h:68
static bool msetcmp_by_docid_inline(const Result &a, const Result &b)
Definition: msetcmp.cc:35
MSetCmp get_msetcmp_function(Xapian::Enquire::Internal::sort_setting sort_by, bool sort_forward, bool sort_val_reverse)
Select the appropriate msetcmp function.
Definition: msetcmp.cc:100
static bool msetcmp_by_value(const Result &a, const Result &b)
Definition: msetcmp.cc:65
static bool msetcmp_by_docid(const Result &a, const Result &b)
Definition: msetcmp.cc:47
static bool msetcmp_by_relevance(const Result &a, const Result &b)
Definition: msetcmp.cc:55
static bool msetcmp_by_relevance_then_value(const Result &a, const Result &b)
Definition: msetcmp.cc:89
static bool msetcmp_by_value_then_relevance(const Result &a, const Result &b)
Definition: msetcmp.cc:76
Result comparison functions.
bool(* MSetCmp)(const Result &, const Result &)
Definition: msetcmp.h:29
Various assertion macros.
#define AssertEq(A, B)
Definition: omassert.h:124
A result in an MSet.