Gaia
view.h
1 /*
2  * Copyright (C) 2006-2013 Music Technology Group - Universitat Pompeu Fabra
3  *
4  * This file is part of Gaia
5  *
6  * Gaia is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License as published by the Free
8  * Software Foundation (FSF), either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the Affero GNU General Public License
17  * version 3 along with this program. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #ifndef GAIA_VIEW_H
21 #define GAIA_VIEW_H
22 
23 #include <QPointer>
24 #include <vector>
25 #include <queue>
26 #include "dataset.h"
27 #include "searchspacepool.h"
28 #include "distancefunction.h"
29 #include "frozendistance.h"
30 
31 namespace gaia2 {
32 
33 class Filter;
34 
41 template <typename DataSetType, typename PointType, typename SearchPointType, typename DistanceType>
42 class BaseView {
43 
44  public:
45 
46  typedef BaseResultSet<SearchPointType, DataSetType> ResultSetType;
47  typedef BaseSearchSpace<SearchPointType, DataSetType> SearchSpaceType;
48 
49  BaseView(DataSetType* dataset);
50  ~BaseView();
51 
52  ResultSetType nnSearch(const PointType& p, const DistanceType* dist, const Filter* filter = 0);
53  ResultSetType nnSearch(const PointType& p, const DistanceType* dist, const QString& filter);
54 
55  ResultSetType nnSearch(const PointType& p, ResultSetType inputSpace,
56  const DistanceType* dist, const Filter* filter = 0);
57  ResultSetType nnSearch(const PointType& p, ResultSetType inputSpace,
58  const DistanceType* dist, const QString& filter);
59 
60 
61  template <typename T>
62  ResultSetType nnSearch(const QString& id, T x) {
63  validate(); // to make sure that _dataset is not a dangling pointer
64  return nnSearch(*_dataset->point(id), x);
65  }
66 
67  template <typename T, typename U>
68  ResultSetType nnSearch(const QString& id, T x, U y) {
69  validate(); // to make sure that _dataset is not a dangling pointer
70  return nnSearch(*_dataset->point(id), x, y);
71  }
72 
73  template <typename T, typename U, typename V>
74  ResultSetType nnSearch(const QString& id, T x, U y, V z) {
75  validate(); // to make sure that _dataset is not a dangling pointer
76  return nnSearch(*_dataset->point(id), x, y, z);
77  }
78 
83  void invalidate();
84 
89  void validate();
90 
95  void indexOn(const QString& descriptorName);
96 
97 
98 
99  protected:
100  QPointer<DataSetType> _dataset;
101  bool _isViewValid;
102  // should have an associated mutex when using multi-threaded code
103  BaseSearchSpacePool<SearchPointType, DataSetType> _searchSpacePool;
104 
105 
106  void init();
107 
108  // a few helper functions
109  static Filter* createFilter(const QString& filterString);
110  static void bindFilter(const Filter* filter, const DataSetType* dataset);
111  // WARNING: this function modifies the results variable.
112  static SearchResults formatResults(std::priority_queue<SearchPointType>& results);
113 
114 
115  // internal nnsearch methods & helpers
116 
117  void checkPoint(const PointType& p); // needs to be specialized
118  void checkDistance(const DistanceType* dist); // needs to be specialized
119 
130  SearchSpaceType* getSearchSpace(SearchSpaceType* sspace = 0,
131  const Filter* filter = 0,
132  bool spaceOwnsFilter = true);
133 
138  SearchSpaceType* getSearchSpace(SearchSpaceType* sspace,
139  const QString& filterString);
140 
145  ResultSetType nnSearch(const PointType& p,
146  SearchSpaceType* sspace,
147  const DistanceType* dist);
148 
149 
150 };
151 
152 typedef BaseView<DataSet, Point, SearchPoint, DistanceFunction> View;
153 typedef BaseView<FrozenDataSet, FrozenPoint, FrozenSearchPoint, FrozenDistance> FrozenView;
154 typedef BaseResultSet<FrozenSearchPoint, FrozenDataSet> FrozenResultSet;
155 
156 template <>
157 inline void View::checkPoint(const Point& p) {
158  if (p.layout() != _dataset->layout()) {
159  QStringList msg;
160  msg << "Cannot query for point '" << p.name() << "', because it has a different "
161  << "layout than the one from the dataset which the view points at.";
162  throw GaiaException(msg);
163  }
164 }
165 
166 template <>
167 inline void View::checkDistance(const DistanceFunction* dist) {
168  if (dist->layout() != _dataset->layout()) {
169  QStringList msg;
170  msg << "View: cannot use given distance because the DataSet and the DistanceFunction "
171  << "don't share the same layout\n"
172  << "Different descriptors: "
173  << dist->layout().symmetricDifferenceWith(_dataset->layout()).join(", ");
174  throw GaiaException(msg);
175  }
176 }
177 
178 template <>
179 inline void FrozenView::checkPoint(const FrozenPoint& p) {
180  if (p.cols() != _dataset->cols()) {
181  QStringList msg;
182  msg << "Cannot query for point because it has a different dimension "
183  << "than the one from the dataset which the view points at.";
184  throw GaiaException(msg);
185  }
186 }
187 
188 template <>
189 inline void FrozenView::checkDistance(const FrozenDistance* dist) {
190  if (&dist->dataset() != _dataset) {
191  QStringList msg;
192  msg << "View: you can only use a distance which has been created with "
193  << "the same dataset as the one that was used to create this view.";
194  throw GaiaException(msg);
195  }
196 }
197 
198 
199 template <> template <typename T>
200 FrozenResultSet FrozenView::nnSearch(const QString& id, T x) {
201  validate(); // to make sure that _dataset is not a dangling pointer
202  return nnSearch(_dataset->row(_dataset->pointIndex(id)), x);
203 }
204 
205 template <> template <typename T, typename U>
206 FrozenResultSet FrozenView::nnSearch(const QString& id, T x, U y) {
207  validate(); // to make sure that _dataset is not a dangling pointer
208  return nnSearch(_dataset->row(_dataset->pointIndex(id)), x, y);
209 }
210 
211 template <> template <typename T, typename U, typename V>
212 FrozenResultSet FrozenView::nnSearch(const QString& id, T x, U y, V z) {
213  validate(); // to make sure that _dataset is not a dangling pointer
214  return nnSearch(_dataset->row(_dataset->pointIndex(id)), x, y, z);
215 }
216 
217 
218 
219 } // namespace gaia2
220 
221 
222 // include implementation as View is a template class
223 #include "view_impl.h"
224 
225 
226 #endif // GAIA_VIEW_H
Main Gaia namespace, which contains all the library functions.
Definition: addfield.cpp:22
SearchSpaceType * getSearchSpace(SearchSpaceType *sspace=0, const Filter *filter=0, bool spaceOwnsFilter=true)
Returns a valid SearchSpace with associated filter.
Definition: view_impl.h:194
void indexOn(const QString &descriptorName)
This methods creates an index on the given descriptor name, in the hope that future queries using thi...
Definition: view_impl.h:51
void invalidate()
This function is called whenever the DataSet it points to changes, so it knows it needs to recompute ...
Definition: view_impl.h:58
void validate()
This function is called to make sure that the View is valid (ie: its sorting structure and filters ac...
Definition: view_impl.h:64