xapian-core  2.0.0
registry.cc
Go to the documentation of this file.
1 
4 /* Copyright (C) 2006,2007,2008,2009,2010,2016,2024 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, see
19  * <https://www.gnu.org/licenses/>.
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 #include "stringutils.h"
35 
36 #include <algorithm>
37 #include <map>
38 #include <string>
39 
40 using namespace std;
41 
43 
45  friend class Xapian::Registry;
46 
48  map<string, Xapian::Weight*, std::less<>> wtschemes;
49 
51  map<string, Xapian::PostingSource*, std::less<>> postingsources;
52 
54  map<string, Xapian::MatchSpy*, std::less<>> matchspies;
55 
57  map<string, Xapian::LatLongMetric*, std::less<>> lat_long_metrics;
58 
60  map<string, opt_intrusive_ptr<Xapian::KeyMaker>, std::less<>> key_makers;
61 
63  void add_defaults();
64 
66  void clear_weighting_schemes();
67 
69  void clear_posting_sources();
70 
72  void clear_match_spies();
73 
75  void clear_lat_long_metrics();
76 
77  public:
78  Internal();
79  ~Internal();
80 };
81 
83 template<class T>
84 static inline void
85 register_object(map<string, opt_intrusive_ptr<T>, std::less<>>& registry,
86  T* obj_)
87 {
88  opt_intrusive_ptr<T> obj(obj_);
89 
90  string name = obj->name();
91  if (rare(name.empty())) {
92  throw Xapian::InvalidOperationError("Unable to register object - "
93  "name() method returned empty "
94  "string");
95  }
96 
97  auto r = registry.insert(make_pair(name, static_cast<T*>(NULL)));
98  r.first->second = std::move(obj);
99 }
100 
102 template<class T>
103 static inline void
104 register_object(map<string, T*, std::less<>>& registry, const T& obj)
105 {
106  string name = obj.name();
107  if (rare(name.empty())) {
108  throw Xapian::InvalidOperationError("Unable to register object - name() method returned empty string");
109  }
110 
111  auto r = registry.insert(make_pair(name, static_cast<T*>(NULL)));
112  if (!r.second) {
113  // Existing element with this key, so replace the pointer with NULL
114  // and delete the existing pointer.
115  //
116  // If the delete throws, this will leave a NULL entry in the map, but
117  // that won't affect behaviour as we return NULL for "not found"
118  // anyway. The memory used will be leaked if the dtor throws, but
119  // throwing exceptions from the dtor is bad form, so that's not a big
120  // problem.
121  T * p = NULL;
122  swap(p, r.first->second);
123  delete p;
124  }
125 
126  T * clone = obj.clone();
127  if (rare(!clone)) {
128  throw Xapian::InvalidOperationError("Unable to register object - clone() method returned NULL");
129  }
130 
131  r.first->second = clone;
132 }
133 
135 template<class T>
136 static inline const T*
137 lookup_object(map<string, opt_intrusive_ptr<T>, std::less<>> registry,
138  string_view name)
139 {
140  auto i = registry.find(name);
141  if (i == registry.end()) {
142  return NULL;
143  }
144  return i->second.get();
145 }
146 
148 template<class T>
149 static inline const T*
150 lookup_object(map<string, T*, std::less<>> registry, string_view name)
151 {
152  auto i = registry.find(name);
153  if (i == registry.end()) {
154  return NULL;
155  }
156  return i->second;
157 }
158 
159 namespace Xapian {
160 
161 Registry::Internal::Internal()
162 {
163  add_defaults();
164 }
165 
166 Registry::Internal::~Internal()
167 {
168  clear_weighting_schemes();
169  clear_posting_sources();
170  clear_match_spies();
171  clear_lat_long_metrics();
172 }
173 
174 void
175 Registry::Internal::add_defaults()
176 {
177  Xapian::Weight * weighting_scheme;
178  weighting_scheme = new Xapian::BB2Weight;
179  wtschemes[weighting_scheme->name()] = weighting_scheme;
180  weighting_scheme = new Xapian::BM25Weight;
181  wtschemes[weighting_scheme->name()] = weighting_scheme;
182  weighting_scheme = new Xapian::BM25PlusWeight;
183  wtschemes[weighting_scheme->name()] = weighting_scheme;
184  weighting_scheme = new Xapian::BoolWeight;
185  wtschemes[weighting_scheme->name()] = weighting_scheme;
186  weighting_scheme = new Xapian::CoordWeight;
187  wtschemes[weighting_scheme->name()] = weighting_scheme;
188  weighting_scheme = new Xapian::TfIdfWeight;
189  wtschemes[weighting_scheme->name()] = weighting_scheme;
190  weighting_scheme = new Xapian::InL2Weight;
191  wtschemes[weighting_scheme->name()] = weighting_scheme;
192  weighting_scheme = new Xapian::IfB2Weight;
193  wtschemes[weighting_scheme->name()] = weighting_scheme;
194  weighting_scheme = new Xapian::IneB2Weight;
195  wtschemes[weighting_scheme->name()] = weighting_scheme;
196  weighting_scheme = new Xapian::DLHWeight;
197  wtschemes[weighting_scheme->name()] = weighting_scheme;
198  weighting_scheme = new Xapian::PL2PlusWeight;
199  wtschemes[weighting_scheme->name()] = weighting_scheme;
200  weighting_scheme = new Xapian::PL2Weight;
201  wtschemes[weighting_scheme->name()] = weighting_scheme;
202  weighting_scheme = new Xapian::DPHWeight;
203  wtschemes[weighting_scheme->name()] = weighting_scheme;
204  weighting_scheme = new Xapian::LMJMWeight;
205  wtschemes[weighting_scheme->name()] = weighting_scheme;
206  weighting_scheme = new Xapian::LMDirichletWeight;
207  wtschemes[weighting_scheme->name()] = weighting_scheme;
208  weighting_scheme = new Xapian::LMAbsDiscountWeight;
209  wtschemes[weighting_scheme->name()] = weighting_scheme;
210  weighting_scheme = new Xapian::LM2StageWeight;
211  wtschemes[weighting_scheme->name()] = weighting_scheme;
212  weighting_scheme = new Xapian::DiceWeight;
213  wtschemes[weighting_scheme->name()] = weighting_scheme;
214 
215  Xapian::PostingSource * source;
216  source = new Xapian::ValueWeightPostingSource(0);
217  postingsources[source->name()] = source;
219  postingsources[source->name()] = source;
220  source = new Xapian::ValueMapPostingSource(0);
221  postingsources[source->name()] = source;
222  source = new Xapian::FixedWeightPostingSource(0.0);
223  postingsources[source->name()] = source;
227  postingsources[source->name()] = source;
228 
229  Xapian::MatchSpy * spy;
230  spy = new Xapian::ValueCountMatchSpy();
231  matchspies[spy->name()] = spy;
232 
233  Xapian::LatLongMetric * metric;
234  metric = new Xapian::GreatCircleMetric();
235  lat_long_metrics[metric->name()] = metric;
236 
237  Xapian::KeyMaker* keymaker;
238  keymaker = new Xapian::MultiValueKeyMaker();
239  key_makers[keymaker->name()] = keymaker->release();
240 }
241 
242 void
243 Registry::Internal::clear_weighting_schemes()
244 {
245  for (auto&& i : wtschemes) {
246  delete i.second;
247  }
248 }
249 
250 void
251 Registry::Internal::clear_posting_sources()
252 {
253  for (auto&& i : postingsources) {
254  delete i.second;
255  }
256 }
257 
258 void
259 Registry::Internal::clear_match_spies()
260 {
261  for (auto&& i : matchspies) {
262  delete i.second;
263  }
264 }
265 
266 void
267 Registry::Internal::clear_lat_long_metrics()
268 {
269  for (auto&& i : lat_long_metrics) {
270  delete i.second;
271  }
272 }
273 
274 Registry::Registry(const Registry & other)
275  : internal(other.internal)
276 {
277  LOGCALL_CTOR(API, "Registry", other);
278 }
279 
280 Registry &
282 {
283  LOGCALL(API, Xapian::Registry &, "Xapian::Registry::operator=", other);
284  internal = other.internal;
285  RETURN(*this);
286 }
287 
288 Registry::Registry(Registry &&) = default;
289 
290 Registry &
291 Registry::operator=(Registry &&) = default;
292 
294  : internal(new Registry::Internal())
295 {
296  LOGCALL_CTOR(API, "Registry", NO_ARGS);
297 }
298 
300 {
301  LOGCALL_DTOR(API, "Registry");
302 
303  // Note - we don't need to do anything special in this destructor, but it
304  // does need to be explicitly defined because the definition of the
305  // internals is not visible externally, which results in an error if the
306  // compiler tries to generate a default destructor.
307 }
308 
309 void
311 {
312  LOGCALL_VOID(API, "Xapian::Registry::register_weighting_scheme", wt.name());
314 }
315 
316 const Xapian::Weight *
318 {
319  LOGCALL(API, const Xapian::Weight *, "Xapian::Registry::get_weighting_scheme", name);
321 }
322 
323 void
325 {
326  LOGCALL_VOID(API, "Xapian::Registry::register_posting_source", source.name());
328 }
329 
330 const Xapian::PostingSource *
332 {
333  LOGCALL(API, const Xapian::PostingSource *, "Xapian::Registry::get_posting_source", name);
335 }
336 
337 void
339 {
340  LOGCALL_VOID(API, "Xapian::Registry::register_match_spy", spy.name());
342 }
343 
344 const Xapian::MatchSpy *
345 Registry::get_match_spy(string_view name) const
346 {
347  LOGCALL(API, const Xapian::MatchSpy *, "Xapian::Registry::get_match_spy", name);
349 }
350 
351 void
353 {
354  LOGCALL_VOID(API, "Xapian::Registry::register_lat_long_metric", metric.name());
356 }
357 
358 const Xapian::LatLongMetric *
360 {
361  LOGCALL(API, const Xapian::LatLongMetric *, "Xapian::Registry::get_lat_long_metric", name);
363 }
364 
365 void
367 {
368  LOGCALL_VOID(API, "Xapian::Registry::register_key_maker", keymaker->name());
369  register_object(internal->key_makers, keymaker);
370 }
371 
372 const Xapian::KeyMaker*
373 Registry::get_key_maker(std::string_view name) const
374 {
375  LOGCALL(API, const Xapian::KeyMaker*, "Xapian::Registry::get_key_maker", name);
377 }
378 
379 }
This class implements the BB2 weighting scheme.
Definition: weight.h:1540
Xapian::Weight subclass implementing the BM25+ probabilistic formula.
Definition: weight.h:1161
Xapian::Weight subclass implementing the BM25 probabilistic formula.
Definition: weight.h:1050
Class implementing a "boolean" weighting scheme.
Definition: weight.h:678
Xapian::Weight subclass implementing Coordinate Matching.
Definition: weight.h:2163
This class implements the DLH weighting scheme, which is a representative scheme of the Divergence fr...
Definition: weight.h:1615
This class implements the DPH weighting scheme.
Definition: weight.h:1826
Read weights from a value which is known to decrease as docid increases.
Xapian::Weight subclass implementing Dice Coefficient.
Definition: weight.h:2207
A posting source which returns a fixed weight for all documents.
Calculate the great-circle distance between two coordinates on a sphere.
Definition: geospatial.h:398
This class implements the IfB2 weighting scheme.
Definition: weight.h:1397
This class implements the InL2 weighting scheme.
Definition: weight.h:1327
This class implements the IneB2 weighting scheme.
Definition: weight.h:1469
Base class for objects managed by intrusive_ptr.
Definition: intrusive_ptr.h:50
A smart pointer that optionally uses intrusive reference counting.
InvalidOperationError indicates the API was used in an invalid way.
Definition: error.h:271
Virtual base class for key making functors.
Definition: keymaker.h:44
KeyMaker * release()
Start reference counting this object.
Definition: keymaker.h:123
virtual std::string name() const
Return the name of this KeyMaker.
Definition: keymaker.cc:48
Language Model weighting with Two Stage smoothing.
Definition: weight.h:2093
Language Model weighting with Absolute Discount smoothing.
Definition: weight.h:2024
Language Model weighting with Dirichlet or Dir+ smoothing.
Definition: weight.h:1948
Language Model weighting with Jelinek-Mercer smoothing.
Definition: weight.h:1875
A sequence of latitude-longitude coordinates.
Definition: geospatial.h:231
Posting source which returns a weight based on geospatial distance.
Definition: geospatial.h:454
Base class for calculating distances between two lat/long coordinates.
Definition: geospatial.h:302
virtual std::string name() const =0
Return the full name of the metric.
Abstract base class for match spies.
Definition: matchspy.h:50
virtual std::string name() const
Return the name of this match spy.
Definition: matchspy.cc:57
KeyMaker subclass which combines several values.
Definition: keymaker.h:156
Xapian::Weight subclass implementing the PL2+ probabilistic formula.
Definition: weight.h:1731
This class implements the PL2 weighting scheme.
Definition: weight.h:1671
Base class which provides an "external" source of postings.
Definition: postingsource.h:47
virtual std::string name() const
Name of the posting source class.
map< string, Xapian::LatLongMetric *, std::less<> > lat_long_metrics
Registered lat-long metrics.
Definition: registry.cc:57
map< string, Xapian::MatchSpy *, std::less<> > matchspies
Registered match spies.
Definition: registry.cc:54
map< string, Xapian::Weight *, std::less<> > wtschemes
Registered weighting schemes.
Definition: registry.cc:48
map< string, Xapian::PostingSource *, std::less<> > postingsources
Registered external posting sources.
Definition: registry.cc:51
map< string, opt_intrusive_ptr< Xapian::KeyMaker >, std::less<> > key_makers
Registered KeyMaker subclasses.
Definition: registry.cc:60
Registry for user subclasses.
Definition: registry.h:47
const Xapian::PostingSource * get_posting_source(std::string_view name) const
Get a posting source given a name.
Definition: registry.cc:331
void register_lat_long_metric(const Xapian::LatLongMetric &metric)
Register a user-defined lat-long metric class.
Definition: registry.cc:352
Registry()
Default constructor.
Definition: registry.cc:293
const Xapian::MatchSpy * get_match_spy(std::string_view name) const
Get a match spy given a name.
Definition: registry.cc:345
void register_posting_source(const Xapian::PostingSource &source)
Register a user-defined posting source class.
Definition: registry.cc:324
const Xapian::Weight * get_weighting_scheme(std::string_view name) const
Get the weighting scheme given a name.
Definition: registry.cc:317
void register_key_maker(Xapian::KeyMaker *keymaker)
Register a user-defined KeyMaker subclass.
Definition: registry.cc:366
void register_weighting_scheme(const Xapian::Weight &wt)
Register a weighting scheme.
Definition: registry.cc:310
void register_match_spy(const Xapian::MatchSpy &spy)
Register a user-defined match spy class.
Definition: registry.cc:338
Xapian::Internal::intrusive_ptr_nonnull< Internal > internal
Definition: registry.h:50
Registry & operator=(const Registry &other)
Assignment operator.
Definition: registry.cc:281
const Xapian::KeyMaker * get_key_maker(std::string_view name) const
Get a KeyMaker given a name.
Definition: registry.cc:373
const Xapian::LatLongMetric * get_lat_long_metric(std::string_view name) const
Get a lat-long metric given a name.
Definition: registry.cc:359
Xapian::Weight subclass implementing the tf-idf weighting scheme.
Definition: weight.h:704
Class for counting the frequencies of values in the matching documents.
Definition: matchspy.h:205
A posting source which looks up weights in a map using values as the key.
A posting source which reads weights from a value slot.
Abstract base class for weighting schemes.
Definition: weight.h:38
virtual std::string name() const
Return the name of this weighting scheme, e.g.
Definition: weight.cc:186
#define rare(COND)
Definition: config.h:607
PositionList * p
Debug logging macros.
#define RETURN(...)
Definition: debuglog.h:484
#define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS)
Definition: debuglog.h:478
#define LOGCALL_CTOR(CATEGORY, CLASS, PARAMS)
Definition: debuglog.h:480
#define LOGCALL_VOID(CATEGORY, FUNC, PARAMS)
Definition: debuglog.h:479
#define LOGCALL_DTOR(CATEGORY, CLASS)
Definition: debuglog.h:481
Hierarchy of classes which Xapian can throw as exceptions.
Geospatial search support routines.
MatchSpy implementation.
The Xapian namespace contains public interfaces for the Xapian library.
Definition: compactor.cc:82
External sources of posting information.
static const T * lookup_object(map< string, opt_intrusive_ptr< T >, std::less<>> registry, string_view name)
Look up an optionally ref-counted object.
Definition: registry.cc:137
static void register_object(map< string, opt_intrusive_ptr< T >, std::less<>> &registry, T *obj_)
Register an optionally ref-counted object.
Definition: registry.cc:85
Class for looking up user subclasses during unserialisation.
Various handy string-related helpers.
Definition: header.h:215
Weighting scheme API.