Ticket #295: remotepostsource3.patch
File remotepostsource3.patch, 45.3 KB (added by , 16 years ago) |
---|
-
xapian-core/matcher/externalpostlist.cc
29 29 30 30 using namespace std; 31 31 32 ExternalPostList::ExternalPostList(Xapian::PostingSource *source_, 32 ExternalPostList::ExternalPostList(const Xapian::Database & db, 33 Xapian::PostingSource *source_, 33 34 double factor_) 34 : source(source_), current(0), factor(factor_)35 : source(source_), source_is_owned(false), current(0), factor(factor_) 35 36 { 36 37 Assert(source); 37 source->reset(); 38 Xapian::PostingSource * newsource = source->clone(); 39 if (newsource != NULL) { 40 source = newsource; 41 source_is_owned = true; 42 } 43 source->reset(db); 38 44 } 39 45 46 ExternalPostList::~ExternalPostList() 47 { 48 if (source_is_owned) { 49 delete source; 50 } 51 } 52 40 53 Xapian::doccount 41 54 ExternalPostList::get_termfreq_min() const 42 55 { -
xapian-core/matcher/queryoptimiser.cc
64 64 65 65 case Xapian::Query::Internal::OP_EXTERNAL_SOURCE: 66 66 Assert(query->external_source); 67 RETURN(new ExternalPostList(query->external_source, factor)); 67 RETURN(new ExternalPostList( 68 Xapian::Database(const_cast<Xapian::Database::Internal *>(&db)), 69 query->external_source, factor)); 68 70 69 71 case Xapian::Query::OP_AND: 70 72 case Xapian::Query::OP_FILTER: -
xapian-core/matcher/externalpostlist.h
29 29 30 30 class ExternalPostList : public PostList { 31 31 Xapian::PostingSource * source; 32 bool source_is_owned; 32 33 33 34 Xapian::docid current; 34 35 … … 43 44 PostList * update_after_advance(); 44 45 45 46 public: 46 ExternalPostList(Xapian::PostingSource *source_, double factor_); 47 ExternalPostList(const Xapian::Database & db, 48 Xapian::PostingSource *source_, 49 double factor_); 50 ~ExternalPostList(); 47 51 48 52 Xapian::doccount get_termfreq_min() const; 49 53 -
xapian-core/tests/api_db.cc
1899 1899 : num_docs(db.get_doccount()), last_docid(db.get_lastdocid()), did(0) 1900 1900 { } 1901 1901 1902 void reset() { did = 0; } 1902 MyOddPostingSource(Xapian::doccount num_docs_, 1903 Xapian::doccount last_docid_) 1904 : num_docs(num_docs_), last_docid(last_docid_), did(0) 1905 { } 1903 1906 1907 PostingSource * clone() const { return new MyOddPostingSource(num_docs, last_docid); } 1908 1909 void reset(const Xapian::Database &) { did = 0; } 1910 1904 1911 // These bounds could be better, but that's not important here. 1905 1912 Xapian::doccount get_termfreq_min() const { return 0; } 1906 1913 … … 1937 1944 Xapian::Enquire enq(db); 1938 1945 MyOddPostingSource src(db); 1939 1946 1940 // Check that passing NULL is rejected as intended.1941 TEST_EXCEPTION(Xapian::InvalidArgumentError, Xapian::Query bad(NULL));1942 Xapian::PostingSource * nullsrc = NULL;1943 TEST_EXCEPTION(Xapian::InvalidArgumentError, Xapian::Query bad(nullsrc));1944 1945 1947 enq.set_query(Xapian::Query(&src)); 1946 1948 1947 1949 Xapian::MSet mset = enq.get_mset(0, 10); … … 1993 1995 : num_docs(db.get_doccount()), last_docid(db.get_lastdocid()), did(0) 1994 1996 { } 1995 1997 1996 void reset() { did = 0; } 1998 MyOddWeightingPostingSource(Xapian::doccount num_docs_, 1999 Xapian::doccount last_docid_) 2000 : num_docs(num_docs_), last_docid(last_docid_), did(0) 2001 { } 1997 2002 2003 PostingSource * clone() const { return new MyOddWeightingPostingSource(num_docs, last_docid); } 2004 2005 void reset(const Xapian::Database &) { did = 0; } 2006 1998 2007 Xapian::weight get_weight() const { 1999 2008 return (did % 2) ? 1000 : 0.001; 2000 2009 } … … 2090 2099 : num_docs(db.get_doccount()), last_docid(db.get_lastdocid()), did(0) 2091 2100 { } 2092 2101 2093 void reset() { did = 0; } 2102 MyDontAskWeightPostingSource(Xapian::doccount num_docs_, 2103 Xapian::doccount last_docid_) 2104 : num_docs(num_docs_), last_docid(last_docid_), did(0) 2105 { } 2094 2106 2107 PostingSource * clone() const { return new MyDontAskWeightPostingSource(num_docs, last_docid); } 2108 2109 void reset(const Xapian::Database &) { did = 0; } 2110 2095 2111 Xapian::weight get_weight() const { 2096 2112 FAIL_TEST("MyDontAskWeightPostingSource::get_weight() called"); 2097 2113 } … … 2163 2179 } 2164 2180 2165 2181 // Check that valueweightsource works correctly. 2166 DEFINE_TESTCASE(valueweightsource1, backend && !remote) { 2167 // FIXME: PostingSource doesn't currently work well with multi databases 2168 // but we should try to resolve that issue. 2169 SKIP_TEST_FOR_BACKEND("multi"); 2182 DEFINE_TESTCASE(valueweightsource1, backend) { 2170 2183 Xapian::Database db(get_database("apitest_phrase")); 2171 2184 Xapian::Enquire enq(db); 2172 Xapian::ValueWeightPostingSource src( db,11);2185 Xapian::ValueWeightPostingSource src(11); 2173 2186 2174 2187 // Should be in descending order of length 2175 2188 tout << "RAW" << endl; … … 2201 2214 // Check that valueweightsource gives the correct bounds for those databases 2202 2215 // which support value statistics. 2203 2216 DEFINE_TESTCASE(valueweightsource2, backend && valuestats) { 2204 // FIXME: PostingSource doesn't currently work well with multi databases2205 // but we should try to resolve that issue.2206 SKIP_TEST_FOR_BACKEND("multi");2207 2217 Xapian::Database db(get_database("apitest_phrase")); 2208 Xapian::ValueWeightPostingSource src(db, 11); 2218 Xapian::ValueWeightPostingSource src(11); 2219 src.reset(db); 2209 2220 TEST_EQUAL(src.get_termfreq_min(), 17); 2210 2221 TEST_EQUAL(src.get_termfreq_est(), 17); 2211 2222 TEST_EQUAL(src.get_termfreq_max(), 17); … … 2220 2231 // but we should try to resolve that issue. 2221 2232 SKIP_TEST_FOR_BACKEND("multi"); 2222 2233 Xapian::Database db(get_database("apitest_phrase")); 2223 Xapian::ValueWeightPostingSource src(db, 11); 2234 Xapian::ValueWeightPostingSource src(11); 2235 src.reset(db); 2224 2236 TEST(!src.at_end()); 2225 2237 src.skip_to(8, 0.0); 2226 2238 TEST(!src.at_end()); … … 2233 2245 } 2234 2246 2235 2247 // Check that fixedweightsource works correctly. 2236 DEFINE_TESTCASE(fixedweightsource1, backend && !remote) { 2237 // FIXME: PostingSource doesn't currently work well with multi databases 2238 // but we should try to resolve that issue. 2239 SKIP_TEST_FOR_BACKEND("multi"); 2248 DEFINE_TESTCASE(fixedweightsource1, backend) { 2240 2249 Xapian::Database db(get_database("apitest_phrase")); 2241 2250 Xapian::Enquire enq(db); 2242 2251 double wt = 5.6; 2243 2252 2244 2253 { 2245 Xapian::FixedWeightPostingSource src( db,wt);2254 Xapian::FixedWeightPostingSource src(wt); 2246 2255 2247 2256 // Should be in increasing order of docid. 2248 2257 enq.set_query(Xapian::Query(&src)); … … 2257 2266 // Do some direct tests, to check the skip_to() and check() methods work. 2258 2267 { 2259 2268 // Check next and skip_to(). 2260 Xapian::FixedWeightPostingSource src(db, wt); 2269 Xapian::FixedWeightPostingSource src(wt); 2270 src.reset(db); 2261 2271 2262 2272 src.next(1.0); 2263 2273 TEST(!src.at_end()); … … 2273 2283 } 2274 2284 { 2275 2285 // Check check() as the first operation, followed by next. 2276 Xapian::FixedWeightPostingSource src(db, wt); 2286 Xapian::FixedWeightPostingSource src(wt); 2287 src.reset(db); 2277 2288 2278 2289 TEST_EQUAL(src.check(5, 1.0), true); 2279 2290 TEST(!src.at_end()); … … 2284 2295 } 2285 2296 { 2286 2297 // Check check() as the first operation, followed by skip_to(). 2287 Xapian::FixedWeightPostingSource src(db, wt); 2298 Xapian::FixedWeightPostingSource src(wt); 2299 src.reset(db); 2288 2300 2289 2301 TEST_EQUAL(src.check(5, 1.0), true); 2290 2302 TEST(!src.at_end()); -
xapian-core/tests/api_percentages.cc
38 38 Xapian::weight maxwt; 39 39 bool started; 40 40 41 MyPostingSource(const std::vector<std::pair<Xapian::docid, Xapian::weight> > &weights_, 42 Xapian::weight maxwt_) 43 : weights(weights_), maxwt(maxwt_), started(false) 44 {} 45 41 46 public: 42 47 MyPostingSource() : maxwt(0.0), started(false) { } 43 48 49 PostingSource * clone() const 50 { 51 return new MyPostingSource(weights, maxwt); 52 } 53 44 54 void append_docweight(Xapian::docid did, Xapian::weight wt) { 45 55 weights.push_back(make_pair(did, wt)); 46 56 if (wt > maxwt) maxwt = wt; … … 50 60 if (wt > maxwt) maxwt = wt; 51 61 } 52 62 53 void reset( ) { started = false; }63 void reset(const Xapian::Database &) { started = false; } 54 64 55 65 Xapian::weight get_weight() const { return i->second; } 56 66 -
xapian-core/tests/internaltest.cc
452 452 Xapian::Query::Internal * qint; 453 453 454 454 s = query->internal->serialise(); 455 qint = Xapian::Query::Internal::unserialise(s); 455 map<string, Xapian::PostingSource *> m; 456 qint = Xapian::Query::Internal::unserialise(s, m); 456 457 457 458 TEST(qint->serialise() == s); 458 459 delete qint; -
xapian-core/tests/api_valuestream.cc
162 162 * 163 163 * The original implementation went into an infinite loop in this case. 164 164 */ 165 DEFINE_TESTCASE(valueweightsource5, writable && valuestats) { 166 // FIXME: PostingSource doesn't currently work well with multi databases 167 // but we should try to resolve that issue. 168 SKIP_TEST_FOR_BACKEND("multi"); 165 DEFINE_TESTCASE(valueweightsource5, writable && valuestats & !multi) { 169 166 // inmemory's memory use is currently O(last_docid)! 170 167 SKIP_TEST_FOR_BACKEND("inmemory"); 171 168 // Not supported currently. … … 177 174 db.replace_document(0xffffffff, doc); 178 175 db.flush(); 179 176 180 Xapian::ValueWeightPostingSource src(db, 1); 177 Xapian::ValueWeightPostingSource src(1); 178 src.reset(db); 181 179 src.next(0.0); 182 180 TEST(!src.at_end()); 183 181 TEST_EQUAL(src.get_docid(), 1); … … 210 208 // 16 Pad 211 209 // 17 Pad 212 210 // 213 DEFINE_TESTCASE(valuemapsource1, backend && !remote) { 214 // FIXME: PostingSource doesn't currently work well with multi databases 215 // but we should try to resolve that issue. 216 SKIP_TEST_FOR_BACKEND("multi"); 211 DEFINE_TESTCASE(valuemapsource1, backend) { 217 212 Xapian::Database db(get_database("apitest_phrase")); 218 213 Xapian::Enquire enq(db); 219 214 220 Xapian::ValueMapPostingSource src( db,13);215 Xapian::ValueMapPostingSource src(13); 221 216 src.add_mapping("Thi", 2.0); 222 217 src.add_mapping("The", 1.0); 223 218 src.add_mapping("You", 3.0); … … 251 246 252 247 // Regression test for valuepostingsource subclasses: used to segfault if skip_to() 253 248 // called on an empty list. 254 DEFINE_TESTCASE(valuemapsource2, backend && !remote) { 255 // FIXME: PostingSource doesn't currently work well with multi databases 256 // but we should try to resolve that issue. 257 SKIP_TEST_FOR_BACKEND("multi"); 249 DEFINE_TESTCASE(valuemapsource2, backend && !remote && !multi) { 258 250 Xapian::Database db(get_database("apitest_phrase")); 259 Xapian::Enquire enq(db);260 251 261 252 { 262 Xapian::ValueMapPostingSource src(db, 100); 253 Xapian::ValueMapPostingSource src(100); 254 src.reset(db); 255 TEST(src.at_end() == false); 263 256 src.next(0.0); 264 257 TEST(src.at_end() == true); 265 258 } 266 259 267 260 { 268 Xapian::ValueMapPostingSource src(db, 100); 261 Xapian::ValueMapPostingSource src(100); 262 src.reset(db); 263 TEST(src.at_end() == false); 269 264 src.skip_to(1, 0.0); 270 265 TEST(src.at_end() == true); 271 266 } 272 267 273 268 { 274 Xapian::ValueMapPostingSource src(db, 100); 269 Xapian::ValueMapPostingSource src(100); 270 src.reset(db); 271 TEST(src.at_end() == false); 275 272 src.check(1, 0.0); 276 273 TEST(src.at_end() == true); 277 274 } 278 275 279 276 return true; 280 277 } 278 279 // Regression test for fixedweightpostingsource: used to segfault if skip_to() 280 // called on an empty list. 281 DEFINE_TESTCASE(fixedweightsource2, !backend) { 282 Xapian::Database db; 283 284 { 285 Xapian::FixedWeightPostingSource src(5.0); 286 src.reset(db); 287 TEST(src.at_end() == false); 288 src.next(0.0); 289 TEST(src.at_end() == true); 290 } 291 292 { 293 Xapian::FixedWeightPostingSource src(5.0); 294 src.reset(db); 295 TEST(src.at_end() == false); 296 src.skip_to(1, 0.0); 297 TEST(src.at_end() == true); 298 } 299 300 // No need to test behaviour of check() - check is only allowed to be 301 // called with document IDs which exist, so can never be called for a 302 // FixedWeightPostingSource with an empty database. 303 304 return true; 305 } -
xapian-core/include/xapian/postingsource.h
138 138 /// Return the current docid. 139 139 virtual Xapian::docid get_docid() const = 0; 140 140 141 /** Clone the posting source. 142 * 143 * The clone should inherit the configuration of the parent, but need not 144 * inherit the state. ie, the clone does not need to be in the same 145 * iteration position as the original: the matcher will always call 146 * reset() on the clone before attempting to move the iterator, or read 147 * the information about the current position of the iterator. 148 * 149 * This may return NULL to indicate that cloning is not supported. In 150 * this case, the PostingSource may only be used with a single-database 151 * search. 152 * 153 * The default implementation returns NULL. 154 */ 155 virtual PostingSource * clone() const; 156 157 /** Name of the posting source, for performing remote searches. 158 * 159 * If the subclass is called FooPostingSource, this should return "Foo". 160 * 161 * This should only be implemented if serialise() and unserialise() are 162 * also implemented. 163 * 164 * The default implmenentation returns an empty string, to indicate that 165 * serialise() and unserialise() are not implemented. 166 */ 167 virtual std::string name() const; 168 169 /** Serialise object parameters into a string. 170 * 171 * The serialised parameters should represent the configuration of the 172 * posting source, but need not (indeed, should not) represent the current 173 * iteration state. 174 */ 175 virtual std::string serialise() const; 176 177 /** Create object given string serialisation returned by serialise(). 178 * 179 * @param s A serialised instance of this PostingSource subclass. 180 */ 181 virtual PostingSource * unserialise(const std::string &s) const; 182 141 183 /** Reset this PostingSource to its freshly constructed state. 142 184 * 143 185 * This is called automatically by the matcher prior to each query being 144 186 * processed. 187 * 188 * FIXME - document the db parameter. 145 189 */ 146 virtual void reset( ) = 0;190 virtual void reset(const Database & db) = 0; 147 191 148 192 /** Return a string describing this object. 149 193 * … … 171 215 Xapian::valueno slot; 172 216 173 217 /// Value stream iterator. 174 Xapian::ValueIterator it;218 Xapian::ValueIterator value_it; 175 219 176 220 /// End iterator corresponding to it. 177 Xapian::ValueIterator end;221 Xapian::ValueIterator value_end; 178 222 179 223 /// Flag indicating if we've started (true if we have). 180 224 bool started; 181 225 182 226 /** An upper bound on the weight returned. 183 227 * 184 * Subclasses should set this in their constructor if they know a bound on185 * the weight. It defaults to DBL_MAX.228 * Subclasses should set this in their reset method if they know a bound 229 * on the weight. It defaults to DBL_MAX. 186 230 */ 187 231 double max_weight; 188 232 … … 210 254 public: 211 255 /** Construct a ValuePostingSource. 212 256 * 213 * @param db_ The database to read values from.214 257 * @param slot_ The value slot to read values from. 215 258 */ 216 ValuePostingSource(Xapian:: Database db_, Xapian::valueno slot_);259 ValuePostingSource(Xapian::valueno slot_); 217 260 218 261 Xapian::doccount get_termfreq_min() const; 219 262 Xapian::doccount get_termfreq_est() const; … … 229 272 230 273 Xapian::docid get_docid() const; 231 274 232 void reset( );275 void reset(const Database & db_); 233 276 }; 234 277 235 278 /** A posting source which reads weights from a value slot. … … 248 291 */ 249 292 class XAPIAN_VISIBILITY_DEFAULT ValueWeightPostingSource 250 293 : public ValuePostingSource { 294 /// Upper bound on the value returned specified in constructor. 295 double specified_max_weight; 296 251 297 public: 252 298 /** Construct a ValueWeightPostingSource. 253 299 * 254 * @param db_ The database to read values from.255 300 * @param slot_ The value slot to read values from. 256 301 */ 257 ValueWeightPostingSource(Xapian:: Database db_, Xapian::valueno slot_);302 ValueWeightPostingSource(Xapian::valueno slot_); 258 303 259 304 /** Construct a ValueWeightPostingSource. 260 305 * 261 * @param db_ The database to read values from.262 306 * @param slot_ The value slot to read values from. 263 307 * @param max_weight_ An upper bound on the weights which are stored in 264 308 * the value slot. Note that for the chert database format, information … … 266 310 * constructor need only be used if more accurate information is 267 311 * available. 268 312 */ 269 ValueWeightPostingSource(Xapian::Database db_, 270 Xapian::valueno slot_, 271 double max_weight_); 313 ValueWeightPostingSource(Xapian::valueno slot_, double max_weight_); 272 314 273 315 Xapian::weight get_weight() const; 316 ValueWeightPostingSource * clone() const; 317 std::string name() const; 318 std::string serialise() const; 319 PostingSource * unserialise(const std::string &s) const; 320 void reset(const Database & db_); 274 321 275 322 std::string get_description() const; 276 323 }; … … 289 336 /// The default weight 290 337 double default_weight; 291 338 339 /// The maximum weight in weight_map. 340 double max_weight_in_map; 341 292 342 /// The value -> weight map 293 343 std::map<std::string, double> weight_map; 294 344 295 345 public: 296 346 /** Construct a ValueWeightPostingSource. 297 347 * 298 * @param db_ The database to read values from.299 348 * @param slot_ The value slot to read values from. 300 349 * @param default_weight The default weight to return for unmapped values. 301 350 */ 302 ValueMapPostingSource(Xapian:: Database db_, Xapian::valueno slot_);351 ValueMapPostingSource(Xapian::valueno slot_); 303 352 304 353 /** Add a mapping. 305 354 * … … 317 366 void set_default_weight(double wt); 318 367 319 368 Xapian::weight get_weight() const; 369 ValueMapPostingSource * clone() const; 370 std::string name() const; 371 std::string serialise() const; 372 PostingSource * unserialise(const std::string &s) const; 373 void reset(const Database & db_); 320 374 321 375 std::string get_description() const; 322 376 }; … … 351 405 public: 352 406 /** Construct a FixedWeightPostingSource. 353 407 * 354 * @param db_ The database to read values from.355 408 * @param slot_ The value slot to read values from. 356 409 */ 357 FixedWeightPostingSource(Xapian:: Database db_, Xapian::weight wt_);410 FixedWeightPostingSource(Xapian::weight wt_); 358 411 359 412 Xapian::doccount get_termfreq_min() const; 360 413 Xapian::doccount get_termfreq_est() const; … … 371 424 372 425 Xapian::docid get_docid() const; 373 426 374 void reset(); 427 FixedWeightPostingSource * clone() const; 428 std::string name() const; 429 std::string serialise() const; 430 PostingSource * unserialise(const std::string &s) const; 431 void reset(const Database & db_); 375 432 376 433 std::string get_description() const; 377 434 }; -
xapian-core/include/xapian/query.h
25 25 #ifndef XAPIAN_INCLUDED_QUERY_H 26 26 #define XAPIAN_INCLUDED_QUERY_H 27 27 28 #include <map> 28 29 #include <string> 29 30 #include <vector> 30 31 … … 204 205 */ 205 206 Query(Query::op op_, Xapian::valueno valno, const std::string &value); 206 207 207 /// Construct an external source query. 208 /** Construct an external source query. 209 * 210 * An attempt to clone the posting source will be made immediately, so 211 * if the posting source supports clone(), the source supplied may be 212 * safely deallocated after this call. If the source does not support 213 * clone, the caller must ensure that the posting source remains valid 214 * until the Query is deallocated. 215 * 216 * @param external_source The source to use in the query. 217 */ 208 218 explicit Query(Xapian::PostingSource * external_source); 209 219 210 220 /** A query which matches all documents in the database. */ … … 249 259 std::string serialise() const; 250 260 251 261 /** Unserialise a query from a string produced by serialise(). 262 * FIXME - need to add a way to register posting sources. 252 263 */ 253 264 static Query unserialise(const std::string &s); 254 265 … … 339 350 /// External posting source. 340 351 Xapian::PostingSource * external_source; 341 352 353 /// Flag, indicating whether the external source is owned by the query. 354 bool external_source_owned; 355 342 356 /** swap the contents of this with another Xapian::Query::Internal, 343 357 * in a way which is guaranteed not to throw. This is 344 358 * used with the assignment operator to make it exception … … 414 428 Internal(op_t op_, Xapian::valueno valno, const std::string &value); 415 429 416 430 /// Construct an external source query. 417 explicit Internal(Xapian::PostingSource * external_source_ );431 explicit Internal(Xapian::PostingSource * external_source_, bool owned); 418 432 419 433 /** Destructor. */ 420 434 ~Internal(); 421 435 422 static Xapian::Query::Internal * unserialise(const std::string &s); 436 static Xapian::Query::Internal * unserialise(const std::string &s, 437 const std::map<std::string, Xapian::PostingSource *> &sources); 423 438 424 439 /** Add a subquery. 425 440 */ -
xapian-core/net/remoteserver.cc
114 114 wtschemes[weight->name()] = weight; 115 115 weight = new Xapian::TradWeight; 116 116 wtschemes[weight->name()] = weight; 117 118 Xapian::PostingSource * source; 119 source = new Xapian::ValueWeightPostingSource(0); 120 postingsources[source->name()] = source; 121 source = new Xapian::ValueMapPostingSource(0); 122 postingsources[source->name()] = source; 123 source = new Xapian::FixedWeightPostingSource(0); 124 postingsources[source->name()] = source; 117 125 } 118 126 119 127 RemoteServer::~RemoteServer() … … 121 129 delete db; 122 130 // wdb is either NULL or equal to db, so we shouldn't delete it too! 123 131 124 map<string, Xapian::Weight*>::const_iterator i; 125 for (i = wtschemes.begin(); i != wtschemes.end(); ++i) { 126 delete i->second; 132 { 133 map<string, Xapian::Weight*>::const_iterator i; 134 for (i = wtschemes.begin(); i != wtschemes.end(); ++i) { 135 delete i->second; 136 } 127 137 } 138 139 { 140 map<string, Xapian::PostingSource *>::const_iterator i; 141 for (i = postingsources.begin(); i != postingsources.end(); ++i) { 142 delete i->second; 143 } 144 } 128 145 } 129 146 130 147 message_type … … 365 382 366 383 // Unserialise the Query. 367 384 len = decode_length(&p, p_end, true); 368 AutoPtr<Xapian::Query::Internal> query(Xapian::Query::Internal::unserialise(string(p, len) ));385 AutoPtr<Xapian::Query::Internal> query(Xapian::Query::Internal::unserialise(string(p, len), postingsources)); 369 386 p += len; 370 387 371 388 // Unserialise assorted Enquire settings. … … 610 627 611 628 send_message(REPLY_ADDDOCUMENT, encode_length(did)); 612 629 } 630 631 632 void 633 RemoteServer::register_posting_source(const Xapian::PostingSource &source) 634 { 635 if (source.name().empty()) { 636 throw Xapian::InvalidOperationError("Unable to register posting source - name() method returns empty string."); 637 } 638 Xapian::PostingSource * sourceclone = source.clone(); 639 if (!sourceclone) { 640 throw Xapian::InvalidOperationError("Unable to register posting source - clone() method returns NULL."); 641 } 642 try { 643 postingsources[source.name()] = sourceclone; 644 } catch(...) { 645 delete sourceclone; 646 throw; 647 } 648 } -
xapian-core/common/remoteserver.h
24 24 25 25 #include "xapian/database.h" 26 26 #include "xapian/enquire.h" 27 #include "xapian/postingsource.h" 27 28 #include "xapian/visibility.h" 28 29 29 30 #include "remoteconnection.h" … … 31 32 #include <map> 32 33 #include <string> 33 34 34 // Forward declaration35 namespace Xapian { class Weight; }36 37 35 using namespace std; 38 36 39 37 /** Remote backend server base class. */ … … 70 68 /// Registered weighting schemes. 71 69 map<string, Xapian::Weight *> wtschemes; 72 70 71 /// Registered external posting sources. 72 map<string, Xapian::PostingSource *> postingsources; 73 73 74 /// Accept a message from the client. 74 75 message_type get_message(Xapian::timeout timeout, string & result, 75 76 message_type required_type = MSG_MAX); … … 173 174 void register_weighting_scheme(const Xapian::Weight &wt) { 174 175 wtschemes[wt.name()] = wt.clone(); 175 176 } 177 178 /** Register a user-defined posting source class. 179 */ 180 void register_posting_source(const Xapian::PostingSource &source); 176 181 }; 177 182 178 183 #endif // XAPIAN_INCLUDED_REMOTESERVER_H -
xapian-core/api/postingsource.cc
32 32 #include "xapian/queryparser.h" // For sortable_unserialise(). 33 33 34 34 #include "omassert.h" 35 #include "serialise.h" 36 #include "serialise-double.h" 35 37 #include "utils.h" 36 38 37 39 #include <cfloat> … … 67 69 return true; 68 70 } 69 71 72 PostingSource * 73 PostingSource::clone() const 74 { 75 return NULL; 76 } 77 70 78 std::string 79 PostingSource::name() const 80 { 81 return std::string(); 82 } 83 84 std::string 85 PostingSource::serialise() const 86 { 87 throw Xapian::InvalidOperationError("serialise() not supported for this PostingSource"); 88 } 89 90 PostingSource * 91 PostingSource::unserialise(const std::string &) const 92 { 93 throw Xapian::InvalidOperationError("unserialise() not supported for this PostingSource"); 94 } 95 96 std::string 71 97 PostingSource::get_description() const 72 98 { 73 99 return "Xapian::PostingSource subclass"; 74 100 } 75 101 76 102 77 ValuePostingSource::ValuePostingSource(Xapian::Database db_, 78 Xapian::valueno slot_) 79 : db(db_), 80 slot(slot_), 81 it(db.valuestream_begin(slot)), 82 end(db.valuestream_end(slot)), 83 started(false), 84 max_weight(DBL_MAX) 103 ValuePostingSource::ValuePostingSource(Xapian::valueno slot_) 104 : slot(slot_) 85 105 { 86 try {87 termfreq_max = db.get_value_freq(slot);88 termfreq_est = termfreq_max;89 termfreq_min = termfreq_max;90 } catch (const Xapian::UnimplementedError &) {91 termfreq_max = db.get_doccount();92 termfreq_est = termfreq_max / 2;93 termfreq_min = 0;94 }95 106 } 96 107 97 108 Xapian::doccount … … 123 134 { 124 135 if (!started) { 125 136 started = true; 126 it = db.valuestream_begin(slot);127 end = db.valuestream_end(slot);137 value_it = db.valuestream_begin(slot); 138 value_end = db.valuestream_end(slot); 128 139 } else { 129 ++ it;140 ++value_it; 130 141 } 131 142 132 if ( it ==end) return;143 if (value_it == value_end) return; 133 144 134 145 if (min_wt > max_weight) { 135 it =end;146 value_it = value_end; 136 147 return; 137 148 } 138 149 } … … 143 154 { 144 155 if (!started) { 145 156 started = true; 146 it = db.valuestream_begin(slot);147 end = db.valuestream_end(slot);157 value_it = db.valuestream_begin(slot); 158 value_end = db.valuestream_end(slot); 148 159 149 if ( it ==end) return;160 if (value_it == value_end) return; 150 161 } 151 162 152 163 if (min_wt > max_weight) { 153 it =end;164 value_it = value_end; 154 165 return; 155 166 } 156 it.skip_to(min_docid);167 value_it.skip_to(min_docid); 157 168 } 158 169 159 170 bool … … 162 173 { 163 174 if (!started) { 164 175 started = true; 165 it = db.valuestream_begin(slot);166 end = db.valuestream_end(slot);176 value_it = db.valuestream_begin(slot); 177 value_end = db.valuestream_end(slot); 167 178 168 if ( it ==end) return true;179 if (value_it == value_end) return true; 169 180 } 170 181 171 182 if (min_wt > max_weight) { 172 it =end;183 value_it = value_end; 173 184 return true; 174 185 } 175 return it.check(min_docid);186 return value_it.check(min_docid); 176 187 } 177 188 178 189 bool 179 190 ValuePostingSource::at_end() const 180 191 { 181 return it ==end;192 return started && value_it == value_end; 182 193 } 183 194 184 195 Xapian::docid 185 196 ValuePostingSource::get_docid() const 186 197 { 187 return it.get_docid();198 return value_it.get_docid(); 188 199 } 189 200 190 201 void 191 ValuePostingSource::reset( )202 ValuePostingSource::reset(const Database & db_) 192 203 { 204 db = db_; 193 205 started = false; 206 max_weight = DBL_MAX; 207 try { 208 termfreq_max = db.get_value_freq(slot); 209 termfreq_est = termfreq_max; 210 termfreq_min = termfreq_max; 211 } catch (const Xapian::UnimplementedError &) { 212 termfreq_max = db.get_doccount(); 213 termfreq_est = termfreq_max / 2; 214 termfreq_min = 0; 215 } 194 216 } 195 217 196 218 197 ValueWeightPostingSource::ValueWeightPostingSource(Xapian:: Database db_,198 Xapian::valueno slot_)199 : ValuePostingSource(db_, slot_)219 ValueWeightPostingSource::ValueWeightPostingSource(Xapian::valueno slot_) 220 : ValuePostingSource(slot_), 221 specified_max_weight(DBL_MAX) 200 222 { 201 try {202 max_weight = sortable_unserialise(db_.get_value_upper_bound(slot_));203 } catch (const Xapian::UnimplementedError &) {204 }205 223 } 206 224 207 ValueWeightPostingSource::ValueWeightPostingSource(Xapian::Database db_, 208 Xapian::valueno slot_, 225 ValueWeightPostingSource::ValueWeightPostingSource(Xapian::valueno slot_, 209 226 double max_weight_) 210 : ValuePostingSource(db_, slot_) 227 : ValuePostingSource(slot_), 228 specified_max_weight(max_weight_) 211 229 { 212 try {213 double ubound = sortable_unserialise(db_.get_value_upper_bound(slot_));214 max_weight = std::min(max_weight_, ubound);215 } catch (const Xapian::UnimplementedError &) {216 max_weight = max_weight_;217 }218 230 } 219 231 220 232 Xapian::weight … … 222 234 { 223 235 Assert(!at_end()); 224 236 Assert(started); 225 return sortable_unserialise(* it);237 return sortable_unserialise(*value_it); 226 238 } 227 239 240 ValueWeightPostingSource * 241 ValueWeightPostingSource::clone() const 242 { 243 return new ValueWeightPostingSource(slot, specified_max_weight); 244 } 245 228 246 std::string 247 ValueWeightPostingSource::name() const 248 { 249 return std::string("ValueWeight"); 250 } 251 252 std::string 253 ValueWeightPostingSource::serialise() const 254 { 255 return encode_length(slot) + serialise_double(specified_max_weight); 256 } 257 258 PostingSource * 259 ValueWeightPostingSource::unserialise(const std::string &s) const 260 { 261 const char * p = s.data(); 262 const char * end = p + s.size(); 263 264 Xapian::valueno new_valno = decode_length(&p, end, false); 265 double new_spec_max = unserialise_double(&p, end); 266 if (p != end) { 267 throw Xapian::NetworkError("Bad serialised ValueWeightPostingSource - junk at end"); 268 } 269 270 return new ValueWeightPostingSource(new_valno, new_spec_max); 271 } 272 273 void 274 ValueWeightPostingSource::reset(const Database & db_) 275 { 276 ValuePostingSource::reset(db_); 277 278 try { 279 double ubound = sortable_unserialise(db.get_value_upper_bound(slot)); 280 max_weight = std::min(specified_max_weight, ubound); 281 } catch (const Xapian::UnimplementedError &) { 282 max_weight = specified_max_weight; 283 } 284 } 285 286 std::string 229 287 ValueWeightPostingSource::get_description() const 230 288 { 231 289 return "Xapian::ValueWeightPostingSource(slot=" + om_tostring(slot) + ")"; 232 290 } 233 291 234 292 235 ValueMapPostingSource::ValueMapPostingSource(Xapian:: Database db_,236 Xapian::valueno slot_)237 : ValuePostingSource(db_, slot_),238 default_weight(0.0)293 ValueMapPostingSource::ValueMapPostingSource(Xapian::valueno slot_) 294 : ValuePostingSource(slot_), 295 default_weight(0.0), 296 max_weight_in_map(0.0) 239 297 { 240 298 } 241 299 … … 243 301 ValueMapPostingSource::add_mapping(std::string key_, double weight_) 244 302 { 245 303 weight_map[key_] = weight_; 246 max_weight = std::max(weight_, max_weight);304 max_weight_in_map = std::max(weight_, max_weight_in_map); 247 305 } 248 306 249 307 void 250 308 ValueMapPostingSource::clear_mappings() 251 309 { 252 310 weight_map.clear(); 253 max_weight = default_weight;311 max_weight_in_map = 0.0; 254 312 } 255 313 256 314 void … … 263 321 Xapian::weight 264 322 ValueMapPostingSource::get_weight() const 265 323 { 266 std::map<std::string, double>::const_iterator wit = weight_map.find(* it);324 std::map<std::string, double>::const_iterator wit = weight_map.find(*value_it); 267 325 if (wit == weight_map.end()) { 268 326 return default_weight; 269 327 } else { … … 271 329 } 272 330 } 273 331 332 ValueMapPostingSource * 333 ValueMapPostingSource::clone() const 334 { 335 AutoPtr<ValueMapPostingSource> res(new ValueMapPostingSource(slot)); 336 std::map<std::string, double>::const_iterator i; 337 for (i = weight_map.begin(); i != weight_map.end(); ++i) 338 { 339 res->add_mapping(i->first, i->second); 340 } 341 res->set_default_weight(default_weight); 342 return res.release(); 343 } 344 274 345 std::string 346 ValueMapPostingSource::name() const 347 { 348 return std::string("ValueMap"); 349 } 350 351 std::string 352 ValueMapPostingSource::serialise() const 353 { 354 std::string result; 355 result = encode_length(slot) + serialise_double(default_weight); 356 357 std::map<std::string, double>::const_iterator i; 358 for (i = weight_map.begin(); i != weight_map.end(); ++i) 359 { 360 result.append(encode_length(i->first.size())); 361 result.append(i->first); 362 result.append(serialise_double(i->second)); 363 } 364 365 return result; 366 } 367 368 PostingSource * 369 ValueMapPostingSource::unserialise(const std::string &s) const 370 { 371 const char * p = s.data(); 372 const char * end = p + s.size(); 373 374 Xapian::valueno new_slot = decode_length(&p, end, false); 375 AutoPtr<ValueMapPostingSource> res(new ValueMapPostingSource(new_slot)); 376 res->set_default_weight(unserialise_double(&p, end)); 377 while (p != end) { 378 size_t keylen = decode_length(&p, end, true); 379 string key(p, keylen); 380 p += keylen; 381 res->add_mapping(key, unserialise_double(&p, end)); 382 } 383 return res.release(); 384 } 385 386 void 387 ValueMapPostingSource::reset(const Database & db_) 388 { 389 ValuePostingSource::reset(db_); 390 max_weight = std::max(max_weight_in_map, default_weight); 391 } 392 393 std::string 275 394 ValueMapPostingSource::get_description() const 276 395 { 277 396 return "Xapian::ValueMapPostingSource(slot=" + om_tostring(slot) + ")"; 278 397 } 279 398 280 399 281 FixedWeightPostingSource::FixedWeightPostingSource(Xapian::Database db_, 282 Xapian::weight wt_) 283 : db(db_), termfreq(db_.get_doccount()), 284 it(db.postlist_begin(std::string())), 285 end(db.postlist_end(std::string())), 286 wt(wt_), 400 FixedWeightPostingSource::FixedWeightPostingSource(Xapian::weight wt_) 401 : wt(wt_), 287 402 started(false) 288 403 { 289 404 } … … 350 465 started = true; 351 466 it = db.postlist_begin(std::string()); 352 467 end = db.postlist_end(std::string()); 468 469 if (it == end) return; 353 470 } 354 471 355 472 if (check_docid) { … … 378 495 bool 379 496 FixedWeightPostingSource::at_end() const 380 497 { 381 return it == end; 498 if (check_docid != 0) return false; 499 return started && it == end; 382 500 } 383 501 384 502 Xapian::docid … … 388 506 return *it; 389 507 } 390 508 509 FixedWeightPostingSource * 510 FixedWeightPostingSource::clone() const 511 { 512 return new FixedWeightPostingSource(wt); 513 } 514 515 std::string 516 FixedWeightPostingSource::name() const 517 { 518 return std::string("FixedWeight"); 519 } 520 521 std::string 522 FixedWeightPostingSource::serialise() const 523 { 524 return serialise_double(wt); 525 } 526 527 PostingSource * 528 FixedWeightPostingSource::unserialise(const std::string &s) const 529 { 530 const char * p = s.data(); 531 const char * s_end = p + s.size(); 532 double new_wt = unserialise_double(&p, s_end); 533 if (p != s_end) { 534 throw Xapian::NetworkError("Bad serialised ValueWeightPostingSource - junk at end"); 535 } 536 return new FixedWeightPostingSource(new_wt); 537 } 538 391 539 void 392 FixedWeightPostingSource::reset( )540 FixedWeightPostingSource::reset(const Xapian::Database & db_) 393 541 { 542 db = db_; 543 termfreq = db_.get_doccount(); 394 544 started = false; 395 545 check_docid = 0; 396 546 } -
xapian-core/api/omqueryinternal.cc
41 41 #include <cfloat> 42 42 #include <climits> 43 43 #include <cmath> 44 #include <map> 44 45 #include <set> 45 46 #include <vector> 46 47 … … 141 142 result += '['; 142 143 result += encode_length(tname.length()); 143 144 result += tname; 144 if (term_pos != curpos) result += '@' + om_tostring(term_pos); 145 if (wqf != 1) result += '#' + om_tostring(wqf); 145 if (term_pos != curpos) result += '@' + om_tostring(term_pos); // FIXME - should this use encode_length()? 146 if (wqf != 1) result += '#' + om_tostring(wqf); // FIXME - should this use encode_length()? 146 147 ++curpos; 147 148 } else if (op == Xapian::Query::Internal::OP_EXTERNAL_SOURCE) { 148 throw Xapian::UnimplementedError("Remote backend doesn't support PostingSource"); 149 string sourcename = external_source->name(); 150 if (sourcename.empty()) 151 throw Xapian::UnimplementedError("This PostingSource doesn't support remote use."); 152 result += '!'; 153 result += encode_length(sourcename.length()); 154 result += sourcename; 155 string sourcedata = external_source->serialise(); 156 result += encode_length(sourcedata.length()); 157 result += sourcedata; 149 158 } else { 150 159 result += "("; 151 160 for (subquery_list::const_iterator i = subqs.begin(); … … 157 166 case Xapian::Query::Internal::OP_LEAF: 158 167 Assert(false); 159 168 break; 169 case Xapian::Query::Internal::OP_EXTERNAL_SOURCE: 170 Assert(false); 171 break; 160 172 case Xapian::Query::OP_AND: 161 173 result += "&"; 162 174 break; … … 379 391 const char *p; 380 392 const char *end; 381 393 Xapian::termpos curpos; 394 const map<string, Xapian::PostingSource *> & sources; 382 395 383 396 Xapian::Query::Internal * readquery(); 397 Xapian::Query::Internal * readexternal(); 384 398 Xapian::Query::Internal * readcompound(); 385 399 386 400 public: 387 QUnserial(const string & s) : p(s.c_str()), end(p + s.size()), curpos(1) { } 401 QUnserial(const string & s, 402 const map<string, Xapian::PostingSource *> & sources_) 403 : p(s.c_str()), end(p + s.size()), curpos(1), sources(sources_) { } 388 404 Xapian::Query::Internal * decode(); 389 405 }; 390 406 … … 423 439 ++curpos; 424 440 return new Xapian::Query::Internal(tname, wqf, term_pos); 425 441 } 442 case '!': 443 return readexternal(); 426 444 case '(': 427 445 return readcompound(); 428 446 default: … … 431 449 } 432 450 } 433 451 452 Xapian::Query::Internal * 453 QUnserial::readexternal() 454 { 455 if (p == end) 456 throw Xapian::InvalidArgumentError("Bad serialised query"); 457 458 size_t length = decode_length(&p, end, true); 459 string sourcename(p, length); 460 map<string, Xapian::PostingSource *>::const_iterator i; 461 i = sources.find(string(p, length)); 462 if (i == sources.end()) { 463 throw Xapian::InvalidArgumentError("PostingSource " + string(p, length) + " not registered"); 464 } 465 466 p += length; 467 length = decode_length(&p, end, true); 468 string sourcedata(p, length); 469 p += length; 470 471 return new Xapian::Query::Internal(i->second->unserialise(sourcedata), true); 472 } 473 434 474 static Xapian::Query::Internal * 435 475 qint_from_vector(Xapian::Query::op op, 436 476 const vector<Xapian::Query::Internal *> & vec, … … 475 515 --p; 476 516 subqs.push_back(readquery()); 477 517 break; 518 case '!': 519 subqs.push_back(readexternal()); 520 break; 478 521 case '(': { 479 522 subqs.push_back(readcompound()); 480 523 break; … … 562 605 } 563 606 564 607 Xapian::Query::Internal * 565 Xapian::Query::Internal::unserialise(const string &s) 608 Xapian::Query::Internal::unserialise(const string &s, 609 const map<string, Xapian::PostingSource *> & sources) 566 610 { 567 611 Assert(s.length() > 1); 568 QUnserial u(s );612 QUnserial u(s, sources); 569 613 Xapian::Query::Internal * qint = u.decode(); 570 614 AssertEq(s, qint->serialise()); 571 615 return qint; 572 616 } 573 617 #else 574 618 Xapian::Query::Internal * 575 Xapian::Query::Internal::unserialise(const string &) 619 Xapian::Query::Internal::unserialise(const string &, 620 const map<string, Xapian::PostingSource *> & sources) 576 621 { 577 622 throw Xapian::InternalError("query serialisation not compiled in"); 578 623 } … … 596 641 std::swap(term_pos, other.term_pos); 597 642 std::swap(wqf, other.wqf); 598 643 std::swap(external_source, other.external_source); 644 std::swap(external_source_owned, other.external_source_owned); 599 645 } 600 646 601 647 Xapian::Query::Internal::Internal(const Xapian::Query::Internal ©me) … … 607 653 str_parameter(copyme.str_parameter), 608 654 term_pos(copyme.term_pos), 609 655 wqf(copyme.wqf), 610 external_source(copyme.external_source) 656 external_source(NULL), 657 external_source_owned(false) 611 658 { 612 659 for (subquery_list::const_iterator i = copyme.subqs.begin(); 613 660 i != copyme.subqs.end(); 614 661 ++i) { 615 662 subqs.push_back(new Xapian::Query::Internal(**i)); 616 663 } 664 if (copyme.external_source) { 665 external_source = copyme.external_source->clone(); 666 if (external_source == NULL) { 667 external_source = copyme.external_source; 668 external_source_owned = false; 669 } else { 670 external_source_owned = true; 671 } 672 } 617 673 } 618 674 619 675 ////////////////////////////////////////// … … 626 682 parameter(0), 627 683 tname(tname_), 628 684 term_pos(term_pos_), 629 wqf(wqf_) 685 wqf(wqf_), 686 external_source(NULL), 687 external_source_owned(false) 630 688 { 631 689 validate_query(); 632 690 } … … 637 695 parameter(parameter_), 638 696 tname(), 639 697 term_pos(0), 640 wqf(0) 698 wqf(0), 699 external_source(NULL), 700 external_source_owned(false) 641 701 { 642 702 if (parameter != 0 && op != OP_PHRASE && op != OP_NEAR && op != OP_ELITE_SET) 643 703 throw Xapian::InvalidArgumentError("parameter is only meaningful for OP_NEAR, OP_PHRASE, or OP_ELITE_SET"); … … 648 708 : op(op_), 649 709 parameter(Xapian::termcount(valno)), 650 710 tname(begin), 651 str_parameter(end) 711 str_parameter(end), 712 external_source(NULL), 713 external_source_owned(false) 652 714 { 653 715 if (op != OP_VALUE_RANGE) 654 716 throw Xapian::InvalidArgumentError("This constructor is only meaningful for OP_VALUE_RANGE"); … … 659 721 const std::string &value) 660 722 : op(op_), 661 723 parameter(Xapian::termcount(valno)), 662 tname(value) 724 tname(value), 725 external_source(NULL), 726 external_source_owned(false) 663 727 { 664 728 if (op != OP_VALUE_GE && op != OP_VALUE_LE) 665 729 throw Xapian::InvalidArgumentError("This constructor is only meaningful for OP_VALUE_GE or OP_VALUE_LE"); … … 673 737 validate_query(); 674 738 } 675 739 676 Xapian::Query::Internal::Internal(PostingSource * external_source_) 677 : op(OP_EXTERNAL_SOURCE), external_source(external_source_) 740 Xapian::Query::Internal::Internal(PostingSource * external_source_, bool owned) 741 : op(OP_EXTERNAL_SOURCE), external_source(external_source_), 742 external_source_owned(owned) 678 743 { 679 if (!external_source) 680 throw Xapian::InvalidArgumentError("The external_source parameter can not be NULL"); 744 Assert(external_source); 681 745 } 682 746 683 747 Xapian::Query::Internal::~Internal() … … 686 750 for (i = subqs.begin(); i != subqs.end(); i++) { 687 751 delete *i; 688 752 } 753 if (external_source_owned) { 754 delete external_source; 755 } 689 756 } 690 757 691 758 Xapian::Query::Internal * -
xapian-core/api/omquery.cc
29 29 #include "utils.h" 30 30 31 31 #include "xapian/error.h" 32 #include "xapian/postingsource.h" 32 33 #include "xapian/termiterator.h" 33 34 34 35 #include <vector> … … 160 161 } 161 162 162 163 Query::Query(PostingSource * external_source) 163 : internal( new Query::Internal(external_source))164 : internal(NULL) 164 165 { 165 166 DEBUGAPICALL(void, "Xapian::Query::Query", external_source); 167 PostingSource * clone = external_source->clone(); 168 if (clone) { 169 internal = new Query::Internal(clone, true); 170 } else { 171 internal = new Query::Internal(external_source, false); 172 } 166 173 } 167 174 168 175 // Copy constructor … … 207 214 DEBUGAPICALL_STATIC(Xapian::Query, "Xapian::Query::unserialise", s); 208 215 Query result; 209 216 if (!s.empty()) { 210 result.internal = Xapian::Query::Internal::unserialise(s); 217 std::map<std::string, Xapian::PostingSource *> sources; 218 result.internal = Xapian::Query::Internal::unserialise(s, sources); 211 219 } 212 220 RETURN(result); 213 221 } -
xapian-bindings/python/generate-python-exceptions
39 39 get_docid 40 40 get_description 41 41 reset 42 name 43 serialise 42 44 ); 43 45 44 46 open FD, ">except.i" or die $!; -
xapian-bindings/python/pythontest2.py
913 913 xapian.PostingSource.__init__(self) 914 914 self.max = max 915 915 916 def reset(self ):916 def reset(self, db): 917 917 self.current = -1 918 918 919 919 def get_termfreq_min(self): return 0 … … 954 954 doc.add_value(1, xapian.sortable_serialise(vals[id])) 955 955 db.add_document(doc) 956 956 957 source = xapian.ValueWeightPostingSource( db,1)957 source = xapian.ValueWeightPostingSource(1) 958 958 query = xapian.Query(source) 959 959 # del source # Check that query keeps a reference to it. 960 960 -
xapian-bindings/xapian.i
194 194 195 195 #ifdef XAPIAN_SWIG_DIRECTORS 196 196 %feature("director") Xapian::PostingSource; 197 %ignore Xapian::PostingSource::clone; 198 %ignore Xapian::PostingSource::unserialise; 197 199 %include <xapian/postingsource.h> 198 200 #else 199 201 %ignore Xapian::Query(Xapian::PostingSource *);