2 * @brief Merged postlist; items from one list, weights from both
4 /* Copyright 1999,2000,2001 BrightStation PLC
5 * Copyright 2002 Ananova Ltd
6 * Copyright 2003,2004,2005,2008,2009,2011,2017 Olly Betts
7 * Copyright 2009 Lemur Consulting Ltd
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
26 #include "andmaybepostlist.h"
29 #include "multiandpostlist.h"
33 AndMaybePostList::process_next_or_skip_to(double w_min
, PostList
*ret
)
35 LOGCALL(MATCH
, PostList
*, "AndMaybePostList::process_next_or_skip_to", w_min
| ret
);
38 // once l is over, so is the AND MAYBE
43 lhead
= l
->get_docid();
44 if (lhead
<= rhead
) RETURN(NULL
);
47 check_handling_prune(r
, lhead
, w_min
- lmax
, matcher
, valid
);
54 rhead
= r
->get_docid();
62 AndMaybePostList::sync_rhs(double w_min
)
64 LOGCALL(MATCH
, PostList
*, "AndMaybePostList::sync_rhs", w_min
);
66 check_handling_prune(r
, lhead
, w_min
- lmax
, matcher
, valid
);
73 rhead
= r
->get_docid();
81 AndMaybePostList::next(double w_min
)
83 LOGCALL(MATCH
, PostList
*, "AndMaybePostList::next", w_min
);
85 // we can replace the AND MAYBE with an AND
87 LOGLINE(MATCH
, "AND MAYBE -> AND");
88 ret
= new MultiAndPostList(l
, r
, lmax
, rmax
, matcher
, dbsize
);
90 skip_to_handling_prune(ret
, std::max(lhead
, rhead
) + 1, w_min
, matcher
);
93 RETURN(process_next_or_skip_to(w_min
, l
->next(w_min
- rmax
)));
97 AndMaybePostList::skip_to(Xapian::docid did
, double w_min
)
99 LOGCALL(MATCH
, PostList
*, "AndMaybePostList::skip_to", did
| w_min
);
101 // we can replace the AND MAYBE with an AND
103 LOGLINE(MATCH
, "AND MAYBE -> AND (in skip_to)");
104 ret
= new MultiAndPostList(l
, r
, lmax
, rmax
, matcher
, dbsize
);
105 did
= std::max(did
, std::max(lhead
, rhead
));
107 skip_to_handling_prune(ret
, did
, w_min
, matcher
);
111 // exit if we're already past the skip point (or at it)
112 if (did
<= lhead
) RETURN(NULL
);
114 RETURN(process_next_or_skip_to(w_min
, l
->skip_to(did
, w_min
- rmax
)));
118 AndMaybePostList::get_termfreq_max() const
120 LOGCALL(MATCH
, Xapian::doccount
, "AndMaybePostList::get_termfreq_max", NO_ARGS
);
121 // Termfreq is exactly that of left hand branch.
122 RETURN(l
->get_termfreq_max());
126 AndMaybePostList::get_termfreq_min() const
128 LOGCALL(MATCH
, Xapian::doccount
, "AndMaybePostList::get_termfreq_min", NO_ARGS
);
129 // Termfreq is exactly that of left hand branch.
130 RETURN(l
->get_termfreq_min());
134 AndMaybePostList::get_termfreq_est() const
136 LOGCALL(MATCH
, Xapian::doccount
, "AndMaybePostList::get_termfreq_est", NO_ARGS
);
137 // Termfreq is exactly that of left hand branch.
138 RETURN(l
->get_termfreq_est());
142 AndMaybePostList::get_termfreq_est_using_stats(
143 const Xapian::Weight::Internal
& stats
) const
145 LOGCALL(MATCH
, TermFreqs
, "AndMaybePostList::get_termfreq_est_using_stats", stats
);
146 // Termfreq is exactly that of left hand branch.
147 RETURN(l
->get_termfreq_est_using_stats(stats
));
151 AndMaybePostList::get_docid() const
153 LOGCALL(MATCH
, Xapian::docid
, "AndMaybePostList::get_docid", NO_ARGS
);
154 Assert(lhead
!= 0); // check we've started
158 // only called if we are doing a probabilistic AND MAYBE
160 AndMaybePostList::get_weight() const
162 LOGCALL(MATCH
, double, "AndMaybePostList::get_weight", NO_ARGS
);
163 Assert(lhead
!= 0); // check we've started
164 if (lhead
== rhead
) RETURN(l
->get_weight() + r
->get_weight());
165 RETURN(l
->get_weight());
168 // only called if we are doing a probabilistic operation
170 AndMaybePostList::get_maxweight() const
172 LOGCALL(MATCH
, double, "AndMaybePostList::get_maxweight", NO_ARGS
);
177 AndMaybePostList::recalc_maxweight()
179 LOGCALL(MATCH
, double, "AndMaybePostList::recalc_maxweight", NO_ARGS
);
180 lmax
= l
->recalc_maxweight();
181 rmax
= r
->recalc_maxweight();
182 RETURN(AndMaybePostList::get_maxweight());
186 AndMaybePostList::at_end() const
188 LOGCALL(MATCH
, bool, "AndMaybePostList::at_end", NO_ARGS
);
193 AndMaybePostList::get_description() const
195 return "(" + l
->get_description() + " AndMaybe " + r
->get_description() +
200 AndMaybePostList::get_doclength() const
202 LOGCALL(MATCH
, Xapian::termcount
, "AndMaybePostList::get_doclength", NO_ARGS
);
203 Assert(lhead
!= 0); // check we've started
204 if (lhead
== rhead
) AssertEq(l
->get_doclength(), r
->get_doclength());
205 RETURN(l
->get_doclength());
209 AndMaybePostList::get_unique_terms() const
211 LOGCALL(MATCH
, Xapian::termcount
, "AndMaybePostList::get_unique_terms", NO_ARGS
);
212 Assert(lhead
!= 0); // check we've started
213 if (lhead
== rhead
) AssertEq(l
->get_unique_terms(), r
->get_unique_terms());
214 RETURN(l
->get_unique_terms());
218 AndMaybePostList::get_wdf() const
220 LOGCALL(MATCH
, Xapian::termcount
, "AndMaybePostList::get_wdf", NO_ARGS
);
221 if (lhead
== rhead
) RETURN(l
->get_wdf() + r
->get_wdf());
222 RETURN(l
->get_wdf());
226 AndMaybePostList::count_matching_subqs() const
228 LOGCALL(MATCH
, Xapian::termcount
, "AndMaybePostList::count_matching_subqs", NO_ARGS
);
230 RETURN(l
->count_matching_subqs() + r
->count_matching_subqs());
231 RETURN(l
->count_matching_subqs());
235 AndMaybePostList::gather_position_lists(OrPositionList
* orposlist
)
237 l
->gather_position_lists(orposlist
);
238 if (lhead
== rhead
) r
->gather_position_lists(orposlist
);