Ticket #206: serialisationcontext4.patch

File serialisationcontext4.patch, 31.5 KB (added by Richard Boulton, 15 years ago)

Patch with tests, ready to apply I think

  • xapian-core/tests/api_serialise.cc

     
    182182
    183183    return true;
    184184}
     185
     186// Test for serialising a query which contains a PostingSource.
     187DEFINE_TESTCASE(serialise_query2, !backend) {
     188    Xapian::ValueWeightPostingSource s1(10);
     189    Xapian::Query q(&s1);
     190    Xapian::Query q2 = Xapian::Query::unserialise(q.serialise());
     191    TEST_EQUAL(q.get_description(), q2.get_description());
     192    TEST_EQUAL(q.get_description(), "Xapian::Query(PostingSource(Xapian::ValueWeightPostingSource(slot=10)))");
     193
     194    Xapian::ValueMapPostingSource s2(11);
     195    s2.set_default_weight(5.0);
     196    q = Xapian::Query(&s2);
     197    q2 = Xapian::Query::unserialise(q.serialise());
     198    TEST_EQUAL(q.get_description(), q2.get_description());
     199    TEST_EQUAL(q.get_description(), "Xapian::Query(PostingSource(Xapian::ValueMapPostingSource(slot=11)))");
     200
     201    Xapian::FixedWeightPostingSource s3(5.5);
     202    q = Xapian::Query(&s3);
     203    q2 = Xapian::Query::unserialise(q.serialise());
     204    TEST_EQUAL(q.get_description(), q2.get_description());
     205    TEST_EQUAL(q.get_description(), "Xapian::Query(PostingSource(Xapian::FixedWeightPostingSource(wt=5.5)))");
     206
     207    return true;
     208}
     209
     210// Test for unserialising a query using the default context.
     211DEFINE_TESTCASE(serialise_query3, !backend) {
     212    Xapian::ValueWeightPostingSource s1(10);
     213    Xapian::Query q(&s1);
     214    Xapian::SerialisationContext ctx;
     215    Xapian::Query q2 = Xapian::Query::unserialise(q.serialise(), ctx);
     216    TEST_EQUAL(q.get_description(), q2.get_description());
     217    TEST_EQUAL(q.get_description(), "Xapian::Query(PostingSource(Xapian::ValueWeightPostingSource(slot=10)))");
     218
     219    Xapian::ValueMapPostingSource s2(11);
     220    s2.set_default_weight(5.0);
     221    q = Xapian::Query(&s2);
     222    q2 = Xapian::Query::unserialise(q.serialise(), ctx);
     223    TEST_EQUAL(q.get_description(), q2.get_description());
     224    TEST_EQUAL(q.get_description(), "Xapian::Query(PostingSource(Xapian::ValueMapPostingSource(slot=11)))");
     225
     226    Xapian::FixedWeightPostingSource s3(5.5);
     227    q = Xapian::Query(&s3);
     228    q2 = Xapian::Query::unserialise(q.serialise(), ctx);
     229    TEST_EQUAL(q.get_description(), q2.get_description());
     230    TEST_EQUAL(q.get_description(), "Xapian::Query(PostingSource(Xapian::FixedWeightPostingSource(wt=5.5)))");
     231
     232    return true;
     233}
     234
     235class MyPostingSource2 : public Xapian::ValuePostingSource {
     236    std::string desc;
     237  public:
     238    MyPostingSource2(const std::string & desc_)
     239            : Xapian::ValuePostingSource(0), desc(desc_)
     240    {
     241    }
     242
     243    MyPostingSource2 * clone() const
     244    {
     245        return new MyPostingSource2(desc);
     246    }
     247
     248    std::string name() const {
     249        return "MyPostingSource2";
     250    }
     251
     252    std::string serialise() const {
     253        return desc;
     254    }
     255
     256    MyPostingSource2 * unserialise(const std::string & s) const {
     257        return new MyPostingSource2(s);
     258    }
     259
     260    Xapian::weight get_weight() const { return 1.0; }
     261
     262    std::string get_description() const {
     263        return "MyPostingSource2(" + desc + ")";
     264    }
     265};
     266
     267// Test for unserialising a query which contains a custom PostingSource.
     268DEFINE_TESTCASE(serialise_query4, !backend) {
     269    MyPostingSource2 s1("foo");
     270    Xapian::Query q(&s1);
     271    TEST_EQUAL(q.get_description(), "Xapian::Query(PostingSource(MyPostingSource2(foo)))");
     272    std::string serialised = q.serialise();
     273
     274    TEST_EXCEPTION(Xapian::InvalidArgumentError, Xapian::Query::unserialise(serialised));
     275    Xapian::SerialisationContext ctx;
     276    TEST_EXCEPTION(Xapian::InvalidArgumentError, Xapian::Query::unserialise(serialised, ctx));
     277
     278    ctx.register_posting_source(s1);
     279    Xapian::Query q2 = Xapian::Query::unserialise(serialised, ctx);
     280    TEST_EQUAL(q.get_description(), q2.get_description());
     281
     282    return true;
     283}
  • xapian-core/tests/internaltest.cc

     
    452452        Xapian::Query::Internal * qint;
    453453
    454454        s = query->internal->serialise();
    455         map<string, Xapian::PostingSource *> m;
    456         qint = Xapian::Query::Internal::unserialise(s, m);
     455        Xapian::SerialisationContext ctx;
     456        qint = Xapian::Query::Internal::unserialise(s, ctx);
    457457
    458458        TEST(qint->serialise() == s);
    459459        delete qint;
  • xapian-core/bin/xapian-tcpsrv.cc

     
    4040    (void)server; // Suppress "unused parameter" warning.
    4141    // If you have defined your own weighting scheme, register it here
    4242    // like so:
    43     // server.register_weighting_scheme(FooWeight());
     43    // SerialisationContext ctx;
     44    // ctx.register_weighting_scheme(FooWeight());
     45    // server.set_context(ctx);
    4446}
    4547
    4648const int MSECS_IDLE_TIMEOUT_DEFAULT = 60000;
  • xapian-core/include/xapian/query.h

     
    2525#ifndef XAPIAN_INCLUDED_QUERY_H
    2626#define XAPIAN_INCLUDED_QUERY_H
    2727
    28 #include <map>
    2928#include <string>
    3029#include <vector>
    3130
     
    4544namespace Xapian {
    4645
    4746class PostingSource;
     47class SerialisationContext;
    4848
    4949/** Class representing a query.
    5050 *
     
    258258        std::string serialise() const;
    259259
    260260        /** Unserialise a query from a string produced by serialise().
    261          *  FIXME - need to add a way to register posting sources.  See ticket #206
     261         *
     262         *  This method will fail if the query contains any external
     263         *  PostingSource leaf nodes.
     264         *
     265         *  @param s The string representing the serialised query.
    262266         */
    263267        static Query unserialise(const std::string &s);
    264268
     269        /** Unserialise a query from a string produced by serialise().
     270         *
     271         *  The supplied context will be used to unserialise any external
     272         *  PostingSource leaf nodes.
     273         *
     274         *  @param s The string representing the serialised query.
     275         *  @param ctx A context to use when unserialising the query.
     276         */
     277        static Query unserialise(const std::string & s, const SerialisationContext & ctx);
     278
    265279        /// Return a string describing this object.
    266280        std::string get_description() const;
    267281
     
    433447        ~Internal();
    434448
    435449        static Xapian::Query::Internal * unserialise(const std::string &s,
    436                 const std::map<std::string, Xapian::PostingSource *> &sources);
     450                                                     const SerialisationContext & ctx);
    437451
    438452        /** Add a subquery.
    439453         */
  • xapian-core/include/xapian/enquire.h

     
    10121012
    10131013namespace Xapian {
    10141014
     1015class SerialisationContext;
     1016
    10151017/// Abstract base class for weighting schemes
    10161018class XAPIAN_VISIBILITY_DEFAULT Weight {
    10171019    friend class Enquire; // So Enquire can clone us
    10181020    friend class ::RemoteServer; // So RemoteServer can clone us - FIXME
     1021    friend class SerialisationContext;
    10191022    friend class ::ScaleWeight;
    10201023    public:
    10211024        class Internal;
  • xapian-core/include/xapian/serialisationcontext.h

     
     1/** @file serialisationcontext.h
     2 * @brief Context for looking up objects during unserialisation.
     3 */
     4/* Copyright 2009 Lemur Consulting Ltd
     5 *
     6 * This program is free software; you can redistribute it and/or
     7 * modify it under the terms of the GNU General Public License as
     8 * published by the Free Software Foundation; either version 2 of the
     9 * License, or (at your option) any later version.
     10 *
     11 * This program is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU General Public License
     17 * along with this program; if not, write to the Free Software
     18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
     19 * USA
     20 */
     21
     22#ifndef XAPIAN_INCLUDED_SERIALISATIONCONTEXT_H
     23#define XAPIAN_INCLUDED_SERIALISATIONCONTEXT_H
     24
     25#include <xapian/base.h>
     26#include <xapian/visibility.h>
     27#include <string>
     28
     29namespace Xapian {
     30
     31// Forward declarations.
     32class Weight;
     33class PostingSource;
     34
     35/** A context for serialisation.
     36 *
     37 *  This context is used to look up weighting schemes and posting sources when
     38 *  unserialising.
     39 */
     40class XAPIAN_VISIBILITY_DEFAULT SerialisationContext {
     41  public:
     42    /// Class holding details of the context.
     43    class Internal;
     44
     45  private:
     46    /// @internal Reference counted internals.
     47    Xapian::Internal::RefCntPtr<Internal> internal;
     48
     49  public:
     50
     51    /** Copy the context.
     52     *
     53     *  The internals are reference counted, so copying is cheap.
     54     */
     55    SerialisationContext(const SerialisationContext & other);
     56
     57    /** Assign to the context - the copy is shallow.
     58     *
     59     *  The internals are reference counted, so assignment is cheap.
     60     */
     61    SerialisationContext & operator=(const SerialisationContext & other);
     62
     63    /** Default constructor: makes a context with default settings.
     64     *
     65     *  The context will contain all standard weighting schemes and
     66     *  posting sources.
     67     */
     68    SerialisationContext();
     69
     70    ~SerialisationContext();
     71
     72    /** Register a weighting scheme with the context.
     73     */
     74    void register_weighting_scheme(const Xapian::Weight &wt);
     75
     76    /** Get a weighting scheme given a name.
     77     *
     78     *  The returned weighting scheme is owned by the context object.
     79     *
     80     *  Returns NULL if the weighting scheme could not be found.
     81     */
     82    const Xapian::Weight *
     83            get_weighting_scheme(const std::string & name) const;
     84
     85    /** Register a user-defined posting source class.
     86     */
     87    void register_posting_source(const Xapian::PostingSource &source);
     88
     89    /** Get a posting source given a name.
     90     *
     91     *  The returned posting source is owned by the context object.
     92     *
     93     *  Returns NULL if the posting source could not be found.
     94     */
     95    const Xapian::PostingSource *
     96            get_posting_source(const std::string & name) const;
     97};
     98
     99}
     100
     101#endif /* XAPIAN_INCLUDED_SERIALISATIONCONTEXT_H */
  • xapian-core/include/Makefile.mk

    Property changes on: xapian-core/include/xapian/serialisationcontext.h
    ___________________________________________________________________
    Name: svn:eol-style
       + native
    
     
    2525        include/xapian/query.h\
    2626        include/xapian/queryparser.h\
    2727        include/xapian/replication.h\
     28        include/xapian/serialisationcontext.h\
    2829        include/xapian/sorter.h\
    2930        include/xapian/stem.h\
    3031        include/xapian/termgenerator.h\
  • xapian-core/include/xapian.h

     
    5454// Stemming
    5555#include <xapian/stem.h>
    5656
     57// Serialisation support
     58#include <xapian/serialisationcontext.h>
     59
    5760// Unicode support
    5861#include <xapian/unicode.h>
    5962
  • xapian-core/net/remoteserver.cc

     
    3232#include <stdlib.h>
    3333
    3434#include "autoptr.h"
     35#include "serialisationcontextinternal.h"
    3536#include "multimatch.h"
    3637#include "omassert.h"
    3738#include "omtime.h"
     
    105106    message += encode_length(uuid.size());
    106107    message += uuid;
    107108    send_message(REPLY_GREETING, message);
    108 
    109     // Register weighting schemes.
    110     Xapian::Weight * weight;
    111     weight = new Xapian::BM25Weight;
    112     wtschemes[weight->name()] = weight;
    113     weight = new Xapian::BoolWeight;
    114     wtschemes[weight->name()] = weight;
    115     weight = new Xapian::TradWeight;
    116     wtschemes[weight->name()] = weight;
    117 
    118     Xapian::PostingSource * source;
    119     source = new Xapian::ValueWeightPostingSource(0);
    120     postingsources[source->name()] = source;
    121     source = new Xapian::ValueMapPostingSource(0);
    122     postingsources[source->name()] = source;
    123     source = new Xapian::FixedWeightPostingSource(0.0);
    124     postingsources[source->name()] = source;
    125109}
    126110
    127111RemoteServer::~RemoteServer()
    128112{
    129113    delete db;
    130114    // wdb is either NULL or equal to db, so we shouldn't delete it too!
    131 
    132     {
    133         map<string, Xapian::Weight*>::const_iterator i;
    134         for (i = wtschemes.begin(); i != wtschemes.end(); ++i) {
    135             delete i->second;
    136         }
    137     }
    138 
    139     {
    140         map<string, Xapian::PostingSource *>::const_iterator i;
    141         for (i = postingsources.begin(); i != postingsources.end(); ++i) {
    142             delete i->second;
    143         }
    144     }
    145115}
    146116
    147117message_type
     
    382352
    383353    // Unserialise the Query.
    384354    len = decode_length(&p, p_end, true);
    385     AutoPtr<Xapian::Query::Internal> query(Xapian::Query::Internal::unserialise(string(p, len), postingsources));
     355    AutoPtr<Xapian::Query::Internal> query(Xapian::Query::Internal::unserialise(string(p, len), ctx));
    386356    p += len;
    387357
    388358    // Unserialise assorted Enquire settings.
     
    421391
    422392    // Unserialise the Weight object.
    423393    len = decode_length(&p, p_end, true);
    424     map<string, Xapian::Weight *>::const_iterator i;
    425     i = wtschemes.find(string(p, len));
    426     if (i == wtschemes.end()) {
    427         throw Xapian::InvalidArgumentError("Weighting scheme " + string(p, len) + " not registered");
     394    const Xapian::Weight * wttype = ctx.get_weighting_scheme(string(p, len));
     395    if (wttype == NULL) {
     396        // Note: user weighting schemes should be registered by adding them to
     397        // a SerialisationContext, and setting the context using
     398        // RemoteServer::set_context().
     399        throw Xapian::InvalidArgumentError("Weighting scheme " +
     400                                           string(p, len) + " not registered");
    428401    }
    429402    p += len;
    430403
    431404    len = decode_length(&p, p_end, true);
    432     AutoPtr<Xapian::Weight> wt(i->second->unserialise(string(p, len)));
     405    AutoPtr<Xapian::Weight> wt(wttype->unserialise(string(p, len)));
    433406    p += len;
    434407
    435408    // Unserialise the RSet object.
     
    627600
    628601    send_message(REPLY_ADDDOCUMENT, encode_length(did));
    629602}
    630 
    631 
    632 void
    633 RemoteServer::register_posting_source(const Xapian::PostingSource &source)
    634 {
    635     if (source.name().empty()) {
    636         throw Xapian::InvalidOperationError("Unable to register posting source - name() method returns empty string.");
    637     }
    638     Xapian::PostingSource * sourceclone = source.clone();
    639     if (!sourceclone) {
    640         throw Xapian::InvalidOperationError("Unable to register posting source - clone() method returns NULL.");
    641     }
    642     try {
    643         postingsources[source.name()] = sourceclone;
    644     } catch(...) {
    645         delete sourceclone;
    646         throw;
    647     }
    648 }
  • xapian-core/common/Makefile.mk

     
    5050        common/safeuuid.h\
    5151        common/safewindows.h\
    5252        common/safewinsock2.h\
     53        common/serialisationcontextinternal.h\
    5354        common/serialise-double.h\
    5455        common/serialise.h\
    5556        common/socket_utils.h\
  • xapian-core/common/remoteserver.h

     
    2222#ifndef XAPIAN_INCLUDED_REMOTESERVER_H
    2323#define XAPIAN_INCLUDED_REMOTESERVER_H
    2424
     25#include "xapian/serialisationcontext.h"
    2526#include "xapian/database.h"
    2627#include "xapian/enquire.h"
    2728#include "xapian/postingsource.h"
     
    6566     */
    6667    Xapian::timeout idle_timeout;
    6768
    68     /// Registered weighting schemes.
    69     map<string, Xapian::Weight *> wtschemes;
     69    /** The context, used for registering weight schemes and posting
     70     *  sources.
     71     */
     72    Xapian::SerialisationContext ctx;
    7073
    71     /// Registered external posting sources.
    72     map<string, Xapian::PostingSource *> postingsources;
    73 
    7474    /// Accept a message from the client.
    7575    message_type get_message(Xapian::timeout timeout, string & result,
    7676                             message_type required_type = MSG_MAX);
     
    170170     */
    171171    void run();
    172172
    173     /// Register a user-defined weighting scheme class.
    174     void register_weighting_scheme(const Xapian::Weight &wt) {
    175         wtschemes[wt.name()] = wt.clone();
     173    /** Get the context used for (un)serialisation.
     174     */
     175    const Xapian::SerialisationContext & get_context() const {
     176        return ctx;
    176177    }
    177178
    178     /** Register a user-defined posting source class.
     179    /** Set the context used for (un)serialisation.
    179180     */
    180     void register_posting_source(const Xapian::PostingSource &source);
     181    void set_context(const Xapian::SerialisationContext & new_ctx) {
     182        ctx = new_ctx;
     183    }
    181184};
    182185
    183186#endif // XAPIAN_INCLUDED_REMOTESERVER_H
  • xapian-core/common/serialisationcontextinternal.h

     
     1/** @file serialisationcontextinternal.h
     2 * @brief Internals of SerialisationContext object.
     3 */
     4/* Copyright 2009 Lemur Consulting Ltd
     5 *
     6 * This program is free software; you can redistribute it and/or
     7 * modify it under the terms of the GNU General Public License as
     8 * published by the Free Software Foundation; either version 2 of the
     9 * License, or (at your option) any later version.
     10 *
     11 * This program is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU General Public License
     17 * along with this program; if not, write to the Free Software
     18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
     19 */
     20
     21#ifndef XAPIAN_INCLUDED_SERIALISATIONCONTEXTINTERNAL_H
     22#define XAPIAN_INCLUDED_SERIALISATIONCONTEXTINTERNAL_H
     23
     24#include "xapian/base.h"
     25#include "xapian/serialisationcontext.h"
     26
     27#include <map>
     28#include <string>
     29
     30class Xapian::Weight;
     31class Xapian::PostingSource;
     32
     33class Xapian::SerialisationContext::Internal
     34        : public Xapian::Internal::RefCntBase {
     35    /// Registered weighting schemes.
     36    std::map<std::string, Xapian::Weight *> wtschemes;
     37
     38    /// Registered external posting sources.
     39    std::map<std::string, Xapian::PostingSource *> postingsources;
     40
     41    /** Add the standard default weighting schemes and posting sources.
     42     */
     43    void add_defaults();
     44
     45    /** Clear all registered weighting schemes from the context.
     46     */
     47    void clear_weighting_schemes();
     48
     49    /** Clear all registered posting sources from the context.
     50     */
     51    void clear_posting_sources();
     52
     53  public:
     54    Internal();
     55    ~Internal();
     56
     57    /** Register a weighting scheme with the context.
     58     */
     59    void register_weighting_scheme(const Xapian::Weight &wt);
     60
     61    /** Get a weighting scheme given a name.
     62     *
     63     *  The returned weighting scheme is owned by the context object.
     64     *
     65     *  Returns NULL if the weighting scheme could not be found.
     66     */
     67    const Xapian::Weight *
     68            get_weighting_scheme(const std::string & name) const;
     69
     70    /** Register a user-defined posting source class.
     71     */
     72    void register_posting_source(const Xapian::PostingSource &source);
     73
     74    /** Get a posting source given a name.
     75     *
     76     *  The returned posting source is owned by the context object.
     77     *
     78     *  Returns NULL if the posting source could not be found.
     79     */
     80    const Xapian::PostingSource *
     81            get_posting_source(const std::string & name) const;
     82};
     83
     84#endif // XAPIAN_INCLUDED_SERIALISATIONCONTEXTINTERNAL_H
  • xapian-core/api/Makefile.mk

    Property changes on: xapian-core/common/serialisationcontextinternal.h
    ___________________________________________________________________
    Name: svn:eol-style
       + native
    
     
    2525        api/postingsource.cc\
    2626        api/postlist.cc\
    2727        api/replication.cc\
     28        api/serialisationcontext.cc\
    2829        api/sortable-serialise.cc\
    2930        api/sorter.cc\
    3031        api/termlist.cc\
  • xapian-core/api/serialisationcontext.cc

     
     1/** @file serialisationcontext.cc
     2 * @brief Context for looking up objects during unserialisation.
     3 */
     4/* Copyright (C) 2009 Lemur Consulting Ltd
     5 *
     6 * This program is free software; you can redistribute it and/or
     7 * modify it under the terms of the GNU General Public License as
     8 * published by the Free Software Foundation; either version 2 of the
     9 * License, or (at your option) any later version.
     10 *
     11 * This program is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU General Public License
     17 * along with this program; if not, write to the Free Software
     18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
     19 */
     20
     21#include <config.h>
     22#include "xapian/serialisationcontext.h"
     23
     24#include "xapian/enquire.h"
     25#include "xapian/error.h"
     26#include "xapian/postingsource.h"
     27#include "serialisationcontextinternal.h"
     28#include "omdebug.h"
     29
     30namespace Xapian {
     31
     32SerialisationContext::SerialisationContext(const SerialisationContext & other)
     33        : internal(other.internal)
     34{
     35    LOGCALL_CTOR(API, "Xapian::SerialisationContext::SerialisationContext", other);
     36}
     37
     38SerialisationContext &
     39SerialisationContext::operator=(const SerialisationContext & other)
     40{
     41    LOGCALL(API, Xapian::SerialisationContext &,
     42            "Xapian::SerialisationContext::operator=", other);
     43    internal = other.internal;
     44    RETURN(*this);
     45}
     46
     47SerialisationContext::SerialisationContext()
     48        : internal(new SerialisationContext::Internal())
     49{
     50    LOGCALL_CTOR(API, "Xapian::SerialisationContext::SerialisationContext",
     51                 "");
     52}
     53
     54SerialisationContext::~SerialisationContext()
     55{
     56    LOGCALL_DTOR(API, "Xapian::SerialisationContext::~SerialisationContext");
     57
     58    // Note - we don't need to do anything special in this destructor, but it
     59    // does need to be explicitly defined because the definition of the
     60    // internals is not visible externally, which results in an error if the
     61    // compiler tries to generate a default destructor.
     62}
     63
     64void
     65SerialisationContext::register_weighting_scheme(const Xapian::Weight &wt)
     66{
     67    LOGCALL_VOID(API,
     68                 "Xapian::SerialisationContext::register_weighting_scheme",
     69                 wt);
     70    internal->register_weighting_scheme(wt);
     71}
     72
     73const Xapian::Weight *
     74SerialisationContext::get_weighting_scheme(const std::string & name) const
     75{
     76    LOGCALL(API,
     77            const Xapian::Weight *,
     78            "Xapian::SerialisationContext::get_weighting_scheme",
     79            name);
     80    RETURN(internal->get_weighting_scheme(name));
     81}
     82
     83
     84void
     85SerialisationContext::register_posting_source(const Xapian::PostingSource &source)
     86{
     87    LOGCALL_VOID(API, "Xapian::SerialisationContext::register_posting_source", source);
     88    internal->register_posting_source(source);
     89}
     90
     91const Xapian::PostingSource *
     92SerialisationContext::get_posting_source(const std::string & name) const
     93{
     94    LOGCALL(API,
     95            const Xapian::PostingSource *,
     96            "Xapian::SerialisationContext::get_posting_source",
     97            name);
     98    RETURN(internal->get_posting_source(name));
     99}
     100
     101
     102SerialisationContext::Internal::Internal()
     103        : Xapian::Internal::RefCntBase(),
     104          wtschemes(),
     105          postingsources()
     106{
     107    add_defaults();
     108}
     109
     110SerialisationContext::Internal::~Internal()
     111{
     112    clear_weighting_schemes();
     113    clear_posting_sources();
     114}
     115
     116void
     117SerialisationContext::Internal::add_defaults()
     118{
     119    Xapian::Weight * weight;
     120    weight = new Xapian::BM25Weight;
     121    wtschemes[weight->name()] = weight;
     122    weight = new Xapian::BoolWeight;
     123    wtschemes[weight->name()] = weight;
     124    weight = new Xapian::TradWeight;
     125    wtschemes[weight->name()] = weight;
     126
     127    Xapian::PostingSource * source;
     128    source = new Xapian::ValueWeightPostingSource(0);
     129    postingsources[source->name()] = source;
     130    source = new Xapian::ValueMapPostingSource(0);
     131    postingsources[source->name()] = source;
     132    source = new Xapian::FixedWeightPostingSource(0.0);
     133    postingsources[source->name()] = source;
     134}
     135
     136void
     137SerialisationContext::Internal::clear_weighting_schemes()
     138{
     139    std::map<std::string, Xapian::Weight*>::const_iterator i;
     140    for (i = wtschemes.begin(); i != wtschemes.end(); ++i) {
     141        delete i->second;
     142    }
     143}
     144
     145void
     146SerialisationContext::Internal::clear_posting_sources()
     147{
     148    std::map<std::string, Xapian::PostingSource *>::const_iterator i;
     149    for (i = postingsources.begin(); i != postingsources.end(); ++i) {
     150        delete i->second;
     151    }
     152}
     153
     154void
     155SerialisationContext::Internal::register_weighting_scheme(const Xapian::Weight &wt)
     156{
     157    std::string wtname(wt.name());
     158    (void) wtschemes.erase(wtname);
     159    wtschemes[wtname] = wt.clone();
     160}
     161
     162const Xapian::Weight *
     163SerialisationContext::Internal::get_weighting_scheme(const std::string & name) const
     164{
     165    std::map<std::string, Xapian::Weight *>::const_iterator i;
     166    i = wtschemes.find(name);
     167    if (i == wtschemes.end()) {
     168        return NULL;
     169    }
     170    return i->second;
     171}
     172
     173void
     174SerialisationContext::Internal::register_posting_source(const Xapian::PostingSource &source)
     175{
     176    std::string sourcename = source.name();
     177    if (sourcename.empty()) {
     178        throw Xapian::InvalidOperationError("Unable to register posting source - name() method returns empty string.");
     179    }
     180    Xapian::PostingSource * sourceclone = source.clone();
     181    if (!sourceclone) {
     182        throw Xapian::InvalidOperationError("Unable to register posting source - clone() method returns NULL.");
     183    }
     184    try {
     185        (void) postingsources.erase(sourcename);
     186        postingsources[sourcename] = sourceclone;
     187    } catch(...) {
     188        delete sourceclone;
     189        throw;
     190    }
     191}
     192
     193const Xapian::PostingSource *
     194SerialisationContext::Internal::get_posting_source(const std::string & name) const
     195{
     196    std::map<std::string, Xapian::PostingSource *>::const_iterator i;
     197    i = postingsources.find(name);
     198    if (i == postingsources.end()) {
     199        return NULL;
     200    }
     201    return i->second;
     202}
     203
     204}
  • xapian-core/api/omqueryinternal.cc

    Property changes on: xapian-core/api/serialisationcontext.cc
    ___________________________________________________________________
    Name: svn:eol-style
       + native
    
     
    2525
    2626#include "omqueryinternal.h"
    2727
     28#include "serialisationcontextinternal.h"
    2829#include "omdebug.h"
    2930#include "utils.h"
    3031#include "serialise.h"
     
    391392    const char *p;
    392393    const char *end;
    393394    Xapian::termpos curpos;
    394     const map<string, Xapian::PostingSource *> & sources;
     395    const Xapian::SerialisationContext & ctx;
    395396
    396397    Xapian::Query::Internal * readquery();
    397398    Xapian::Query::Internal * readexternal();
     
    399400
    400401  public:
    401402    QUnserial(const string & s,
    402               const map<string, Xapian::PostingSource *> & sources_)
    403             : p(s.c_str()), end(p + s.size()), curpos(1), sources(sources_) { }
     403              const Xapian::SerialisationContext & ctx_)
     404            : p(s.c_str()), end(p + s.size()), curpos(1), ctx(ctx_) { }
    404405    Xapian::Query::Internal * decode();
    405406};
    406407
     
    457458
    458459    size_t length = decode_length(&p, end, true);
    459460    string sourcename(p, length);
    460     map<string, Xapian::PostingSource *>::const_iterator i;
    461     i = sources.find(sourcename);
    462     if (i == sources.end()) {
    463         throw Xapian::InvalidArgumentError("PostingSource " + string(p, length) + " not registered");
     461    const Xapian::PostingSource * source = ctx.get_posting_source(sourcename);
     462    if (source == NULL) {
     463        throw Xapian::InvalidArgumentError("PostingSource " + sourcename +
     464                                          " not registered");
    464465    }
    465466
    466467    p += length;
     
    468469    string sourcedata(p, length);
    469470    p += length;
    470471
    471     return new Xapian::Query::Internal(i->second->unserialise(sourcedata), true);
     472    return new Xapian::Query::Internal(source->unserialise(sourcedata), true);
    472473}
    473474
    474475static Xapian::Query::Internal *
     
    606607
    607608Xapian::Query::Internal *
    608609Xapian::Query::Internal::unserialise(const string &s,
    609                         const map<string, Xapian::PostingSource *> & sources)
     610                const Xapian::SerialisationContext & ctx)
    610611{
    611612    Assert(s.length() > 1);
    612     QUnserial u(s, sources);
     613    QUnserial u(s, ctx);
    613614    Xapian::Query::Internal * qint = u.decode();
    614615    AssertEq(s, qint->serialise());
    615616    return qint;
     
    617618#else
    618619Xapian::Query::Internal *
    619620Xapian::Query::Internal::unserialise(const string &,
    620                         const map<string, Xapian::PostingSource *> & sources)
     621                const Xapian::SerialisationContext & ctx)
    621622{
    622623    throw Xapian::InternalError("query serialisation not compiled in");
    623624}
  • xapian-core/api/omquery.cc

     
    3030
    3131#include "xapian/error.h"
    3232#include "xapian/postingsource.h"
     33#include "xapian/serialisationcontext.h"
    3334#include "xapian/termiterator.h"
    3435
    3536#include <vector>
     
    216217    DEBUGAPICALL_STATIC(Xapian::Query, "Xapian::Query::unserialise", s);
    217218    Query result;
    218219    if (!s.empty()) {
    219         std::map<std::string, Xapian::PostingSource *> sources;
    220         result.internal = Xapian::Query::Internal::unserialise(s, sources);
     220        SerialisationContext ctx;
     221        result.internal = Xapian::Query::Internal::unserialise(s, ctx);
    221222    }
    222223    RETURN(result);
    223224}
    224225
     226Query
     227Query::unserialise(const std::string & s, const SerialisationContext & ctx)
     228{
     229    DEBUGAPICALL_STATIC(Xapian::Query, "Xapian::Query::unserialise",
     230                        s << ", ctx");
     231    Query result;
     232    if (!s.empty()) {
     233        result.internal = Xapian::Query::Internal::unserialise(s, ctx);
     234    }
     235    RETURN(result);
     236}
     237
    225238std::string
    226239Query::get_description() const
    227240{
  • xapian-bindings/csharp/Makefile.am

     
    4444        SWIGTYPE_p_std__string.cs \
    4545        SWIGTYPE_p_std__vectorT_std__string_t.cs \
    4646        SWIGTYPE_p_std__vectorT_Xapian__Query_t.cs \
     47        SerialisationContext.cs \
    4748        SimpleStopper.cs \
    4849        Sorter.cs \
    4950        Stem.cs \
  • xapian-bindings/xapian.i

     
    812812%include <xapian/replication.h>
    813813%include <xapian/valuesetmatchdecider.h>
    814814
     815%ignore Xapian::SerialisationContext::operator=;
     816%include <xapian/serialisationcontext.h>
     817
    815818namespace Xapian {
    816819
    817820#if defined SWIGPYTHON