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 "api_percentages.h"
00025
00026 #include <xapian.h>
00027
00028 #include "apitest.h"
00029 #include "backendmanager_local.h"
00030 #include "str.h"
00031 #include "testutils.h"
00032
00033 #include <cfloat>
00034
00035 using namespace std;
00036
00037
00038
00039
00040 DEFINE_TESTCASE(consistency3, backend) {
00041 Xapian::Database db(get_database("apitest_sortconsist"));
00042 Xapian::Enquire enquire(db);
00043 enquire.set_query(Xapian::Query("foo"));
00044 enquire.set_sort_by_value(1, 0);
00045 Xapian::doccount lots = 3;
00046 Xapian::MSet bigmset = enquire.get_mset(0, lots);
00047 TEST_EQUAL(bigmset.size(), lots);
00048 for (Xapian::doccount start = 0; start < lots; ++start) {
00049 tout << *bigmset[start] << ":" << bigmset[start].get_weight() << ":"
00050 << bigmset[start].get_percent() << "%" << endl;
00051 for (Xapian::doccount size = 0; size < lots - start; ++size) {
00052 Xapian::MSet mset = enquire.get_mset(start, size);
00053 if (mset.size()) {
00054 TEST_EQUAL(start + mset.size(),
00055 min(start + size, bigmset.size()));
00056 } else if (size) {
00057 TEST(start >= bigmset.size());
00058 }
00059 for (Xapian::doccount i = 0; i < mset.size(); ++i) {
00060 TEST_EQUAL(*mset[i], *bigmset[start + i]);
00061 TEST_EQUAL_DOUBLE(mset[i].get_weight(),
00062 bigmset[start + i].get_weight());
00063 TEST_EQUAL_DOUBLE(mset[i].get_percent(),
00064 bigmset[start + i].get_percent());
00065 }
00066 }
00067 }
00068 return true;
00069 }
00070
00071 class MyPostingSource : public Xapian::PostingSource {
00072 vector<pair<Xapian::docid, Xapian::weight> > weights;
00073 vector<pair<Xapian::docid, Xapian::weight> >::const_iterator i;
00074 bool started;
00075
00076 MyPostingSource(const vector<pair<Xapian::docid, Xapian::weight> > &weights_,
00077 Xapian::weight max_wt)
00078 : weights(weights_), started(false)
00079 {
00080 set_maxweight(max_wt);
00081 }
00082
00083 public:
00084 MyPostingSource() : started(false) { }
00085
00086 PostingSource * clone() const
00087 {
00088 return new MyPostingSource(weights, get_maxweight());
00089 }
00090
00091 void append_docweight(Xapian::docid did, Xapian::weight wt) {
00092 weights.push_back(make_pair(did, wt));
00093 if (wt > get_maxweight()) set_maxweight(wt);
00094 }
00095
00096 void init(const Xapian::Database &) { started = false; }
00097
00098 Xapian::weight get_weight() const { return i->second; }
00099
00100 Xapian::doccount get_termfreq_min() const { return weights.size(); }
00101 Xapian::doccount get_termfreq_est() const { return weights.size(); }
00102 Xapian::doccount get_termfreq_max() const { return weights.size(); }
00103
00104 void next(Xapian::weight ) {
00105 if (!started) {
00106 i = weights.begin();
00107 started = true;
00108 } else {
00109 ++i;
00110 }
00111 }
00112
00113 bool at_end() const {
00114 return (i == weights.end());
00115 }
00116
00117 Xapian::docid get_docid() const { return i->first; }
00118
00119 string get_description() const {
00120 return "MyPostingSource";
00121 }
00122 };
00123
00124
00126 DEFINE_TESTCASE(pctcutoff4, backend && !remote && !multi) {
00127
00128
00129 int epsilons = 0;
00130 Xapian::Database db(get_database("apitest_simpledata"));
00131 Xapian::Enquire enquire(db);
00132 while (true) {
00133 MyPostingSource source;
00134 source.append_docweight(1, 100);
00135 source.append_docweight(2, 50 - epsilons * DBL_EPSILON);
00136 enquire.set_query(Xapian::Query(&source));
00137 Xapian::MSet mset = enquire.get_mset(0, 10);
00138 TEST_EQUAL(mset.size(), 2);
00139 if (mset[1].get_percent() != 50) break;
00140 ++epsilons;
00141 }
00142
00143
00144
00145 MyPostingSource source;
00146 source.append_docweight(1, 100);
00147 source.append_docweight(2, 50);
00148 source.append_docweight(3, 50 - (epsilons - 1) * DBL_EPSILON);
00149 source.append_docweight(4, 50 - epsilons * DBL_EPSILON);
00150 source.append_docweight(5, 25);
00151
00152 enquire.set_query(Xapian::Query(&source));
00153 Xapian::MSet mset1 = enquire.get_mset(0, 10);
00154 TEST_EQUAL(mset1.size(), 5);
00155 TEST_EQUAL(mset1[2].get_percent(), 50);
00156 TEST_EQUAL(mset1[3].get_percent(), 49);
00157
00158
00159
00160 int percent = 100;
00161 for (Xapian::MSetIterator i = mset1.begin(); i != mset1.end(); ++i) {
00162 int new_percent = mset1.convert_to_percent(i);
00163 tout << "mset1 item = " << i.get_percent() << "%\n";
00164 if (new_percent != percent) {
00165 enquire.set_cutoff(percent);
00166 Xapian::MSet mset2 = enquire.get_mset(0, 10);
00167 tout << "cutoff = " << percent << "%, "
00168 "mset size = " << mset2.size() << "\n";
00169 TEST_EQUAL(mset2.size(), i.get_rank());
00170 percent = new_percent;
00171 }
00172 }
00173
00174 return true;
00175 }
00176
00178 DEFINE_TESTCASE(pctcutoff5, backend) {
00179 Xapian::Database db(get_database("apitest_simpledata"));
00180 Xapian::Enquire enquire(db);
00181 enquire.set_query(Xapian::Query("test"));
00182 enquire.set_cutoff(42);
00183 Xapian::MSet mset;
00184
00185 enquire.set_sort_by_value(0, false);
00186 TEST_EXCEPTION(Xapian::UnimplementedError, mset = enquire.get_mset(0, 10));
00187
00188 enquire.set_sort_by_value(0, true);
00189 TEST_EXCEPTION(Xapian::UnimplementedError, mset = enquire.get_mset(0, 10));
00190
00191 enquire.set_sort_by_value_then_relevance(0, false);
00192 TEST_EXCEPTION(Xapian::UnimplementedError, mset = enquire.get_mset(0, 10));
00193
00194 enquire.set_sort_by_value_then_relevance(0, true);
00195 TEST_EXCEPTION(Xapian::UnimplementedError, mset = enquire.get_mset(0, 10));
00196
00197 return true;
00198 }
00199
00200
00201 DEFINE_TESTCASE(topercent3, remote) {
00202 BackendManagerLocal local_manager;
00203 local_manager.set_datadir(test_driver::get_srcdir() + "/testdata/");
00204 Xapian::Database db;
00205 db.add_database(get_database("apitest_simpledata"));
00206 db.add_database(local_manager.get_database("apitest_simpledata"));
00207
00208 Xapian::Enquire enquire(db);
00209 enquire.set_sort_by_value(1, false);
00210
00211 const char * terms[] = { "paragraph", "banana" };
00212 enquire.set_query(Xapian::Query(Xapian::Query::OP_OR, terms, terms + 2));
00213
00214 Xapian::MSet mset = enquire.get_mset(0, 20);
00215
00216 Xapian::MSetIterator i;
00217 for (i = mset.begin(); i != mset.end(); ++i) {
00218
00219 TEST_REL(i.get_percent(),<,100);
00220 }
00221
00222 return true;
00223 }
00224
00225
00226
00227 DEFINE_TESTCASE(topercent4, backend) {
00228 Xapian::Enquire enquire(get_database("apitest_simpledata"));
00229
00230 Xapian::Query query(Xapian::Query::OP_FILTER,
00231 Xapian::Query("paragraph"),
00232 Xapian::Query("queri"));
00233 query = Xapian::Query(Xapian::Query::OP_XOR,
00234 query, Xapian::Query("rubbish"));
00235
00236 enquire.set_query(query);
00237 Xapian::MSet mset = enquire.get_mset(0, 10);
00238
00239
00240 TEST(!mset.empty());
00241 TEST_EQUAL(mset[0].get_percent(), 50);
00242
00243 return true;
00244 }
00245
00247 DEFINE_TESTCASE(topercent5, backend) {
00248 Xapian::Enquire enquire(get_database("apitest_simpledata"));
00249 Xapian::Query q(Xapian::Query::OP_OR,
00250 Xapian::Query("paragraph"), Xapian::Query("xyzzy"));
00251 enquire.set_query(q);
00252 Xapian::MSet mset = enquire.get_mset(0, 10);
00253 TEST(!mset.empty());
00254 TEST(mset[0].get_percent() < 100);
00255
00256
00257
00258 TEST(mset[0].get_percent() >= 50);
00259 return true;
00260 }
00261
00263
00264 DEFINE_TESTCASE(topercent6, backend) {
00265 Xapian::Enquire enquire(get_database("apitest_simpledata"));
00266 Xapian::Query q(Xapian::Query::OP_OR,
00267 Xapian::Query("rubbish"), Xapian::Query("letter"));
00268 enquire.set_query(q);
00269 Xapian::MSet mset = enquire.get_mset(0, 10);
00270 TEST(!mset.empty());
00271 TEST(mset[0].get_percent() < 100);
00272
00273 q = Xapian::Query(q.OP_FILTER, q, Xapian::Query("this"));
00274 enquire.set_query(q);
00275 Xapian::MSet mset2 = enquire.get_mset(0, 10);
00276 TEST(!mset2.empty());
00277 TEST_EQUAL(mset[0].get_percent(), mset2[0].get_percent());
00278 return true;
00279 }
00280
00281 static void
00282 make_topercent7_db(Xapian::WritableDatabase &db, const string &)
00283 {
00284 for (int i = 1; i <= 6; ++i) {
00285 Xapian::Document d;
00286 d.set_data(str(i));
00287 d.add_term("boom", 2 + (i - 4)*(i - 2));
00288 if (i != 5)
00289 d.add_boolean_term("XCAT122");
00290 db.add_document(d);
00291 }
00292 db.commit();
00293 }
00294
00296
00297
00298 DEFINE_TESTCASE(topercent7, generated) {
00299 Xapian::Database db(get_database("topercent7", make_topercent7_db));
00300
00301 Xapian::Query q;
00302 q = Xapian::Query(q.OP_OR, Xapian::Query("tomb"), Xapian::Query("boom"));
00303 q = Xapian::Query(q.OP_AND, q, Xapian::Query("XCAT122"));
00304
00305 Xapian::Enquire enq(db);
00306 enq.set_query(q);
00307 Xapian::MSet m = enq.get_mset(0, 10);
00308 TEST(!m.empty());
00309 TEST_REL(m[0].get_percent(),>,60);
00310 return true;
00311 }