Ticket #178: metadata_and_mvcms_register_and_spelling.patch
File metadata_and_mvcms_register_and_spelling.patch, 14.7 KB (added by , 15 years ago) |
---|
-
xapian-core/tests/api_metadata.cc
122 122 } 123 123 124 124 // Test metadata iterators. 125 DEFINE_TESTCASE(metadata5, writable ) {125 DEFINE_TESTCASE(metadata5, writable && !remote) { 126 126 Xapian::WritableDatabase db = get_writable_database(); 127 127 128 128 // Check that iterator on empty database returns nothing. -
xapian-core/tests/harness/testrunner.cc
58 58 "synonyms,replicas,flint" }, 59 59 { "multi_flint", "backend,positional,multi" }, 60 60 { "multi_chert", "backend,positional,valuestats,multi" }, 61 { "remoteprog_flint", "backend,remote,transactions,positional,writable" }, 62 { "remotetcp_flint", "backend,remote,transactions,positional,writable" }, 63 { "remoteprog_chert", "backend,remote,transactions,positional,valuestats,writable" }, 64 { "remotetcp_chert", "backend,remote,transactions,positional,valuestats,writable" }, 61 { "remoteprog_flint", "backend,remote,transactions,positional,writable," 62 "metadata,spelling" }, 63 { "remotetcp_flint", "backend,remote,transactions,positional,writable," 64 "metadata,spelling" }, 65 { "remoteprog_chert", "backend,remote,transactions,positional,valuestats,writable," 66 "metadata,spelling" }, 67 { "remotetcp_chert", "backend,remote,transactions,positional,valuestats,writable," 68 "metadata,spelling" }, 65 69 { NULL, NULL } 66 70 }; 67 71 -
xapian-core/net/remoteserver.cc
36 36 #include "multimatch.h" 37 37 #include "omassert.h" 38 38 #include "omtime.h" 39 #include "ortermlist.h" 40 #include "termlist.h" 39 41 #include "serialise.h" 40 42 #include "serialise-double.h" 41 43 #include "utils.h" 42 44 #include "weightinternal.h" 45 #include "database.h" // so we can use internal in msg_openspellingtermlist 43 46 44 47 /// Class to throw when we receive the connection closing message. 45 48 struct ConnectionClosed { }; … … 185 188 &RemoteServer::msg_replacedocumentterm, 186 189 &RemoteServer::msg_deletedocument, 187 190 &RemoteServer::msg_writeaccess, 191 &RemoteServer::msg_getmetadata, 192 &RemoteServer::msg_setmetadata, 193 &RemoteServer::msg_addspelling, 194 &RemoteServer::msg_removespelling, 195 &RemoteServer::msg_getspellingsuggestion, 196 &RemoteServer::msg_openspellingtermlist, 197 &RemoteServer::msg_openspellingwordlist, 198 &RemoteServer::msg_getspellingfreq 188 199 // MSG_GETMSET - used during a conversation. 189 200 // MSG_SHUTDOWN - handled by get_message(). 190 201 }; … … 658 669 659 670 send_message(REPLY_ADDDOCUMENT, encode_length(did)); 660 671 } 672 673 674 void 675 RemoteServer::msg_getmetadata(const string & message) 676 { 677 send_message(REPLY_METADATA, db->get_metadata(message)); 678 } 679 680 void 681 RemoteServer::msg_setmetadata(const string & message) 682 { 683 if (!wdb) 684 throw Xapian::InvalidOperationError("Server is read-only"); 685 const char *p = message.data(); 686 const char *p_end = p + message.size(); 687 size_t keylen = decode_length(&p, p_end, false); 688 string key = string(p, keylen); 689 p += keylen; 690 string val = string(p); 691 wdb->set_metadata(key, val); 692 } 693 694 void 695 RemoteServer::msg_addspelling(const string & message) 696 { 697 if (!wdb) 698 throw Xapian::InvalidOperationError("Server is read-only"); 699 const char *p = message.data(); 700 const char *p_end = p + message.size(); 701 Xapian::termcount freq = decode_length(&p, p_end, false); 702 string term = string(p, p_end - p); 703 wdb->add_spelling(term, freq); 704 } 705 706 void 707 RemoteServer::msg_removespelling(const string & message) 708 { 709 if (!wdb) 710 throw Xapian::InvalidOperationError("Server is read-only"); 711 const char *p = message.data(); 712 const char *p_end = p + message.size(); 713 Xapian::termcount freqdec = decode_length(&p, p_end, false); 714 wdb->remove_spelling(string(p, p_end - p), freqdec); 715 } 716 717 void 718 RemoteServer::msg_getspellingsuggestion(const string & message) 719 { 720 const char *p = message.data(); 721 const char *p_end = p + message.size(); 722 size_t dist = decode_length(&p, p_end, false); 723 string word = string(p); 724 send_message(REPLY_SPELLINGSUGGESTION, db->get_spelling_suggestion(word, dist)); 725 } 726 727 void 728 RemoteServer::msg_openspellingwordlist(const std::string& message) 729 730 { 731 // FIXME - we should possibly not be sending the words in one go here? 732 spelling_term_or_wordlist(message, true); 733 } 734 735 void 736 RemoteServer::msg_openspellingtermlist(const std::string& message) 737 { 738 spelling_term_or_wordlist(message, false); 739 } 740 741 void 742 RemoteServer::spelling_term_or_wordlist(const std::string& message, bool words) 743 { 744 745 // this code is basically cut and paste from 746 // Database::get_spelling_suggestion - if I knew where to put stuff 747 // I'd factor out the common code. 748 749 // n.b. this uses internal. Comments up the code suggest this is a 750 // bad thing - but I don't see how we're going to get hold of the 751 // spellings otherwise. 752 753 AutoPtr<TermList> merger; 754 for (size_t i = 0; i < db->internal.size(); ++i) { 755 TermList * tl = (words? 756 db->internal[i]->open_spelling_wordlist() : 757 db->internal[i]->open_spelling_termlist(message)) ; 758 if (tl) { 759 if (merger.get()) { 760 if (words) 761 merger.reset(new OrTermList(merger.release(), tl)); 762 else 763 merger.reset(new FreqAdderOrTermList(merger.release(), tl)); 764 } else { 765 merger.reset(tl); 766 } 767 } 768 } 769 770 string data; 771 int count = 0; 772 // is it OK to send these in one shot? 773 if (merger.get()) { 774 while (true) { 775 TermList * t = merger->next(); 776 if (t) merger.reset(t); 777 if (merger->at_end()) break; 778 string termname = merger->get_termname(); 779 data += encode_length(termname.length()); 780 data += termname; 781 Xapian::termcount score = (words? 782 merger->get_termfreq(): 783 merger->get_wdf()); 784 data += encode_length(score); 785 ++count; 786 } 787 } 788 789 send_message(REPLY_SPELLINGTERMS, encode_length(count)+data) ; 790 } 791 792 793 void 794 RemoteServer::msg_getspellingfreq(const string & message) 795 { 796 Xapian::doccount freq = 0; 797 for (size_t j = 0; j < db->internal.size(); ++j) 798 freq += db->internal[j]->get_spelling_frequency(message); 799 send_message(REPLY_SPELLINGFREQ, encode_length(freq)); 800 } -
xapian-core/common/remote-database.h
89 89 90 90 void update_stats(message_type msg_code = MSG_UPDATE) const; 91 91 92 // get spelling word or termlist; 93 TermList * receive_spelling_list(bool) const; 94 92 95 protected: 93 96 /** Constructor. The constructor is protected so that raw instances 94 97 * can't be created - a derived class must be instantiated which … … 241 244 const Xapian::Document & document); 242 245 243 246 std::string get_uuid() const; 247 248 string get_metadata(const string & key) const; 249 void set_metadata(const string & key, const string & value); 250 string get_spelling_suggestion(const string &word, 251 unsigned max_edit_distance); 252 TermList * open_spelling_termlist(const string& word) const; 253 TermList * open_spelling_wordlist() const; 254 255 void add_spelling(const std::string&, Xapian::termcount) const; 256 void remove_spelling(const std::string&, Xapian::termcount freqdec) const; 257 Xapian::doccount get_spelling_frequency(const string & word) const; 244 258 }; 245 246 259 #endif // XAPIAN_INCLUDED_REMOTE_DATABASE_H -
xapian-core/common/remoteprotocol.h
73 73 MSG_REPLACEDOCUMENTTERM, // Replace Document by term 74 74 MSG_DELETEDOCUMENT, // Delete Document 75 75 MSG_WRITEACCESS, // Upgrade to WritableDatabase 76 MSG_GETMETADATA, // get metadata 77 MSG_SETMETADATA, // set metadata 78 MSG_ADDSPELLING, // add a spelling 79 MSG_REMOVESPELLING, // add a spelling 80 MSG_GETSPELLINGSUGGESTION, // get a spelling suggestion 81 MSG_OPENSPELLINGTERMLIST, // get spelling termlist 82 MSG_OPENSPELLINGWORDLIST, // get spelling wordlist 83 MSG_GETSPELLINGFREQ, // get spelling frequency 76 84 MSG_GETMSET, // Get MSet 77 85 MSG_SHUTDOWN, // Shutdown 78 86 MSG_MAX … … 100 108 REPLY_VALUE, // Document Value 101 109 REPLY_ADDDOCUMENT, // Add Document 102 110 REPLY_RESULTS, // Results (MSet) 111 REPLY_METADATA, // Metadata 112 REPLY_SPELLINGSUGGESTION, // Get Spelling 113 REPLY_SPELLINGTERMS, // Spelling terms 114 REPLY_SPELLINGFREQ, // Spelling frequency 103 115 REPLY_MAX 104 116 }; 105 117 -
xapian-core/common/remoteserver.h
69 69 /// The registry, which allows unserialisation of user subclasses. 70 70 Xapian::Registry reg; 71 71 72 /// construct spelling termlist or wordlist 73 void spelling_term_or_wordlist (const std::string& message, bool words); 74 72 75 /// Accept a message from the client. 73 76 message_type get_message(Xapian::timeout timeout, std::string & result, 74 77 message_type required_type = MSG_MAX); … … 142 145 // replace document with unique term 143 146 void msg_replacedocumentterm(const std::string & message); 144 147 148 // get metadata 149 void msg_getmetadata(const std::string & message); 150 151 // set metadata 152 void msg_setmetadata(const std::string & message); 153 154 // add a spelling 155 void msg_addspelling(const std::string & message); 156 157 // remove a spelling 158 void msg_removespelling(const std::string & message); 159 160 // get spellings 161 void msg_getspellingsuggestion(const std::string & message); 162 163 // open spelling termlist 164 void msg_openspellingtermlist(const std::string&); 165 166 // open spelling wordlist 167 void msg_openspellingwordlist(const std::string&); 168 169 // get spelling frequency 170 void msg_getspellingfreq(const std::string&); 171 145 172 public: 146 173 /** Construct a RemoteServer. 147 174 * -
xapian-core/api/registry.cc
194 194 Xapian::MatchSpy * spy; 195 195 spy = new Xapian::ValueCountMatchSpy(); 196 196 matchspies[spy->name()] = spy; 197 198 Xapian::MatchSpy * mvspy; 199 mvspy = new Xapian::MultiValueCountMatchSpy(); 200 matchspies[mvspy->name()] = mvspy; 197 201 } 198 202 199 203 void -
xapian-core/backends/remote/remote-database.cc
723 723 { 724 724 return uuid; 725 725 } 726 727 string 728 RemoteDatabase::get_metadata(const string & key) const 729 { 730 send_message(MSG_GETMETADATA, key); 731 string metadata; 732 get_message(metadata, REPLY_METADATA); 733 return metadata; 734 } 735 736 void 737 RemoteDatabase::set_metadata(const string & key, const string & value) 738 { 739 string data = encode_length(key.size()); 740 data += key; 741 data += value; 742 send_message(MSG_SETMETADATA, data); 743 } 744 745 void 746 RemoteDatabase::add_spelling(const std::string & word, 747 Xapian::termcount freqinc) const 748 { 749 string data = encode_length(freqinc); 750 data += word; 751 send_message(MSG_ADDSPELLING, data); 752 } 753 754 void 755 RemoteDatabase::remove_spelling(const std::string & word, 756 Xapian::termcount freqdec) const 757 { 758 string data = encode_length(freqdec); 759 data += word; 760 send_message(MSG_REMOVESPELLING, data); 761 } 762 763 string 764 RemoteDatabase::get_spelling_suggestion(const string & word, 765 unsigned max_edit_distance) 766 { 767 string data = encode_length(max_edit_distance); 768 data += word; 769 send_message(MSG_GETSPELLINGSUGGESTION, data); 770 771 string message; 772 get_message(message, REPLY_SPELLINGSUGGESTION); 773 return message; 774 } 775 776 TermList * 777 RemoteDatabase::open_spelling_wordlist() const{ 778 send_message(MSG_OPENSPELLINGWORDLIST, ""); 779 return receive_spelling_list(true); 780 } 781 782 TermList * 783 RemoteDatabase::open_spelling_termlist(const string& word) const { 784 send_message(MSG_OPENSPELLINGTERMLIST, word); 785 // FIXME - gets them all - probably not what's wanted? 786 return receive_spelling_list(false); 787 } 788 789 TermList * 790 RemoteDatabase::receive_spelling_list(bool words) const { 791 string message; 792 get_message(message, REPLY_SPELLINGTERMS); 793 const char * p = message.data(); 794 const char * p_end = p + message.size(); 795 int item_count = decode_length(&p, p_end, false); 796 AutoPtr<NetworkTermList> tlist( 797 new NetworkTermList(0, item_count, 798 Xapian::Internal::RefCntPtr<const RemoteDatabase>(this), 799 0)); 800 vector<NetworkTermListItem> & items = tlist->items; 801 802 while (p < p_end) { 803 size_t tlen = decode_length(&p, p_end, false); 804 NetworkTermListItem item; 805 item.tname.assign(p, tlen); 806 p += tlen; 807 Xapian::termcount score = decode_length(&p, p_end, false); 808 if (words) 809 item.termfreq = score; 810 else 811 item.wdf = score; 812 items.push_back(item); 813 } 814 tlist->current_position = tlist->items.begin(); 815 return tlist.release(); 816 } 817 818 Xapian::doccount 819 RemoteDatabase::get_spelling_frequency(const string & word) const 820 { 821 send_message(MSG_GETSPELLINGFREQ, word); 822 string message; 823 get_message(message, REPLY_SPELLINGFREQ); 824 const char * p = message.data(); 825 const char * p_end = p + message.size(); 826 Xapian::doccount freq = decode_length(&p, p_end, false); 827 return freq; 828 }