Ticket #38: xapian-remote-postlist.patch
| File xapian-remote-postlist.patch, 10.1 kB (added by richard, 21 months ago) |
|---|
-
net/remoteserver.cc
139 139 { 140 140 while (true) { 141 141 try { 142 /* This list needs to be kept in the same order as the list of 143 * message types in "remoteprotocol.h". Note that messages at the 144 * end of the list in "remoteprotocol.h" can be omitted if they 145 * don't correspond to dispatch actions. 146 */ 142 147 static const dispatch_func dispatch[] = { 143 148 &RemoteServer::msg_allterms, 144 149 &RemoteServer::msg_collfreq, … … 150 155 &RemoteServer::msg_query, 151 156 &RemoteServer::msg_termlist, 152 157 &RemoteServer::msg_positionlist, 158 &RemoteServer::msg_postlist, 153 159 &RemoteServer::msg_reopen, 154 160 &RemoteServer::msg_update, 155 161 &RemoteServer::msg_adddocument, … … 223 229 Xapian::docid did = decode_length(&p, p_end, false); 224 230 string term(p, p_end - p); 225 231 226 int N = 0;227 232 Xapian::termpos lastpos = static_cast<Xapian::termpos>(-1); 228 233 const Xapian::PositionIterator end = db->positionlist_end(did, term); 229 234 for (Xapian::PositionIterator i = db->positionlist_begin(did, term); … … 231 236 Xapian::termpos pos = *i; 232 237 send_message(REPLY_POSITIONLIST, encode_length(pos - lastpos - 1)); 233 238 lastpos = pos; 234 ++N;235 239 } 236 240 237 241 send_message(REPLY_DONE, ""); 238 242 } 239 243 240 244 void 245 RemoteServer::msg_postlist(const string &message) 246 { 247 const char *p = message.data(); 248 const char *p_end = p + message.size(); 249 string term(p, p_end - p); 250 251 Xapian::doccount termfreq = db->get_termfreq(term); 252 send_message(REPLY_POSTLISTSTART, encode_length(termfreq)); 253 254 Xapian::docid lastdocid = static_cast<Xapian::termpos>(0); 255 const Xapian::PostingIterator end = db->postlist_end(term); 256 for (Xapian::PostingIterator i = db->postlist_begin(term); 257 i != end; ++i) { 258 259 Xapian::docid newdocid = *i; 260 string reply = encode_length(newdocid - lastdocid - 1); 261 reply += encode_length(i.get_wdf()); 262 // FIXME: get_doclength should always return an integer, but 263 // Xapian::doclength is a double... 264 reply += serialise_double(i.get_doclength()); 265 266 send_message(REPLY_POSTLISTITEM, reply); 267 lastdocid = newdocid; 268 } 269 270 send_message(REPLY_DONE, ""); 271 } 272 273 void 241 274 RemoteServer::msg_reopen(const string & msg) 242 275 { 243 276 db->reopen(); -
common/remote-database.h
33 33 } 34 34 35 35 class Stats; 36 class NetworkPostList; 36 37 37 38 /** RemoteDatabase is the baseclass for remote database implementations. 38 39 * … … 161 162 162 163 LeafPostList * do_open_post_list(const string & tname) const; 163 164 165 void read_post_list(const string &term, NetworkPostList & pl) const; 166 164 167 PositionList * open_position_list(Xapian::docid did, 165 168 const string & tname) const; 166 169 -
common/remoteprotocol.h
28 28 // 24: Support for OP_VALUE_RANGE in query serialisation 29 29 // 25: Support for delete_document and replace_document with unique term 30 30 // 26: Tweak delete_document with unique term; delta encode rset and termpos 31 #define XAPIAN_REMOTE_PROTOCOL_VERSION 26 31 // 27: Support for postlists (always passes the whole list across) 32 #define XAPIAN_REMOTE_PROTOCOL_VERSION 27 32 33 33 34 /// Message types (client -> server). 34 35 enum message_type { … … 42 43 MSG_QUERY, // Run Query 43 44 MSG_TERMLIST, // Get TermList 44 45 MSG_POSITIONLIST, // Get PositionList 46 MSG_POSTLIST, // Get PostList 45 47 MSG_REOPEN, // Reopen 46 48 MSG_UPDATE, // Get Updated DocCount and AvLength 47 49 MSG_ADDDOCUMENT, // Add Document … … 72 74 REPLY_STATS, // Stats 73 75 REPLY_TERMLIST, // Get Termlist 74 76 REPLY_POSITIONLIST, // Get PositionList 77 REPLY_POSTLISTSTART, // Start of a postlist 78 REPLY_POSTLISTITEM, // Item in body of a postlist 75 79 REPLY_UPDATE, // Get Updated DocCount and AvLength 76 80 REPLY_VALUE, // Document Value 77 81 REPLY_ADDDOCUMENT, // Add Document -
common/remoteserver.h
103 103 // get termlist 104 104 void msg_termlist(const std::string & message); 105 105 106 // get postlist 107 void msg_postlist(const std::string & message); 108 106 109 // get positionlist 107 110 void msg_positionlist(const std::string &message); 108 111 -
backends/remote/remote-database.cc
26 26 #include <xapian/error.h> 27 27 28 28 #include "inmemory_positionlist.h" 29 #include "net_postlist.h" 29 30 #include "net_termlist.h" 30 31 #include "net_document.h" 31 32 #include "omassert.h" … … 173 174 } 174 175 175 176 LeafPostList * 176 RemoteDatabase::do_open_post_list(const string & ) const177 RemoteDatabase::do_open_post_list(const string &term) const 177 178 { 178 throw Xapian::UnimplementedError("RemoteDatabase::do_open_post_list not implemented"); 179 AutoPtr<NetworkPostList> plist; 180 return new NetworkPostList(Xapian::Internal::RefCntPtr<const RemoteDatabase>(this), term); 179 181 } 180 182 183 void 184 RemoteDatabase::read_post_list(const string &term, NetworkPostList & pl) const 185 { 186 send_message(MSG_POSTLIST, term); 187 188 string message; 189 char type; 190 get_message(message, REPLY_POSTLISTSTART); 191 192 const char * p = message.data(); 193 const char * p_end = p + message.size(); 194 pl.initialise(decode_length(&p, p_end, false)); 195 196 while ((type = get_message(message)) == REPLY_POSTLISTITEM) { 197 pl.append_posting(message); 198 } 199 if (type != REPLY_DONE) { 200 throw Xapian::NetworkError("Bad message received", context); 201 } 202 } 203 181 204 PositionList * 182 205 RemoteDatabase::open_position_list(Xapian::docid did, const string &term) const 183 206 { -
backends/remote/Makefile.mk
5 5 if BUILD_BACKEND_REMOTE 6 6 noinst_HEADERS +=\ 7 7 backends/remote/net_document.h\ 8 backends/remote/net_postlist.h\ 8 9 backends/remote/net_termlist.h 9 10 10 11 libxapian_la_SOURCES +=\ -
backends/remote/net_postlist.h
1 /* net_postlist.h 2 * 3 * Copyright 2007 Lemur Consulting Ltd 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 18 * USA 19 */ 20 21 #ifndef OM_HGUARD_NET_POSTLIST_H 22 #define OM_HGUARD_NET_POSTLIST_H 23 24 #include <string> 25 26 #include "leafpostlist.h" 27 #include "remote-database.h" 28 #include "serialise.h" 29 #include "serialise-double.h" 30 31 using namespace std; 32 33 /** A postlist in a remote database. 34 */ 35 class NetworkPostList : public LeafPostList { 36 private: 37 friend class RemoteDatabase; 38 Xapian::Internal::RefCntPtr<const RemoteDatabase> db; 39 string term; 40 41 string postings; 42 bool started; 43 const char * pos; 44 const char * pos_end; 45 46 Xapian::docid lastdocid; 47 Xapian::termcount lastwdf; 48 Xapian::doclength lastdoclen; 49 Xapian::Internal::RefCntPtr<PositionList> lastposlist; 50 51 Xapian::doccount termfreq; 52 53 void initialise(Xapian::doccount termfreq_) { 54 termfreq = termfreq_; 55 } 56 57 void append_posting(const string & serialised) 58 { 59 Assert(pos == NULL); 60 Assert(!started); 61 postings.append(serialised); 62 } 63 64 public: 65 NetworkPostList(Xapian::Internal::RefCntPtr<const RemoteDatabase> db_, 66 const string & term_) 67 : db(db_), 68 term(term_), 69 started(false), 70 pos(NULL), 71 pos_end(NULL), 72 lastdocid(0), 73 lastwdf(0), 74 lastdoclen(0), 75 termfreq(0) 76 { 77 db->read_post_list(term, *this); 78 } 79 80 Xapian::doccount get_termfreq() const 81 { 82 return termfreq; 83 } 84 85 Xapian::docid get_docid() const 86 { 87 return lastdocid; 88 } 89 90 Xapian::doclength get_doclength() const 91 { 92 return lastdoclen; 93 } 94 95 Xapian::termcount get_wdf() const 96 { 97 return lastwdf; 98 } 99 100 PositionList * read_position_list() 101 { 102 lastposlist = db->open_position_list(lastdocid, term); 103 return lastposlist.get(); 104 } 105 106 PositionList * open_position_list() const 107 { 108 return db->open_position_list(lastdocid, term); 109 } 110 111 PostList * next(Xapian::weight) 112 { 113 if (!started) { 114 started = true; 115 pos = postings.data(); 116 pos_end = pos + postings.size(); 117 lastdocid = 0; 118 } 119 120 if (pos == pos_end) { 121 pos = NULL; 122 } else { 123 lastdocid += decode_length(&pos, pos_end, false) + 1; 124 lastwdf = decode_length(&pos, pos_end, false); 125 lastdoclen = unserialise_double(&pos, pos_end); 126 } 127 128 return NULL; 129 } 130 131 PostList *skip_to(Xapian::docid did, Xapian::weight weight) 132 { 133 if (pos == NULL) 134 next(weight); 135 while (pos != pos_end && lastdocid < did) 136 next(weight); 137 return NULL; 138 } 139 140 bool at_end() const 141 { 142 return (pos == NULL && started); 143 } 144 145 string get_description() const 146 { 147 return "NetworkPostList(" + term + ")"; 148 } 149 }; 150 151 #endif /* OM_HGUARD_NET_POSTLIST_H */
