Make TradWeight a simple subclass and deprecate
[xapian.git] / xapian-core / matcher / maxpostlist.cc
blobb6a01e007ec86ec21cf8a3b11f73ed1ef2ac6d34
1 /** @file
2 * @brief N-way OR postlist with wt=max(wt_i)
3 */
4 /* Copyright (C) 2007,2009,2010,2011,2012,2013,2014,2017 Olly Betts
5 * Copyright (C) 2009 Lemur Consulting Ltd
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <config.h>
24 #include "maxpostlist.h"
26 #include "debuglog.h"
27 #include "omassert.h"
29 using namespace std;
31 MaxPostList::~MaxPostList()
33 if (plist) {
34 for (size_t i = 0; i < n_kids; ++i) {
35 delete plist[i];
37 delete [] plist;
41 Xapian::docid
42 MaxPostList::get_docid() const
44 return did;
47 double
48 MaxPostList::get_weight(Xapian::termcount doclen,
49 Xapian::termcount unique_terms,
50 Xapian::termcount wdfdocmax) const
52 Assert(did);
53 double res = 0.0;
54 for (size_t i = 0; i < n_kids; ++i) {
55 if (plist[i]->get_docid() == did)
56 res = max(res, plist[i]->get_weight(doclen,
57 unique_terms,
58 wdfdocmax));
60 return res;
63 bool
64 MaxPostList::at_end() const
66 return (did == 0);
69 double
70 MaxPostList::recalc_maxweight()
72 double result = plist[0]->recalc_maxweight();
73 for (size_t i = 1; i < n_kids; ++i) {
74 result = max(result, plist[i]->recalc_maxweight());
76 return result;
79 PostList *
80 MaxPostList::next(double w_min)
82 Xapian::docid old_did = did;
83 did = 0;
84 for (size_t i = 0; i < n_kids; UNSIGNED_OVERFLOW_OK(++i)) {
85 Xapian::docid cur_did = 0;
86 if (old_did != 0)
87 cur_did = plist[i]->get_docid();
88 if (cur_did <= old_did) {
89 PostList * res;
90 if (old_did == 0 || cur_did == old_did) {
91 res = plist[i]->next(w_min);
92 } else {
93 res = plist[i]->skip_to(old_did + 1, w_min);
95 if (res) {
96 delete plist[i];
97 plist[i] = res;
100 if (plist[i]->at_end()) {
101 // erase_sublist(i) shuffles down i+1, etc down one index, so
102 // the next sublist to deal with is also at index i, unless
103 // this was the last index. We deal with this by decrementing
104 // i here and it'll be incremented by the loop, but this may
105 // underflow (which is OK because i is an unsigned type).
106 erase_sublist(UNSIGNED_OVERFLOW_OK(i--));
107 continue;
110 if (res)
111 matcher->force_recalc();
113 cur_did = plist[i]->get_docid();
116 if (did == 0 || cur_did < did) {
117 did = cur_did;
121 if (n_kids == 1) {
122 n_kids = 0;
123 return plist[0];
126 return NULL;
129 PostList *
130 MaxPostList::skip_to(Xapian::docid did_min, double w_min)
132 Xapian::docid old_did = did;
133 did = 0;
134 for (size_t i = 0; i < n_kids; ++i) {
135 Xapian::docid cur_did = 0;
136 if (old_did != 0)
137 cur_did = plist[i]->get_docid();
138 if (cur_did < did_min) {
139 PostList * res = plist[i]->skip_to(did_min, w_min);
140 if (res) {
141 delete plist[i];
142 plist[i] = res;
145 if (plist[i]->at_end()) {
146 erase_sublist(i--);
147 continue;
150 if (res)
151 matcher->force_recalc();
153 cur_did = plist[i]->get_docid();
156 if (did == 0 || cur_did < did) {
157 did = cur_did;
161 if (n_kids == 1) {
162 n_kids = 0;
163 return plist[0];
166 return NULL;
169 void
170 MaxPostList::get_docid_range(Xapian::docid& first, Xapian::docid& last) const
172 plist[0]->get_docid_range(first, last);
173 for (size_t i = 1; i != n_kids; ++i) {
174 Xapian::docid f = 1, l = Xapian::docid(-1);
175 plist[i]->get_docid_range(f, l);
176 first = min(first, f);
177 last = max(last, l);
181 string
182 MaxPostList::get_description() const
184 string desc("(");
185 desc += plist[0]->get_description();
186 for (size_t i = 1; i < n_kids; ++i) {
187 desc += " MAX ";
188 desc += plist[i]->get_description();
190 desc += ')';
191 return desc;
194 Xapian::termcount
195 MaxPostList::get_wdf() const
197 Xapian::termcount totwdf = 0;
198 for (size_t i = 0; i < n_kids; ++i) {
199 if (plist[i]->get_docid() == did)
200 totwdf += plist[i]->get_wdf();
202 return totwdf;
205 Xapian::termcount
206 MaxPostList::count_matching_subqs() const
208 return 1;