00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include "xapian/registry.h"
00025
00026 #include "xapian/error.h"
00027 #include "xapian/matchspy.h"
00028 #include "xapian/postingsource.h"
00029 #include "xapian/weight.h"
00030
00031 #include "registryinternal.h"
00032 #include "debuglog.h"
00033
00034 #include <algorithm>
00035 #include <map>
00036
00037 using namespace std;
00038
00039 template<class T>
00040 static inline void
00041 register_object(map<string, T*> & registry, const T & obj)
00042 {
00043 string name = obj.name();
00044 if (rare(name.empty())) {
00045 throw Xapian::InvalidOperationError("Unable to register object - name() method returned empty string");
00046 }
00047
00048 pair<typename map<string, T *>::iterator, bool> r;
00049 r = registry.insert(make_pair(name, static_cast<T*>(NULL)));
00050 if (!r.second) {
00051
00052
00053
00054
00055
00056
00057
00058
00059 T * p = NULL;
00060 swap(p, r.first->second);
00061 delete p;
00062 }
00063
00064 T * clone = obj.clone();
00065 if (rare(!clone)) {
00066 throw Xapian::InvalidOperationError("Unable to register object - clone() method returned NULL");
00067 }
00068
00069 r.first->second = clone;
00070 }
00071
00072 template<class T>
00073 static inline const T *
00074 lookup_object(map<string, T*> registry, const string & name)
00075 {
00076 typename map<string, T*>::const_iterator i = registry.find(name);
00077 if (i == registry.end()) {
00078 return NULL;
00079 }
00080 return i->second;
00081 }
00082
00083 namespace Xapian {
00084
00085 Registry::Registry(const Registry & other)
00086 : internal(other.internal)
00087 {
00088 LOGCALL_CTOR(API, "Registry", other);
00089 }
00090
00091 Registry &
00092 Registry::operator=(const Registry & other)
00093 {
00094 LOGCALL(API, Xapian::Registry &, "Xapian::Registry::operator=", other);
00095 internal = other.internal;
00096 return(*this);
00097 }
00098
00099 Registry::Registry()
00100 : internal(new Registry::Internal())
00101 {
00102 LOGCALL_CTOR(API, "Registry", NO_ARGS);
00103 }
00104
00105 Registry::~Registry()
00106 {
00107 LOGCALL_DTOR(API, "Registry");
00108
00109
00110
00111
00112
00113 }
00114
00115 void
00116 Registry::register_weighting_scheme(const Xapian::Weight &wt)
00117 {
00118 LOGCALL_VOID(API, "Xapian::Registry::register_weighting_scheme", wt.name());
00119 register_object(internal->wtschemes, wt);
00120 }
00121
00122 const Xapian::Weight *
00123 Registry::get_weighting_scheme(const string & name) const
00124 {
00125 LOGCALL(API, const Xapian::Weight *, "Xapian::Registry::get_weighting_scheme", name);
00126 RETURN(lookup_object(internal->wtschemes, name));
00127 }
00128
00129 void
00130 Registry::register_posting_source(const Xapian::PostingSource &source)
00131 {
00132 LOGCALL_VOID(API, "Xapian::Registry::register_posting_source", source.name());
00133 register_object(internal->postingsources, source);
00134 }
00135
00136 const Xapian::PostingSource *
00137 Registry::get_posting_source(const string & name) const
00138 {
00139 LOGCALL(API, const Xapian::PostingSource *, "Xapian::Registry::get_posting_source", name);
00140 RETURN(lookup_object(internal->postingsources, name));
00141 }
00142
00143 void
00144 Registry::register_match_spy(const Xapian::MatchSpy &spy)
00145 {
00146 LOGCALL_VOID(API, "Xapian::Registry::register_match_spy", spy.name());
00147 register_object(internal->matchspies, spy);
00148 }
00149
00150 const Xapian::MatchSpy *
00151 Registry::get_match_spy(const string & name) const
00152 {
00153 LOGCALL(API, const Xapian::MatchSpy *, "Xapian::Registry::get_match_spy", name);
00154 RETURN(lookup_object(internal->matchspies, name));
00155 }
00156
00157
00158 Registry::Internal::Internal()
00159 : Xapian::Internal::RefCntBase(),
00160 wtschemes(),
00161 postingsources()
00162 {
00163 add_defaults();
00164 }
00165
00166 Registry::Internal::~Internal()
00167 {
00168 clear_weighting_schemes();
00169 clear_posting_sources();
00170 clear_match_spies();
00171 }
00172
00173 void
00174 Registry::Internal::add_defaults()
00175 {
00176 Xapian::Weight * weighting_scheme;
00177 weighting_scheme = new Xapian::BM25Weight;
00178 wtschemes[weighting_scheme->name()] = weighting_scheme;
00179 weighting_scheme = new Xapian::BoolWeight;
00180 wtschemes[weighting_scheme->name()] = weighting_scheme;
00181 weighting_scheme = new Xapian::TradWeight;
00182 wtschemes[weighting_scheme->name()] = weighting_scheme;
00183
00184 Xapian::PostingSource * source;
00185 source = new Xapian::ValueWeightPostingSource(0);
00186 postingsources[source->name()] = source;
00187 source = new Xapian::DecreasingValueWeightPostingSource(0);
00188 postingsources[source->name()] = source;
00189 source = new Xapian::ValueMapPostingSource(0);
00190 postingsources[source->name()] = source;
00191 source = new Xapian::FixedWeightPostingSource(0.0);
00192 postingsources[source->name()] = source;
00193
00194 Xapian::MatchSpy * spy;
00195 spy = new Xapian::ValueCountMatchSpy();
00196 matchspies[spy->name()] = spy;
00197 }
00198
00199 void
00200 Registry::Internal::clear_weighting_schemes()
00201 {
00202 map<string, Xapian::Weight*>::const_iterator i;
00203 for (i = wtschemes.begin(); i != wtschemes.end(); ++i) {
00204 delete i->second;
00205 }
00206 }
00207
00208 void
00209 Registry::Internal::clear_posting_sources()
00210 {
00211 map<string, Xapian::PostingSource *>::const_iterator i;
00212 for (i = postingsources.begin(); i != postingsources.end(); ++i) {
00213 delete i->second;
00214 }
00215 }
00216
00217 void
00218 Registry::Internal::clear_match_spies()
00219 {
00220 map<string, Xapian::MatchSpy *>::const_iterator i;
00221 for (i = matchspies.begin(); i != matchspies.end(); ++i) {
00222 delete i->second;
00223 }
00224 }
00225
00226 }