xapian-core  1.4.19
registry.cc
Go to the documentation of this file.
1 
4 /* Copyright (C) 2006,2007,2008,2009,2010,2016 Olly Betts
5  * Copyright (C) 2006,2007,2009 Lemur Consulting Ltd
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <config.h>
23 
24 #include "xapian/registry.h"
25 
26 #include "xapian/error.h"
27 #include "xapian/geospatial.h"
28 #include "xapian/intrusive_ptr.h"
29 #include "xapian/matchspy.h"
30 #include "xapian/postingsource.h"
31 #include "xapian/weight.h"
32 
33 #include "debuglog.h"
34 
35 #include <algorithm>
36 #include <map>
37 #include <string>
38 
39 using namespace std;
40 
42  friend class Xapian::Registry;
43 
45  std::map<std::string, Xapian::Weight *> wtschemes;
46 
48  std::map<std::string, Xapian::PostingSource *> postingsources;
49 
51  std::map<std::string, Xapian::MatchSpy *> matchspies;
52 
54  std::map<std::string, Xapian::LatLongMetric *> lat_long_metrics;
55 
57  void add_defaults();
58 
60  void clear_weighting_schemes();
61 
63  void clear_posting_sources();
64 
66  void clear_match_spies();
67 
69  void clear_lat_long_metrics();
70 
71  public:
72  Internal();
73  ~Internal();
74 };
75 
76 template<class T>
77 static inline void
78 register_object(map<string, T*> & registry, const T & obj)
79 {
80  string name = obj.name();
81  if (rare(name.empty())) {
82  throw Xapian::InvalidOperationError("Unable to register object - name() method returned empty string");
83  }
84 
85  pair<typename map<string, T *>::iterator, bool> r;
86  r = registry.insert(make_pair(name, static_cast<T*>(NULL)));
87  if (!r.second) {
88  // Existing element with this key, so replace the pointer with NULL
89  // and delete the existing pointer.
90  //
91  // If the delete throws, this will leave a NULL entry in the map, but
92  // that won't affect behaviour as we return NULL for "not found"
93  // anyway. The memory used will be leaked if the dtor throws, but
94  // throwing exceptions from the dtor is bad form, so that's not a big
95  // problem.
96  T * p = NULL;
97  swap(p, r.first->second);
98  delete p;
99  }
100 
101  T * clone = obj.clone();
102  if (rare(!clone)) {
103  throw Xapian::InvalidOperationError("Unable to register object - clone() method returned NULL");
104  }
105 
106  r.first->second = clone;
107 }
108 
109 template<class T>
110 static inline const T *
111 lookup_object(map<string, T*> registry, const string & name)
112 {
113  typename map<string, T*>::const_iterator i = registry.find(name);
114  if (i == registry.end()) {
115  return NULL;
116  }
117  return i->second;
118 }
119 
120 namespace Xapian {
121 
122 Registry::Internal::Internal()
123 {
124  add_defaults();
125 }
126 
127 Registry::Internal::~Internal()
128 {
129  clear_weighting_schemes();
130  clear_posting_sources();
131  clear_match_spies();
132  clear_lat_long_metrics();
133 }
134 
135 void
136 Registry::Internal::add_defaults()
137 {
138  Xapian::Weight * weighting_scheme;
139  weighting_scheme = new Xapian::BB2Weight;
140  wtschemes[weighting_scheme->name()] = weighting_scheme;
141  weighting_scheme = new Xapian::BM25Weight;
142  wtschemes[weighting_scheme->name()] = weighting_scheme;
143  weighting_scheme = new Xapian::BM25PlusWeight;
144  wtschemes[weighting_scheme->name()] = weighting_scheme;
145  weighting_scheme = new Xapian::BoolWeight;
146  wtschemes[weighting_scheme->name()] = weighting_scheme;
147  weighting_scheme = new Xapian::CoordWeight;
148  wtschemes[weighting_scheme->name()] = weighting_scheme;
149  weighting_scheme = new Xapian::TradWeight;
150  wtschemes[weighting_scheme->name()] = weighting_scheme;
151  weighting_scheme = new Xapian::TfIdfWeight;
152  wtschemes[weighting_scheme->name()] = weighting_scheme;
153  weighting_scheme = new Xapian::InL2Weight;
154  wtschemes[weighting_scheme->name()] = weighting_scheme;
155  weighting_scheme = new Xapian::IfB2Weight;
156  wtschemes[weighting_scheme->name()] = weighting_scheme;
157  weighting_scheme = new Xapian::IneB2Weight;
158  wtschemes[weighting_scheme->name()] = weighting_scheme;
159  weighting_scheme = new Xapian::DLHWeight;
160  wtschemes[weighting_scheme->name()] = weighting_scheme;
161  weighting_scheme = new Xapian::PL2PlusWeight;
162  wtschemes[weighting_scheme->name()] = weighting_scheme;
163  weighting_scheme = new Xapian::PL2Weight;
164  wtschemes[weighting_scheme->name()] = weighting_scheme;
165  weighting_scheme = new Xapian::DPHWeight;
166  wtschemes[weighting_scheme->name()] = weighting_scheme;
167  weighting_scheme = new Xapian::LMWeight;
168  wtschemes[weighting_scheme->name()] = weighting_scheme;
169 
170  Xapian::PostingSource * source;
171  source = new Xapian::ValueWeightPostingSource(0);
172  postingsources[source->name()] = source;
174  postingsources[source->name()] = source;
175  source = new Xapian::ValueMapPostingSource(0);
176  postingsources[source->name()] = source;
177  source = new Xapian::FixedWeightPostingSource(0.0);
178  postingsources[source->name()] = source;
182  postingsources[source->name()] = source;
183 
184  Xapian::MatchSpy * spy;
185  spy = new Xapian::ValueCountMatchSpy();
186  matchspies[spy->name()] = spy;
187 
188  Xapian::LatLongMetric * metric;
189  metric = new Xapian::GreatCircleMetric();
190  lat_long_metrics[metric->name()] = metric;
191 }
192 
193 void
194 Registry::Internal::clear_weighting_schemes()
195 {
196  map<string, Xapian::Weight*>::const_iterator i;
197  for (i = wtschemes.begin(); i != wtschemes.end(); ++i) {
198  delete i->second;
199  }
200 }
201 
202 void
203 Registry::Internal::clear_posting_sources()
204 {
205  map<string, Xapian::PostingSource *>::const_iterator i;
206  for (i = postingsources.begin(); i != postingsources.end(); ++i) {
207  delete i->second;
208  }
209 }
210 
211 void
212 Registry::Internal::clear_match_spies()
213 {
214  map<string, Xapian::MatchSpy *>::const_iterator i;
215  for (i = matchspies.begin(); i != matchspies.end(); ++i) {
216  delete i->second;
217  }
218 }
219 
220 void
221 Registry::Internal::clear_lat_long_metrics()
222 {
223  map<string, Xapian::LatLongMetric *>::const_iterator i;
224  for (i = lat_long_metrics.begin(); i != lat_long_metrics.end(); ++i) {
225  delete i->second;
226  }
227 }
228 
229 Registry::Registry(const Registry & other)
230  : internal(other.internal)
231 {
232  LOGCALL_CTOR(API, "Registry", other);
233 }
234 
235 Registry &
237 {
238  LOGCALL(API, Xapian::Registry &, "Xapian::Registry::operator=", other);
239  internal = other.internal;
240  RETURN(*this);
241 }
242 
243 Registry::Registry(Registry &&) = default;
244 
245 Registry &
246 Registry::operator=(Registry &&) = default;
247 
249  : internal(new Registry::Internal())
250 {
251  LOGCALL_CTOR(API, "Registry", NO_ARGS);
252 }
253 
255 {
256  LOGCALL_DTOR(API, "Registry");
257 
258  // Note - we don't need to do anything special in this destructor, but it
259  // does need to be explicitly defined because the definition of the
260  // internals is not visible externally, which results in an error if the
261  // compiler tries to generate a default destructor.
262 }
263 
264 void
266 {
267  LOGCALL_VOID(API, "Xapian::Registry::register_weighting_scheme", wt.name());
268  register_object(internal->wtschemes, wt);
269 }
270 
271 const Xapian::Weight *
273 {
274  LOGCALL(API, const Xapian::Weight *, "Xapian::Registry::get_weighting_scheme", name);
275  RETURN(lookup_object(internal->wtschemes, name));
276 }
277 
278 void
280 {
281  LOGCALL_VOID(API, "Xapian::Registry::register_posting_source", source.name());
282  register_object(internal->postingsources, source);
283 }
284 
285 const Xapian::PostingSource *
286 Registry::get_posting_source(const string & name) const
287 {
288  LOGCALL(API, const Xapian::PostingSource *, "Xapian::Registry::get_posting_source", name);
289  RETURN(lookup_object(internal->postingsources, name));
290 }
291 
292 void
294 {
295  LOGCALL_VOID(API, "Xapian::Registry::register_match_spy", spy.name());
296  register_object(internal->matchspies, spy);
297 }
298 
299 const Xapian::MatchSpy *
300 Registry::get_match_spy(const string & name) const
301 {
302  LOGCALL(API, const Xapian::MatchSpy *, "Xapian::Registry::get_match_spy", name);
303  RETURN(lookup_object(internal->matchspies, name));
304 }
305 
306 void
308 {
309  LOGCALL_VOID(API, "Xapian::Registry::register_lat_long_metric", metric.name());
310  register_object(internal->lat_long_metrics, metric);
311 }
312 
313 const Xapian::LatLongMetric *
314 Registry::get_lat_long_metric(const string & name) const
315 {
316  LOGCALL(API, const Xapian::LatLongMetric *, "Xapian::Registry::get_lat_long_metric", name);
317  RETURN(lookup_object(internal->lat_long_metrics, name));
318 }
319 
320 }
The Xapian namespace contains public interfaces for the Xapian library.
Definition: compactor.cc:80
#define RETURN(A)
Definition: debuglog.h:482
void register_weighting_scheme(const Xapian::Weight &wt)
Register a weighting scheme.
Definition: registry.cc:265
virtual std::string name() const
Return the name of this weighting scheme.
Definition: weight.cc:135
InvalidOperationError indicates the API was used in an invalid way.
Definition: error.h:283
Abstract base class for match spies.
Definition: matchspy.h:49
A posting source which looks up weights in a map using values as the key.
#define LOGCALL_DTOR(CATEGORY, CLASS)
Definition: debuglog.h:479
External sources of posting information.
static const T * lookup_object(map< string, T *> registry, const string &name)
Definition: registry.cc:111
This class implements the InL2 weighting scheme.
Definition: weight.h:838
#define LOGCALL_VOID(CATEGORY, FUNC, PARAMS)
Definition: debuglog.h:477
STL namespace.
const Xapian::PostingSource * get_posting_source(const std::string &name) const
Get a posting source given a name.
Definition: registry.cc:286
std::map< std::string, Xapian::LatLongMetric * > lat_long_metrics
Registered lat-long metrics.
Definition: registry.cc:54
std::map< std::string, Xapian::MatchSpy * > matchspies
Registered match spies.
Definition: registry.cc:51
static void register_object(map< string, T *> &registry, const T &obj)
Definition: registry.cc:78
Xapian::Weight subclass implementing the PL2+ probabilistic formula.
Definition: weight.h:1257
#define rare(COND)
Definition: config.h:543
Read weights from a value which is known to decrease as docid increases.
Hierarchy of classes which Xapian can throw as exceptions.
This class implements the BB2 weighting scheme.
Definition: weight.h:1054
Xapian::Weight subclass implementing Coordinate Matching.
Definition: weight.h:1509
const Xapian::MatchSpy * get_match_spy(const std::string &name) const
Get a match spy given a name.
Definition: registry.cc:300
Posting source which returns a weight based on geospatial distance.
Definition: geospatial.h:454
Class implementing a "boolean" weighting scheme.
Definition: weight.h:422
Geospatial search support routines.
MatchSpy implementation.
void register_match_spy(const Xapian::MatchSpy &spy)
Register a user-defined match spy class.
Definition: registry.cc:293
Registry for user subclasses.
Definition: registry.h:47
A posting source which returns a fixed weight for all documents.
const Xapian::Weight * get_weighting_scheme(const std::string &name) const
Get the weighting scheme given a name.
Definition: registry.cc:272
Base class for calculating distances between two lat/long coordinates.
Definition: geospatial.h:303
Registry()
Default constructor.
Definition: registry.cc:248
Xapian::Weight subclass implementing the traditional probabilistic formula.
Definition: weight.h:768
This class implements the DLH weighting scheme, which is a representative scheme of the Divergence fr...
Definition: weight.h:1130
This class implements the PL2 weighting scheme.
Definition: weight.h:1190
A sequence of latitude-longitude coordinates.
Definition: geospatial.h:232
This class implements the IneB2 weighting scheme.
Definition: weight.h:982
Base class which provides an "external" source of postings.
Definition: postingsource.h:47
Registry & operator=(const Registry &other)
Assignment operator.
Definition: registry.cc:236
Base class for objects managed by intrusive_ptr.
Definition: intrusive_ptr.h:49
#define LOGCALL_CTOR(CATEGORY, CLASS, PARAMS)
Definition: debuglog.h:478
Weighting scheme API.
Class for counting the frequencies of values in the matching documents.
Definition: matchspy.h:205
This class implements the IfB2 weighting scheme.
Definition: weight.h:909
A posting source which reads weights from a value slot.
void register_posting_source(const Xapian::PostingSource &source)
Register a user-defined posting source class.
Definition: registry.cc:279
This class implements the DPH weighting scheme.
Definition: weight.h:1353
virtual std::string name() const =0
Return the full name of the metric.
void register_lat_long_metric(const Xapian::LatLongMetric &metric)
Register a user-defined lat-long metric class.
Definition: registry.cc:307
std::map< std::string, Xapian::PostingSource * > postingsources
Registered external posting sources.
Definition: registry.cc:48
Definition: quest.cc:110
Definition: header.h:151
std::map< std::string, Xapian::Weight * > wtschemes
Registered weighting schemes.
Definition: registry.cc:45
Calculate the great-circle distance between two coordinates on a sphere.
Definition: geospatial.h:399
Xapian::Weight subclass implementing the Language Model formula.
Definition: weight.h:1406
Xapian::Internal::intrusive_ptr< Internal > internal
Definition: registry.h:50
virtual std::string name() const
Name of the posting source class.
Xapian::Weight subclass implementing the BM25+ probabilistic formula.
Definition: weight.h:639
Debug logging macros.
Xapian::Weight subclass implementing the BM25 probabilistic formula.
Definition: weight.h:535
#define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS)
Definition: debuglog.h:476
Class for looking up user subclasses during unserialisation.
Xapian::Weight subclass implementing the tf-idf weighting scheme.
Definition: weight.h:447
Abstract base class for weighting schemes.
Definition: weight.h:35
const Xapian::LatLongMetric * get_lat_long_metric(const std::string &name) const
Get a lat-long metric given a name.
Definition: registry.cc:314
virtual std::string name() const
Return the name of this match spy.
Definition: matchspy.cc:59