Ticket #710: remote_protocol_server_on_public_api.diff
File remote_protocol_server_on_public_api.diff, 10.6 KB (added by , 9 years ago) |
---|
-
xapian-core/api/omenquire.cc
commit dc8483f6c6af8d0f38a57f6d8108305e3978b9a7 Author: German M. Bravo <german.mb@deipi.com> Date: Mon Feb 29 09:54:19 2016 -0600 Public API for allowing custom Remote Protocol Server implementation. To be able to implement a Remote Protocol Server with only the xapian public API, four changes are needed: * Add Xapian::Enquire::prepare_mset(): prepares an enquire to get a MSet. Xapian::Weight::Internal is filled with the statistics and a MultiMatch is initialized. * Add stats serialisation methods: Xapian::Enquire::serialise_stats() and Xapian::Enquire::unserialise_stats(). These are used by MSG_QUERY and MSG_GETMSET. * Add Xapian::MSet::serialise() and Xapian::MSet::unserialise(). Used by MSG_GETMSET. * Add Xapian::RSet::serialise() and Xapian::RSet::unserialise(). Used by MSG_QUERY. diff --git a/xapian-core/api/omenquire.cc b/xapian-core/api/omenquire.cc index ad04eff..7b56d7a 100644
a b 43 43 #include "api/omenquireinternal.h" 44 44 #include "str.h" 45 45 #include "weight/weightinternal.h" 46 #include "net/serialise.h" 46 47 47 48 #include <algorithm> 48 49 #include "autoptr.h" … … RSet::Internal::get_description() const 133 134 return description; 134 135 } 135 136 137 std::string 138 RSet::serialise() const 139 { 140 LOGCALL(API, std::string, "RSet::serialise", NO_ARGS); 141 RETURN(serialise_rset(*this)); 142 } 143 144 RSet 145 RSet::unserialise(const std::string &s) 146 { 147 LOGCALL_STATIC(API, RSet, "RSet::unserialise", s); 148 RETURN(unserialise_rset(s)); 149 } 150 136 151 namespace Internal { 137 152 138 153 // Methods for Xapian::MSetItem … … MSet::get_description() const 321 336 return "Xapian::MSet(" + internal->get_description() + ")"; 322 337 } 323 338 339 std::string 340 MSet::serialise() const 341 { 342 LOGCALL(API, std::string, "MSet::serialise", NO_ARGS); 343 RETURN(serialise_mset(*this)); 344 } 345 346 MSet 347 MSet::unserialise(const std::string &s) 348 { 349 LOGCALL_STATIC(API, MSet, "MSet::unserialise", s); 350 RETURN(unserialise_mset(s.data(), s.data() + s.size())); 351 } 352 324 353 int 325 354 MSet::Internal::convert_to_percent_internal(double wt) const 326 355 { … … Enquire::Internal::get_query() const 620 649 return query; 621 650 } 622 651 623 MSet 624 Enquire::Internal::get_mset(Xapian::doccount first, Xapian::doccount maxitems, 625 Xapian::doccount check_at_least, const RSet *rset, 626 const MatchDecider *mdecider) const 652 void 653 Enquire::Internal::unserialise_stats(const string& serialised) 654 { 655 if (!stats) stats.reset(new Xapian::Weight::Internal); 656 ::unserialise_stats(serialised, *(stats.get())); 657 stats->set_bounds_from_db(db); 658 } 659 660 const string 661 Enquire::Internal::serialise_stats() const 627 662 { 628 LOGCALL(MATCH, MSet, "Enquire::Internal::get_mset", first | maxitems | check_at_least | rset | mdecider); 663 return ::serialise_stats(*(stats.get())); 664 } 665 666 void 667 Enquire::Internal::prepare_mset(const RSet *rset, 668 const MatchDecider *mdecider) const 669 { 670 LOGCALL(MATCH, MSet, "Enquire::Internal::prepare_mset", maxitems | rset | mdecider); 629 671 630 672 if (percent_cutoff && (sort_by == VAL || sort_by == VAL_REL)) { 631 673 throw Xapian::UnimplementedError("Use of a percentage cutoff while sorting primary by value isn't currently supported"); 632 674 } 633 675 676 stats.reset(new Xapian::Weight::Internal); 677 match.reset(new ::MultiMatch(db, query, qlen, rset, 678 collapse_max, collapse_key, 679 percent_cutoff, weight_cutoff, 680 order, sort_key, sort_by, sort_value_forward, 681 time_limit, *(stats.get()), weight, spies, 682 (sorter.get() != NULL), 683 (mdecider != NULL))); 684 } 685 686 MSet 687 Enquire::Internal::get_mset(Xapian::doccount first, Xapian::doccount maxitems, 688 Xapian::doccount check_at_least, const RSet *rset, 689 const MatchDecider *mdecider) const 690 { 634 691 if (weight == 0) { 635 692 weight = new BM25Weight; 636 693 } 637 694 638 Xapian::doccount first_orig = first; 639 { 640 Xapian::doccount docs = db.get_doccount(); 641 first = min(first, docs); 642 maxitems = min(maxitems, docs); 643 check_at_least = min(check_at_least, docs); 644 check_at_least = max(check_at_least, maxitems); 695 if (!stats || !match) { 696 prepare_mset(rset, mdecider); 645 697 } 646 698 647 AutoPtr<Xapian::Weight::Internal> stats(new Xapian::Weight::Internal); 648 ::MultiMatch match(db, query, qlen, rset, 649 collapse_max, collapse_key, 650 percent_cutoff, weight_cutoff, 651 order, sort_key, sort_by, sort_value_forward, 652 time_limit, *(stats.get()), weight, spies, 653 (sorter.get() != NULL), 654 (mdecider != NULL)); 655 // Run query and put results into supplied Xapian::MSet object. 656 MSet retval; 657 match.get_mset(first, maxitems, check_at_least, retval, 658 *(stats.get()), mdecider, sorter.get()); 659 if (first_orig != first && retval.internal.get()) { 660 retval.internal->firstitem = first_orig; 661 } 699 try { 700 Xapian::doccount first_orig = first; 701 { 702 Xapian::doccount docs = db.get_doccount(); 703 first = min(first, docs); 704 maxitems = min(maxitems, docs); 705 check_at_least = min(check_at_least, docs); 706 check_at_least = max(check_at_least, maxitems); 707 } 708 709 // Run query and put results into supplied Xapian::MSet object. 710 MSet retval; 711 match->get_mset(first, maxitems, check_at_least, retval, 712 *(stats.get()), mdecider, sorter.get()); 713 if (first_orig != first && retval.internal.get()) { 714 retval.internal->firstitem = first_orig; 715 } 662 716 663 717 Assert(weight->name() != "bool" || retval.get_max_possible() == 0); 664 718 665 666 667 668 669 719 // The Xapian::MSet needs to have a pointer to ourselves, so that it can 720 // retrieve the documents. This is set here explicitly to avoid having 721 // to pass it into the matcher, which gets messy particularly in the 722 // networked case. 723 retval.internal->enquire = this; 670 724 671 if (!retval.internal->stats) { 672 retval.internal->stats = stats.release(); 673 } 725 if (!retval.internal->stats) { 726 retval.internal->stats = stats.release(); 727 } else { 728 stats.reset(); 729 } 730 731 match.reset(); 674 732 675 RETURN(retval); 733 RETURN(retval); 734 } catch(...) { 735 stats.reset(); 736 match.reset(); 737 throw; 738 } 676 739 } 677 740 678 741 ESet … … Enquire::set_time_limit(double time_limit) 1006 1069 internal->time_limit = time_limit; 1007 1070 } 1008 1071 1072 void 1073 Enquire::unserialise_stats(const string& serialised) 1074 { 1075 internal->unserialise_stats(serialised); 1076 } 1077 1078 const string 1079 Enquire::serialise_stats() const 1080 { 1081 RETURN(internal->serialise_stats()); 1082 } 1083 1084 void 1085 Enquire::prepare_mset(const RSet *rset, 1086 const MatchDecider *mdecider) const 1087 { 1088 LOGCALL(API, Xapian::MSet, "Xapian::Enquire::prepare_mset", maxitems | rset | mdecider); 1089 1090 internal->prepare_mset(rset, mdecider); 1091 } 1092 1009 1093 MSet 1010 1094 Enquire::get_mset(Xapian::doccount first, Xapian::doccount maxitems, 1011 1095 Xapian::doccount check_at_least, const RSet *rset, -
xapian-core/api/omenquireinternal.h
diff --git a/xapian-core/api/omenquireinternal.h b/xapian-core/api/omenquireinternal.h index 4b4c902..f1d7c7e 100644
a b 37 37 #include <map> 38 38 #include <set> 39 39 40 #include "autoptr.h" 40 41 #include "weight/weightinternal.h" 41 42 42 43 using namespace std; … … class Enquire::Internal : public Xapian::Internal::intrusive_base { 151 152 152 153 Xapian::Internal::opt_intrusive_ptr<KeyMaker> sorter; 153 154 155 mutable AutoPtr<Xapian::Weight::Internal> stats; 156 mutable AutoPtr<::MultiMatch> match; 157 154 158 double time_limit; 155 159 156 160 /** The weight to use for this query. … … class Enquire::Internal : public Xapian::Internal::intrusive_base { 183 187 184 188 void set_query(const Query & query_, termcount qlen_); 185 189 const Query & get_query() const; 190 191 void unserialise_stats(const string& serialised); 192 const string serialise_stats() const; 193 194 void prepare_mset(const RSet *omrset, 195 const MatchDecider *mdecider) const; 196 186 197 MSet get_mset(Xapian::doccount first, Xapian::doccount maxitems, 187 198 Xapian::doccount check_at_least, 188 199 const RSet *omrset, -
xapian-core/include/xapian/enquire.h
diff --git a/xapian-core/include/xapian/enquire.h b/xapian-core/include/xapian/enquire.h index 09db354..ed7c06b 100644
a b class XAPIAN_VISIBILITY_DEFAULT RSet { 262 262 263 263 /// Return a string describing this object. 264 264 std::string get_description() const; 265 266 /** Serialise RSet into a string. 267 * 268 * The document representation may change between Xapian releases: 269 * even between minor versions. However, it is guaranteed not to 270 * change if the remote database protocol has not changed between 271 * releases. 272 */ 273 std::string serialise() const; 274 275 /** Unserialise a document from a string produced by serialise(). 276 */ 277 static RSet unserialise(const std::string &serialised); 278 265 279 }; 266 280 267 281 /** Base class for matcher decision functor. … … class XAPIAN_VISIBILITY_DEFAULT Enquire { 619 633 */ 620 634 void set_time_limit(double time_limit); 621 635 636 void unserialise_stats(const std::string& serialised); 637 const std::string serialise_stats() const; 638 622 639 /** Get (a portion of) the match set for the current query. 623 640 * 624 641 * @param first the first item in the result set to return. … … class XAPIAN_VISIBILITY_DEFAULT Enquire { 657 674 * 658 675 * @{ 659 676 */ 677 void prepare_mset(const RSet * omrset = 0, 678 const MatchDecider * mdecider = 0) const; 660 679 MSet get_mset(Xapian::doccount first, Xapian::doccount maxitems, 661 680 Xapian::doccount checkatleast = 0, 662 681 const RSet * omrset = 0, -
xapian-core/include/xapian/mset.h
diff --git a/xapian-core/include/xapian/mset.h b/xapian-core/include/xapian/mset.h index de6025d..914c535 100644
a b class XAPIAN_VISIBILITY_DEFAULT MSet { 179 179 /// Return a string describing this object. 180 180 std::string get_description() const; 181 181 182 /** Serialise MSet into a string. 183 * 184 * The document representation may change between Xapian releases: 185 * even between minor versions. However, it is guaranteed not to 186 * change if the remote database protocol has not changed between 187 * releases. 188 */ 189 std::string serialise() const; 190 191 /** Unserialise a document from a string produced by serialise(). 192 */ 193 static MSet unserialise(const std::string &serialised); 194 182 195 /** @private @internal MSet is what the C++ STL calls a container. 183 196 * 184 197 * The following typedefs allow the class to be used in templates in the