1 /** @file branchpostlist.h
2 * @brief virtual base class for branched types of postlist
3 */
4 /* Copyright 1999,2000,2001 BrightStation PLC
5 * Copyright 2002 Ananova Ltd
6 * Copyright 2003,2004,2007,2011 Olly Betts
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 #ifndef OM_HGUARD_BRANCHPOSTLIST_H
25 #define OM_HGUARD_BRANCHPOSTLIST_H
26
27 #include "multimatch.h"
28 #include "api/postlist.h"
29
30 /** Base class for postlists which are generated by merging two
31 * sub-postlists.
32 *
33 * These postlists form a tree which is used to perform a sum over all the
34 * terms in the query for each document, in order to calculate the score
35 * for that document.
36 */
37 class BranchPostList : public PostList {
38 private:
39 // Prevent copying
40 BranchPostList(const BranchPostList &);
41 BranchPostList & operator=(const BranchPostList &);
42
43 protected:
44 /// Left sub-postlist
45 PostList *l;
46
47 /// Right sub-postlist
48 PostList *r;
49
50 /** The object which is using this postlist to perform
51 * a match. This object needs to be notified when the
52 * tree changes such that the maximum weights need to be
53 * recalculated.
54 */
55 MultiMatch *matcher;
56
57 /** Utility method, to call recalc_maxweight() and do the pruning
58 * if a next() or skip_to() returns non-NULL result.
59 */
handle_prune(PostList * & kid,PostList * ret)60 void handle_prune(PostList *&kid, PostList *ret) {
61 if (ret) {
62 delete kid;
63 kid = ret;
64
65 // now tell matcher that maximum weights need recalculation.
66 matcher->recalc_maxweight();
67 }
68 }
69
70 public:
BranchPostList(PostList * l_,PostList * r_,MultiMatch * matcher_)71 BranchPostList(PostList *l_, PostList *r_, MultiMatch *matcher_)
72 : l(l_), r(r_), matcher(matcher_) {}
73
74 virtual ~BranchPostList();
75 };
76
77 // Helper functions - call next/skip_to on a postlist and handle any
78 // resulting prune
79 //
80 // Returns true iff a prune was handled, so the caller can recalculate
81 // weights etc if necessary
82 inline bool
next_handling_prune(PostList * & pl,double w_min,MultiMatch * matcher)83 next_handling_prune(PostList * & pl, double w_min, MultiMatch *matcher)
84 {
85 PostList *p = pl->next(w_min);
86 if (!p) return false;
87 delete pl;
88 pl = p;
89 // now tell matcher that maximum weights need recalculation.
90 if (matcher) matcher->recalc_maxweight();
91 return true;
92 }
93
94 inline bool
skip_to_handling_prune(PostList * & pl,Xapian::docid did,double w_min,MultiMatch * matcher)95 skip_to_handling_prune(PostList * & pl, Xapian::docid did, double w_min,
96 MultiMatch *matcher)
97 {
98 PostList *p = pl->skip_to(did, w_min);
99 if (!p) return false;
100 delete pl;
101 pl = p;
102 // now tell matcher that maximum weights need recalculation.
103 if (matcher) matcher->recalc_maxweight();
104 return true;
105 }
106
107 inline bool
check_handling_prune(PostList * & pl,Xapian::docid did,double w_min,MultiMatch * matcher,bool & valid)108 check_handling_prune(PostList * & pl, Xapian::docid did, double w_min,
109 MultiMatch *matcher, bool & valid)
110 {
111 PostList *p = pl->check(did, w_min, valid);
112 if (!p) return false;
113 delete pl;
114 pl = p;
115 // now tell matcher that maximum weights need recalculation.
116 if (matcher) matcher->recalc_maxweight();
117 return true;
118 }
119
120 #endif /* OM_HGUARD_BRANCHPOSTLIST_H */
121