00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef XAPIAN_INCLUDED_MULTIANDPOSTLIST_H
00023 #define XAPIAN_INCLUDED_MULTIANDPOSTLIST_H
00024
00025 #include "multimatch.h"
00026 #include "omassert.h"
00027 #include "postlist.h"
00028
00030 class MultiAndPostList : public PostList {
00033 struct ComparePostListTermFreqAscending {
00035 bool operator()(const PostList *a, const PostList *b) {
00036 return a->get_termfreq_est() < b->get_termfreq_est();
00037 }
00038 };
00039
00041 void operator=(const MultiAndPostList &);
00042
00044 MultiAndPostList(const MultiAndPostList &);
00045
00047 Xapian::docid did;
00048
00050 size_t n_kids;
00051
00053 PostList ** plist;
00054
00056 Xapian::weight * max_wt;
00057
00059 Xapian::weight max_total;
00060
00062 Xapian::doccount db_size;
00063
00065 MultiMatch *matcher;
00066
00068 Xapian::weight new_min(Xapian::weight w_min, size_t n) {
00069 return w_min - (max_total - max_wt[n]);
00070 }
00071
00073 void next_helper(size_t n, Xapian::weight w_min) {
00074 PostList * res = plist[n]->next(new_min(w_min, n));
00075 if (res) {
00076 delete plist[n];
00077 plist[n] = res;
00078 matcher->recalc_maxweight();
00079 }
00080 }
00081
00083 void skip_to_helper(size_t n, Xapian::docid did_min, Xapian::weight w_min) {
00084 PostList * res = plist[n]->skip_to(did_min, new_min(w_min, n));
00085 if (res) {
00086 delete plist[n];
00087 plist[n] = res;
00088 matcher->recalc_maxweight();
00089 }
00090 }
00091
00093 void check_helper(size_t n, Xapian::docid did_min, Xapian::weight w_min,
00094 bool &valid) {
00095 PostList * res = plist[n]->check(did_min, new_min(w_min, n), valid);
00096 if (res) {
00097 delete plist[n];
00098 plist[n] = res;
00099 matcher->recalc_maxweight();
00100 }
00101 }
00102
00107 void allocate_plist_and_max_wt();
00108
00110 PostList * find_next_match(Xapian::weight w_min);
00111
00112 public:
00116 template <class RandomItor>
00117 MultiAndPostList(RandomItor pl_begin, RandomItor pl_end,
00118 MultiMatch * matcher_, Xapian::doccount db_size_)
00119 : did(0), n_kids(pl_end - pl_begin), plist(NULL), max_wt(NULL),
00120 max_total(0), db_size(db_size_), matcher(matcher_)
00121 {
00122 allocate_plist_and_max_wt();
00123
00124
00125
00126
00127 std::partial_sort_copy(pl_begin, pl_end, plist, plist + n_kids,
00128 ComparePostListTermFreqAscending());
00129 }
00130
00137 MultiAndPostList(PostList *l, PostList *r,
00138 Xapian::weight lmax, Xapian::weight rmax,
00139 MultiMatch * matcher_, Xapian::doccount db_size_,
00140 bool check_order = false)
00141 : did(0), n_kids(2), plist(NULL), max_wt(NULL),
00142 max_total(lmax + rmax), db_size(db_size_), matcher(matcher_)
00143 {
00144 if (check_order) {
00145 if (l->get_termfreq_est() < r->get_termfreq_est()) {
00146 std::swap(l, r);
00147 std::swap(lmax, rmax);
00148 }
00149 } else {
00150 AssertRel(l->get_termfreq_est(),>=,r->get_termfreq_est());
00151 }
00152 allocate_plist_and_max_wt();
00153
00154 plist[0] = r;
00155 plist[1] = l;
00156 max_wt[0] = rmax;
00157 max_wt[1] = lmax;
00158 }
00159
00160 ~MultiAndPostList();
00161
00162 Xapian::doccount get_termfreq_min() const;
00163
00164 Xapian::doccount get_termfreq_max() const;
00165
00166 Xapian::doccount get_termfreq_est() const;
00167
00168 TermFreqs get_termfreq_est_using_stats(
00169 const Xapian::Weight::Internal & stats) const;
00170
00171 Xapian::weight get_maxweight() const;
00172
00173 Xapian::docid get_docid() const;
00174
00175 Xapian::termcount get_doclength() const;
00176
00177 Xapian::weight get_weight() const;
00178
00179 bool at_end() const;
00180
00181 Xapian::weight recalc_maxweight();
00182
00183 Internal *next(Xapian::weight w_min);
00184
00185 Internal *skip_to(Xapian::docid, Xapian::weight w_min);
00186
00187 std::string get_description() const;
00188
00196 Xapian::termcount get_wdf() const;
00197
00198 Xapian::termcount count_matching_subqs() const;
00199 };
00200
00201 #endif // XAPIAN_INCLUDED_MULTIANDPOSTLIST_H