Ticket #178: metadata_and_mvcms_register_and_spelling.patch

File metadata_and_mvcms_register_and_spelling.patch, 14.7 KB (added by Paul Rudin, 14 years ago)
  • xapian-core/tests/api_metadata.cc

     
    122122}
    123123
    124124// Test metadata iterators.
    125 DEFINE_TESTCASE(metadata5, writable) {
     125DEFINE_TESTCASE(metadata5, writable && !remote) {
    126126    Xapian::WritableDatabase db = get_writable_database();
    127127
    128128    // Check that iterator on empty database returns nothing.
  • xapian-core/tests/harness/testrunner.cc

     
    5858               "synonyms,replicas,flint" },
    5959    { "multi_flint", "backend,positional,multi" },
    6060    { "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" },
    6569    { NULL, NULL }
    6670};
    6771
  • xapian-core/net/remoteserver.cc

     
    3636#include "multimatch.h"
    3737#include "omassert.h"
    3838#include "omtime.h"
     39#include "ortermlist.h"
     40#include "termlist.h"
    3941#include "serialise.h"
    4042#include "serialise-double.h"
    4143#include "utils.h"
    4244#include "weightinternal.h"
     45#include "database.h" // so we can use internal in msg_openspellingtermlist
    4346
    4447/// Class to throw when we receive the connection closing message.
    4548struct ConnectionClosed { };
     
    185188                &RemoteServer::msg_replacedocumentterm,
    186189                &RemoteServer::msg_deletedocument,
    187190                &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
    188199                // MSG_GETMSET - used during a conversation.
    189200                // MSG_SHUTDOWN - handled by get_message().
    190201            };
     
    658669
    659670    send_message(REPLY_ADDDOCUMENT, encode_length(did));
    660671}
     672
     673
     674void
     675RemoteServer::msg_getmetadata(const string & message)
     676{
     677  send_message(REPLY_METADATA, db->get_metadata(message));
     678}
     679
     680void
     681RemoteServer::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
     694void
     695RemoteServer::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
     706void
     707RemoteServer::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
     717void
     718RemoteServer::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
     727void
     728RemoteServer::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
     735void
     736RemoteServer::msg_openspellingtermlist(const std::string& message)
     737{
     738    spelling_term_or_wordlist(message, false);
     739}
     740
     741void
     742RemoteServer::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
     793void
     794RemoteServer::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

     
    8989
    9090    void update_stats(message_type msg_code = MSG_UPDATE) const;
    9191
     92    // get spelling word or termlist;
     93    TermList * receive_spelling_list(bool) const;
     94
    9295  protected:
    9396    /** Constructor.  The constructor is protected so that raw instances
    9497     *  can't be created - a derived class must be instantiated which
     
    241244                                   const Xapian::Document & document);
    242245
    243246    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;
    244258};
    245 
    246259#endif // XAPIAN_INCLUDED_REMOTE_DATABASE_H
  • xapian-core/common/remoteprotocol.h

     
    7373    MSG_REPLACEDOCUMENTTERM,    // Replace Document by term
    7474    MSG_DELETEDOCUMENT,         // Delete Document
    7575    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
    7684    MSG_GETMSET,                // Get MSet
    7785    MSG_SHUTDOWN,               // Shutdown
    7886    MSG_MAX
     
    100108    REPLY_VALUE,                // Document Value
    101109    REPLY_ADDDOCUMENT,          // Add Document
    102110    REPLY_RESULTS,              // Results (MSet)
     111    REPLY_METADATA,             // Metadata
     112    REPLY_SPELLINGSUGGESTION,   // Get Spelling
     113    REPLY_SPELLINGTERMS,        // Spelling terms
     114    REPLY_SPELLINGFREQ,         // Spelling frequency
    103115    REPLY_MAX
    104116};
    105117
  • xapian-core/common/remoteserver.h

     
    6969    /// The registry, which allows unserialisation of user subclasses.
    7070    Xapian::Registry reg;
    7171
     72    /// construct spelling termlist or wordlist
     73    void spelling_term_or_wordlist (const std::string& message, bool words);
     74
    7275    /// Accept a message from the client.
    7376    message_type get_message(Xapian::timeout timeout, std::string & result,
    7477                             message_type required_type = MSG_MAX);
     
    142145    // replace document with unique term
    143146    void msg_replacedocumentterm(const std::string & message);
    144147
     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
    145172  public:
    146173    /** Construct a RemoteServer.
    147174     *
  • xapian-core/api/registry.cc

     
    194194    Xapian::MatchSpy * spy;
    195195    spy = new Xapian::ValueCountMatchSpy();
    196196    matchspies[spy->name()] = spy;
     197
     198    Xapian::MatchSpy * mvspy;
     199    mvspy = new Xapian::MultiValueCountMatchSpy();
     200    matchspies[mvspy->name()] = mvspy;
    197201}
    198202
    199203void
  • xapian-core/backends/remote/remote-database.cc

     
    723723{
    724724    return uuid;
    725725}
     726
     727string
     728RemoteDatabase::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
     736void
     737RemoteDatabase::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
     745void
     746RemoteDatabase::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
     754void
     755RemoteDatabase::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
     763string
     764RemoteDatabase::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
     776TermList *
     777RemoteDatabase::open_spelling_wordlist() const{
     778    send_message(MSG_OPENSPELLINGWORDLIST, "");
     779    return receive_spelling_list(true);
     780}
     781
     782TermList *
     783RemoteDatabase::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
     789TermList *
     790RemoteDatabase::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
     818Xapian::doccount
     819RemoteDatabase::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}