Branch data Line data Source code
1 : : /* andmaybepostlist.cc: Merged postlist; items from one list, weights from both
2 : : *
3 : : * Copyright 1999,2000,2001 BrightStation PLC
4 : : * Copyright 2002 Ananova Ltd
5 : : * Copyright 2003,2004,2005,2008,2009 Olly Betts
6 : : * Copyright 2009 Lemur Consulting Ltd
7 : : *
8 : : * This program is free software; you can redistribute it and/or
9 : : * modify it under the terms of the GNU General Public License as
10 : : * published by the Free Software Foundation; either version 2 of the
11 : : * License, or (at your option) any later version.
12 : : *
13 : : * This program is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : : * GNU General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU General Public License
19 : : * along with this program; if not, write to the Free Software
20 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21 : : * USA
22 : : */
23 : :
24 : : #include <config.h>
25 : : #include "andmaybepostlist.h"
26 : :
27 : : #include "debuglog.h"
28 : : #include "multiandpostlist.h"
29 : : #include "omassert.h"
30 : :
31 : : PostList *
32 : 1183 : AndMaybePostList::process_next_or_skip_to(Xapian::weight w_min, PostList *ret)
33 : : {
34 : : LOGCALL(MATCH, PostList *, "AndMaybePostList::process_next_or_skip_to", w_min | ret);
35 : 1183 : handle_prune(l, ret);
36 [ + + ]: 1183 : if (l->at_end()) {
37 : : // once l is over, so is the AND MAYBE
38 : 181 : lhead = 0;
39 : 181 : RETURN(NULL);
40 : : }
41 : :
42 : 1002 : lhead = l->get_docid();
43 [ + + ]: 1002 : if (lhead <= rhead) RETURN(NULL);
44 : :
45 : : bool valid;
46 : 690 : check_handling_prune(r, lhead, w_min - lmax, matcher, valid);
47 [ + + ]: 690 : if (r->at_end()) {
48 : 42 : PostList *tmp = l;
49 : 42 : l = NULL;
50 : 42 : RETURN(tmp);
51 : : }
52 [ + - ]: 648 : if (valid) {
53 : 648 : rhead = r->get_docid();
54 : : } else {
55 : 0 : rhead = 0;
56 : : }
57 : 1183 : RETURN(NULL);
58 : : }
59 : :
60 : : PostList *
61 : 3 : AndMaybePostList::sync_rhs(Xapian::weight w_min)
62 : : {
63 : : LOGCALL(MATCH, PostList *, "AndMaybePostList::sync_rhs", w_min);
64 : : bool valid;
65 : 3 : check_handling_prune(r, lhead, w_min - lmax, matcher, valid);
66 [ - + ]: 3 : if (r->at_end()) {
67 : 0 : PostList *tmp = l;
68 : 0 : l = NULL;
69 : 0 : RETURN(tmp);
70 : : }
71 [ + - ]: 3 : if (valid) {
72 : 3 : rhead = r->get_docid();
73 : : } else {
74 : 0 : rhead = 0;
75 : : }
76 : 3 : RETURN(NULL);
77 : : }
78 : :
79 : : PostList *
80 : 1192 : AndMaybePostList::next(Xapian::weight w_min)
81 : : {
82 : : LOGCALL(MATCH, PostList *, "AndMaybePostList::next", w_min);
83 [ + + ]: 1192 : if (w_min > lmax) {
84 : : // we can replace the AND MAYBE with an AND
85 : : PostList *ret;
86 : : LOGLINE(MATCH, "AND MAYBE -> AND");
87 : 9 : ret = new MultiAndPostList(l, r, lmax, rmax, matcher, dbsize, true);
88 : 9 : l = r = NULL;
89 : 9 : skip_to_handling_prune(ret, std::max(lhead, rhead) + 1, w_min, matcher);
90 : 9 : RETURN(ret);
91 : : }
92 : 1192 : RETURN(process_next_or_skip_to(w_min, l->next(w_min - rmax)));
93 : : }
94 : :
95 : : PostList *
96 : 0 : AndMaybePostList::skip_to(Xapian::docid did, Xapian::weight w_min)
97 : : {
98 : : LOGCALL(MATCH, PostList *, "AndMaybePostList::skip_to", did | w_min);
99 [ # # ]: 0 : if (w_min > lmax) {
100 : : // we can replace the AND MAYBE with an AND
101 : : PostList *ret;
102 : : LOGLINE(MATCH, "AND MAYBE -> AND (in skip_to)");
103 : 0 : ret = new MultiAndPostList(l, r, lmax, rmax, matcher, dbsize, true);
104 : 0 : did = std::max(did, std::max(lhead, rhead));
105 : 0 : l = r = NULL;
106 : 0 : skip_to_handling_prune(ret, did, w_min, matcher);
107 : 0 : RETURN(ret);
108 : : }
109 : :
110 : : // exit if we're already past the skip point (or at it)
111 [ # # ]: 0 : if (did <= lhead) RETURN(NULL);
112 : :
113 : 0 : RETURN(process_next_or_skip_to(w_min, l->skip_to(did, w_min - rmax)));
114 : : }
115 : :
116 : : Xapian::doccount
117 : 100 : AndMaybePostList::get_termfreq_max() const
118 : : {
119 : : LOGCALL(MATCH, Xapian::doccount, "AndMaybePostList::get_termfreq_max", NO_ARGS);
120 : : // Termfreq is exactly that of left hand branch.
121 : 100 : RETURN(l->get_termfreq_max());
122 : : }
123 : :
124 : : Xapian::doccount
125 : 100 : AndMaybePostList::get_termfreq_min() const
126 : : {
127 : : LOGCALL(MATCH, Xapian::doccount, "AndMaybePostList::get_termfreq_min", NO_ARGS);
128 : : // Termfreq is exactly that of left hand branch.
129 : 100 : RETURN(l->get_termfreq_min());
130 : : }
131 : :
132 : : Xapian::doccount
133 : 152 : AndMaybePostList::get_termfreq_est() const
134 : : {
135 : : LOGCALL(MATCH, Xapian::doccount, "AndMaybePostList::get_termfreq_est", NO_ARGS);
136 : : // Termfreq is exactly that of left hand branch.
137 : 152 : RETURN(l->get_termfreq_est());
138 : : }
139 : :
140 : : TermFreqs
141 : 32 : AndMaybePostList::get_termfreq_est_using_stats(
142 : : const Xapian::Weight::Internal & stats) const
143 : : {
144 : : LOGCALL(MATCH, TermFreqs, "AndMaybePostList::get_termfreq_est_using_stats", stats);
145 : : // Termfreq is exactly that of left hand branch.
146 : 32 : RETURN(l->get_termfreq_est_using_stats(stats));
147 : : }
148 : :
149 : : Xapian::docid
150 : 813 : AndMaybePostList::get_docid() const
151 : : {
152 : : LOGCALL(MATCH, Xapian::docid, "AndMaybePostList::get_docid", NO_ARGS);
153 : : Assert(lhead != 0); // check we've started
154 : 813 : RETURN(lhead);
155 : : }
156 : :
157 : : // only called if we are doing a probabilistic AND MAYBE
158 : : Xapian::weight
159 : 911 : AndMaybePostList::get_weight() const
160 : : {
161 : : LOGCALL(MATCH, Xapian::weight, "AndMaybePostList::get_weight", NO_ARGS);
162 : : Assert(lhead != 0); // check we've started
163 [ + + ]: 911 : if (lhead == rhead) RETURN(l->get_weight() + r->get_weight());
164 : 911 : RETURN(l->get_weight());
165 : : }
166 : :
167 : : // only called if we are doing a probabilistic operation
168 : : Xapian::weight
169 : 398 : AndMaybePostList::get_maxweight() const
170 : : {
171 : : LOGCALL(MATCH, Xapian::weight, "AndMaybePostList::get_maxweight", NO_ARGS);
172 : 398 : RETURN(lmax + rmax);
173 : : }
174 : :
175 : : Xapian::weight
176 : 282 : AndMaybePostList::recalc_maxweight()
177 : : {
178 : : LOGCALL(MATCH, Xapian::weight, "AndMaybePostList::recalc_maxweight", NO_ARGS);
179 : 282 : lmax = l->recalc_maxweight();
180 : 282 : rmax = r->recalc_maxweight();
181 : 282 : RETURN(AndMaybePostList::get_maxweight());
182 : : }
183 : :
184 : : bool
185 : 1148 : AndMaybePostList::at_end() const
186 : : {
187 : : LOGCALL(MATCH, bool, "AndMaybePostList::at_end", NO_ARGS);
188 : 1148 : RETURN(lhead == 0);
189 : : }
190 : :
191 : : std::string
192 : 0 : AndMaybePostList::get_description() const
193 : : {
194 : 0 : return "(" + l->get_description() + " AndMaybe " + r->get_description() +
195 : 0 : ")";
196 : : }
197 : :
198 : : Xapian::termcount
199 : 26 : AndMaybePostList::get_doclength() const
200 : : {
201 : : LOGCALL(MATCH, Xapian::termcount, "AndMaybePostList::get_doclength", NO_ARGS);
202 : : Assert(lhead != 0); // check we've started
203 : 26 : if (lhead == rhead) AssertEq(l->get_doclength(), r->get_doclength());
204 : 26 : RETURN(l->get_doclength());
205 : : }
206 : :
207 : : Xapian::termcount
208 : 52 : AndMaybePostList::get_wdf() const
209 : : {
210 : : LOGCALL(MATCH, Xapian::termcount, "AndMaybePostList::get_wdf", NO_ARGS);
211 [ + + ]: 52 : if (lhead == rhead) RETURN(l->get_wdf() + r->get_wdf());
212 : 52 : RETURN(l->get_wdf());
213 : : }
214 : :
215 : : Xapian::termcount
216 : 211 : AndMaybePostList::count_matching_subqs() const
217 : : {
218 : : LOGCALL(MATCH, Xapian::termcount, "AndMaybePostList::count_matching_subqs", NO_ARGS);
219 [ + + ]: 211 : if (lhead == rhead)
220 : 172 : RETURN(l->count_matching_subqs() + r->count_matching_subqs());
221 : 211 : RETURN(l->count_matching_subqs());
222 : : }
|