00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include "localsubmatch.h"
00025
00026 #include "database.h"
00027 #include "debuglog.h"
00028 #include "extraweightpostlist.h"
00029 #include "leafpostlist.h"
00030 #include "omassert.h"
00031 #include "omqueryinternal.h"
00032 #include "queryoptimiser.h"
00033 #include "synonympostlist.h"
00034 #include "termlist.h"
00035 #include "weightinternal.h"
00036
00037 #include "autoptr.h"
00038 #include <map>
00039 #include <string>
00040
00041 using namespace std;
00042
00043 bool
00044 LocalSubMatch::prepare_match(bool nowait,
00045 Xapian::Weight::Internal & total_stats)
00046 {
00047 LOGCALL(MATCH, bool, "LocalSubMatch::prepare_match", nowait | total_stats);
00048 (void)nowait;
00049 Assert(db);
00050 Assert(query);
00051 total_stats.accumulate_stats(*db, rset);
00052 RETURN(true);
00053 }
00054
00055 void
00056 LocalSubMatch::start_match(Xapian::doccount first,
00057 Xapian::doccount maxitems,
00058 Xapian::doccount check_at_least,
00059 const Xapian::Weight::Internal & total_stats)
00060 {
00061 LOGCALL_VOID(MATCH, "LocalSubMatch::start_match", first | maxitems | check_at_least | total_stats);
00062 (void)first;
00063 (void)maxitems;
00064 (void)check_at_least;
00065
00066 stats = &total_stats;
00067 }
00068
00069 PostList *
00070 LocalSubMatch::get_postlist_and_term_info(MultiMatch * matcher,
00071 map<string, Xapian::MSet::Internal::TermFreqAndWeight> * termfreqandwts,
00072 Xapian::termcount * total_subqs_ptr)
00073 {
00074 LOGCALL(MATCH, PostList *, "LocalSubMatch::get_postlist_and_term_info", matcher | termfreqandwts | total_subqs_ptr);
00075 (void)matcher;
00076 term_info = termfreqandwts;
00077
00078
00079
00080
00081 QueryOptimiser opt(*db, *this, matcher);
00082 PostList * pl = opt.optimise_query(query);
00083 *total_subqs_ptr = opt.get_total_subqueries();
00084
00085 AutoPtr<Xapian::Weight> extra_wt(wt_factory->clone());
00086 extra_wt->init_(*stats, qlen);
00087 if (extra_wt->get_maxextra() != 0.0) {
00088
00089
00090
00091 pl = new ExtraWeightPostList(pl, extra_wt.release(), matcher);
00092 }
00093
00094 RETURN(pl);
00095 }
00096
00097 PostList *
00098 LocalSubMatch::make_synonym_postlist(PostList * or_pl, MultiMatch * matcher,
00099 double factor)
00100 {
00101 LOGCALL(MATCH, PostList *, "LocalSubMatch::make_synonym_postlist", or_pl | matcher | factor);
00102 LOGVALUE(MATCH, or_pl->get_termfreq_est());
00103 AutoPtr<SynonymPostList> res(new SynonymPostList(or_pl, matcher));
00104 AutoPtr<Xapian::Weight> wt(wt_factory->clone());
00105
00106 TermFreqs freqs;
00107
00108
00109
00110
00111
00112 if (usual(stats->collection_size != 0)) {
00113 freqs = or_pl->get_termfreq_est_using_stats(*stats);
00114 }
00115 wt->init_(*stats, qlen, factor, freqs.termfreq, freqs.reltermfreq);
00116
00117 res->set_weight(wt.release());
00118 RETURN(res.release());
00119 }
00120
00121 PostList *
00122 LocalSubMatch::postlist_from_op_leaf_query(const Xapian::Query::Internal *leaf,
00123 double factor)
00124 {
00125 LOGCALL(MATCH, PostList *, "LocalSubMatch::postlist_from_op_leaf_query", leaf | factor);
00126 Assert(leaf);
00127 AssertEq(leaf->op, Xapian::Query::Internal::OP_LEAF);
00128 Assert(leaf->subqs.empty());
00129 const string & term = leaf->tname;
00130 bool boolean = (factor == 0.0);
00131 AutoPtr<Xapian::Weight> wt;
00132 if (!boolean) {
00133 wt.reset(wt_factory->clone());
00134 wt->init_(*stats, qlen, term, leaf->get_wqf(), factor);
00135 }
00136
00137 if (term_info) {
00138 Xapian::doccount tf = stats->get_termfreq(term);
00139 using namespace Xapian;
00140
00141 map<string, MSet::Internal::TermFreqAndWeight>::iterator i;
00142 i = term_info->insert(
00143 make_pair(term, MSet::Internal::TermFreqAndWeight(tf))).first;
00144 if (!boolean)
00145 i->second.termweight += wt->get_maxpart();
00146 }
00147
00148 LeafPostList * pl = db->open_post_list(term);
00149
00150
00151 if (!boolean)
00152 pl->set_termweight(wt.release());
00153 RETURN(pl);
00154 }