00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef XAPIAN_INCLUDED_MULTIANDPOSTLIST_H
00022 #define XAPIAN_INCLUDED_MULTIANDPOSTLIST_H
00023
00024 #include "multimatch.h"
00025 #include "postlist.h"
00026
00028 class MultiAndPostList : public PostList {
00031 struct ComparePostListTermFreqAscending {
00033 bool operator()(const PostList *a, const PostList *b) {
00034 return a->get_termfreq_est() < b->get_termfreq_est();
00035 }
00036 };
00037
00039 void operator=(const MultiAndPostList &);
00040
00042 MultiAndPostList(const MultiAndPostList &);
00043
00045 Xapian::docid did;
00046
00048 size_t n_kids;
00049
00051 PostList ** plist;
00052
00054 Xapian::weight * max_wt;
00055
00057 Xapian::weight max_total;
00058
00060 Xapian::doccount db_size;
00061
00063 MultiMatch *matcher;
00064
00066 Xapian::weight new_min(Xapian::weight w_min, size_t n) {
00067 return w_min - (max_total - max_wt[n]);
00068 }
00069
00071 void next_helper(size_t n, Xapian::weight w_min) {
00072 PostList * res = plist[n]->next(new_min(w_min, n));
00073 if (res) {
00074 delete plist[n];
00075 plist[n] = res;
00076 matcher->recalc_maxweight();
00077 }
00078 }
00079
00081 void skip_to_helper(size_t n, Xapian::docid did_min, Xapian::weight w_min) {
00082 PostList * res = plist[n]->skip_to(did_min, new_min(w_min, n));
00083 if (res) {
00084 delete plist[n];
00085 plist[n] = res;
00086 matcher->recalc_maxweight();
00087 }
00088 }
00089
00091 void check_helper(size_t n, Xapian::docid did_min, Xapian::weight w_min,
00092 bool &valid) {
00093 PostList * res = plist[n]->check(did_min, new_min(w_min, n), valid);
00094 if (res) {
00095 delete plist[n];
00096 plist[n] = res;
00097 matcher->recalc_maxweight();
00098 }
00099 }
00100
00102 PostList * find_next_match(Xapian::weight w_min);
00103
00104 public:
00108 template <class RandomItor>
00109 MultiAndPostList(RandomItor pl_begin, RandomItor pl_end,
00110 MultiMatch * matcher_, Xapian::doccount db_size_)
00111 : did(0), n_kids(pl_end - pl_begin), plist(NULL), max_wt(NULL),
00112 max_total(0), db_size(db_size_), matcher(matcher_)
00113 {
00114 plist = new PostList * [n_kids];
00115 try {
00116 max_wt = new Xapian::weight [n_kids];
00117 } catch (...) {
00118 delete [] plist;
00119 plist = NULL;
00120 throw;
00121 }
00122
00123
00124
00125
00126 std::partial_sort_copy(pl_begin, pl_end, plist, plist + n_kids,
00127 ComparePostListTermFreqAscending());
00128 }
00129
00130 ~MultiAndPostList();
00131
00132 Xapian::doccount get_termfreq_min() const;
00133
00134 Xapian::doccount get_termfreq_max() const;
00135
00136 Xapian::doccount get_termfreq_est() const;
00137
00138 Xapian::weight get_maxweight() const;
00139
00140 Xapian::docid get_docid() const;
00141
00142 Xapian::doclength get_doclength() const;
00143
00144 Xapian::weight get_weight() const;
00145
00146 bool at_end() const;
00147
00148 Xapian::weight recalc_maxweight();
00149
00150 Internal *next(Xapian::weight w_min);
00151
00152 Internal *skip_to(Xapian::docid, Xapian::weight w_min);
00153
00154 std::string get_description() const;
00155
00161 virtual Xapian::termcount get_wdf() const;
00162 };
00163
00164 #endif // XAPIAN_INCLUDED_MULTIANDPOSTLIST_H