2 * @brief MSetItem comparison functions.
4 /* Copyright (C) 2006,2009,2013,2017 Olly Betts
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.
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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
27 /* We use templates to generate the 14 different comparison functions
28 * which we need. This avoids having to write them all out by hand.
31 // Order by did. Helper comparison template function, which is used as the
32 // last fallback by the others.
33 template<bool FORWARD_DID
, bool CHECK_DID_ZERO
>
35 msetcmp_by_did(const Xapian::Internal::MSetItem
&a
,
36 const Xapian::Internal::MSetItem
&b
)
40 // We want dummy did 0 to compare worse than any other.
41 if (a
.did
== 0) return false;
42 if (b
.did
== 0) return true;
44 return (a
.did
< b
.did
);
46 return (a
.did
> b
.did
);
50 // Order by relevance, then docid.
51 template<bool FORWARD_DID
>
53 msetcmp_by_relevance(const Xapian::Internal::MSetItem
&a
,
54 const Xapian::Internal::MSetItem
&b
)
56 if (a
.wt
> b
.wt
) return true;
57 if (a
.wt
< b
.wt
) return false;
58 return msetcmp_by_did
<FORWARD_DID
, true>(a
, b
);
61 // Order by value, then docid.
62 template<bool FORWARD_VALUE
, bool FORWARD_DID
>
64 msetcmp_by_value(const Xapian::Internal::MSetItem
&a
,
65 const Xapian::Internal::MSetItem
&b
)
68 // We want dummy did 0 to compare worse than any other.
69 if (a
.did
== 0) return false;
70 if (b
.did
== 0) return true;
72 int sort_cmp
= a
.sort_key
.compare(b
.sort_key
);
73 if (sort_cmp
> 0) return FORWARD_VALUE
;
74 if (sort_cmp
< 0) return !FORWARD_VALUE
;
75 return msetcmp_by_did
<FORWARD_DID
, FORWARD_VALUE
>(a
, b
);
78 // Order by value, then relevance, then docid.
79 template<bool FORWARD_VALUE
, bool FORWARD_DID
>
81 msetcmp_by_value_then_relevance(const Xapian::Internal::MSetItem
&a
,
82 const Xapian::Internal::MSetItem
&b
)
85 // two special cases to make min_item compares work when did == 0
86 if (a
.did
== 0) return false;
87 if (b
.did
== 0) return true;
89 int sort_cmp
= a
.sort_key
.compare(b
.sort_key
);
90 if (sort_cmp
> 0) return FORWARD_VALUE
;
91 if (sort_cmp
< 0) return !FORWARD_VALUE
;
92 if (a
.wt
> b
.wt
) return true;
93 if (a
.wt
< b
.wt
) return false;
94 return msetcmp_by_did
<FORWARD_DID
, FORWARD_VALUE
>(a
, b
);
97 // Order by relevance, then value, then docid.
98 template<bool FORWARD_VALUE
, bool FORWARD_DID
>
100 msetcmp_by_relevance_then_value(const Xapian::Internal::MSetItem
&a
,
101 const Xapian::Internal::MSetItem
&b
)
103 if (!FORWARD_VALUE
) {
104 // two special cases to make min_item compares work when did == 0
105 if (a
.did
== 0) return false;
106 if (b
.did
== 0) return true;
108 if (a
.wt
> b
.wt
) return true;
109 if (a
.wt
< b
.wt
) return false;
110 int sort_cmp
= a
.sort_key
.compare(b
.sort_key
);
111 if (sort_cmp
> 0) return FORWARD_VALUE
;
112 if (sort_cmp
< 0) return !FORWARD_VALUE
;
113 return msetcmp_by_did
<FORWARD_DID
, FORWARD_VALUE
>(a
, b
);
117 get_msetcmp_function(Xapian::Enquire::Internal::sort_setting sort_by
,
119 bool sort_val_reverse
)
122 case Xapian::Enquire::Internal::REL
:
124 return msetcmp_by_relevance
<true>;
126 return msetcmp_by_relevance
<false>;
127 case Xapian::Enquire::Internal::VAL
:
129 if (sort_val_reverse
) {
130 return msetcmp_by_value
<true, true>;
132 return msetcmp_by_value
<false, true>;
135 if (sort_val_reverse
) {
136 return msetcmp_by_value
<true, false>;
138 return msetcmp_by_value
<false, false>;
141 case Xapian::Enquire::Internal::VAL_REL
:
143 if (sort_val_reverse
) {
144 return msetcmp_by_value_then_relevance
<true, true>;
146 return msetcmp_by_value_then_relevance
<false, true>;
149 if (sort_val_reverse
) {
150 return msetcmp_by_value_then_relevance
<true, false>;
152 return msetcmp_by_value_then_relevance
<false, false>;
156 // Must be REL_VAL, but handle with "default" to avoid warnings
157 // about falling off the end of the function.
158 AssertEq(sort_by
, Xapian::Enquire::Internal::REL_VAL
);
160 if (sort_val_reverse
) {
161 return msetcmp_by_relevance_then_value
<true, true>;
163 return msetcmp_by_relevance_then_value
<false, true>;
166 if (sort_val_reverse
) {
167 return msetcmp_by_relevance_then_value
<true, false>;
169 return msetcmp_by_relevance_then_value
<false, false>;