Ticket #710: 710-remote_protocol_server_on_public_api.diff
File 710-remote_protocol_server_on_public_api.diff, 9.8 KB (added by , 9 years ago) |
---|
-
xapian-core/api/omenquire.cc
commit 2ca6c36627cc0ec16e3c1cc78acb23f461c51577 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..0c31a0c 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 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 662 { 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", rset | mdecider); 671 672 if (percent_cutoff && (sort_by == VAL || sort_by == VAL_REL)) { 673 throw Xapian::UnimplementedError("Use of a percentage cutoff while sorting primary by value isn't currently supported"); 674 } 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 623 686 MSet 624 687 Enquire::Internal::get_mset(Xapian::doccount first, Xapian::doccount maxitems, 625 688 Xapian::doccount check_at_least, const RSet *rset, … … Enquire::Internal::get_mset(Xapian::doccount first, Xapian::doccount maxitems, 644 707 check_at_least = max(check_at_least, maxitems); 645 708 } 646 709 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 } 710 try { 711 if (!stats || !match) { 712 prepare_mset(rset, mdecider); 713 } 662 714 663 Assert(weight->name() != "bool" || retval.get_max_possible() == 0); 715 // Run query and put results into supplied Xapian::MSet object. 716 MSet retval; 717 match->get_mset(first, maxitems, check_at_least, retval, 718 *(stats.get()), mdecider, sorter.get()); 719 if (first_orig != first && retval.internal.get()) { 720 retval.internal->firstitem = first_orig; 721 } 664 722 665 // The Xapian::MSet needs to have a pointer to ourselves, so that it can 666 // retrieve the documents. This is set here explicitly to avoid having 667 // to pass it into the matcher, which gets messy particularly in the 668 // networked case. 669 retval.internal->enquire = this; 723 Assert(weight->name() != "bool" || retval.get_max_possible() == 0); 670 724 671 if (!retval.internal->stats) { 672 retval.internal->stats = stats.release(); 673 } 725 // The Xapian::MSet needs to have a pointer to ourselves, so that it can 726 // retrieve the documents. This is set here explicitly to avoid having 727 // to pass it into the matcher, which gets messy particularly in the 728 // networked case. 729 retval.internal->enquire = this; 730 731 if (!retval.internal->stats) { 732 retval.internal->stats = stats.release(); 733 } else { 734 stats.reset(); 735 } 736 737 match.reset(); 674 738 675 RETURN(retval); 739 RETURN(retval); 740 } catch(...) { 741 stats.reset(); 742 match.reset(); 743 throw; 744 } 676 745 } 677 746 678 747 ESet … … Enquire::set_time_limit(double time_limit) 1006 1075 internal->time_limit = time_limit; 1007 1076 } 1008 1077 1078 void 1079 Enquire::unserialise_stats(const string& serialised) 1080 { 1081 internal->unserialise_stats(serialised); 1082 } 1083 1084 const string 1085 Enquire::serialise_stats() const 1086 { 1087 RETURN(internal->serialise_stats()); 1088 } 1089 1090 void 1091 Enquire::prepare_mset(const RSet *rset, 1092 const MatchDecider *mdecider) const 1093 { 1094 LOGCALL(API, Xapian::MSet, "Xapian::Enquire::prepare_mset", maxitems | rset | mdecider); 1095 1096 internal->prepare_mset(rset, mdecider); 1097 } 1098 1009 1099 MSet 1010 1100 Enquire::get_mset(Xapian::doccount first, Xapian::doccount maxitems, 1011 1101 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