aGrUM  0.14.2
DBTranslatorSet_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
25 #ifndef DOXYGEN_SHOULD_SKIP_THIS
26 
27 namespace gum {
28 
29  namespace learning {
30 
32  template < template < typename > class ALLOC >
35  return __columns.get_allocator();
36  }
37 
38 
40  template < template < typename > class ALLOC >
42  ALLOC< DBTranslator< ALLOC > > allocator(this->getAllocator());
43  for (auto translator : __translators) {
44  allocator.destroy(translator);
45  allocator.deallocate(translator, 1);
46  }
47 
48  __translators.clear();
49  __columns.clear();
50  __highest_column = std::size_t(0);
51  }
52 
53 
55  template < template < typename > class ALLOC >
56  void DBTranslatorSet< ALLOC >::__copy(
57  const DBTranslatorSet< ALLOC >& from,
58  const typename DBTranslatorSet< ALLOC >::allocator_type& alloc) {
59  if (__translators.size() != 0) clear();
60 
61  // resize the vectors used in the set. First, we reserve new memory. This
62  // will keep the DBTranslatorSet in a correct state, even if the memory
63  // allocation fails
64  const std::size_t size = from.__translators.size();
65  __translators.reserve(size);
66  __columns.reserve(size);
67  __translators.resize(size);
68  __columns.resize(size);
69 
70  std::size_t i;
71  try {
72  for (i = std::size_t(0); i < size; ++i) {
73  __translators[i] = from.__translators[i]->clone(alloc);
74  __columns[i] = from.__columns[i];
75  }
76  } catch (...) {
77  __translators.resize(i);
78  clear();
79  throw;
80  }
81 
82  __highest_column = from.__highest_column;
83  }
84 
85 
87  template < template < typename > class ALLOC >
89  const typename DBTranslatorSet< ALLOC >::allocator_type& alloc) :
90  __translators(alloc),
91  __columns(allocator_type(alloc)) {
92  GUM_CONSTRUCTOR(DBTranslatorSet);
93  }
94 
95 
97  template < template < typename > class ALLOC >
99  const DBTranslatorSet< ALLOC >& from,
100  const typename DBTranslatorSet< ALLOC >::allocator_type& alloc) :
101  __translators(alloc),
102  __columns(alloc) {
103  __copy(from, alloc);
104 
105  GUM_CONS_CPY(DBTranslatorSet);
106  }
107 
108 
110  template < template < typename > class ALLOC >
112  const DBTranslatorSet< ALLOC >& from) :
113  DBTranslatorSet< ALLOC >(from, from.getAllocator()) {}
114 
115 
117  template < template < typename > class ALLOC >
119  DBTranslatorSet< ALLOC >&& from,
120  const typename DBTranslatorSet< ALLOC >::allocator_type& alloc) :
121  __translators(std::move(from.__translators), alloc),
122  __columns(std::move(from.__columns), alloc),
123  __highest_column(from.__highest_column) {
124  GUM_CONS_MOV(DBTranslatorSet);
125  }
126 
127 
129  template < template < typename > class ALLOC >
130  INLINE
131  DBTranslatorSet< ALLOC >::DBTranslatorSet(DBTranslatorSet< ALLOC >&& from) :
132  DBTranslatorSet< ALLOC >(from, from.getAllocator()) {}
133 
134 
136  template < template < typename > class ALLOC >
137  DBTranslatorSet< ALLOC >* DBTranslatorSet< ALLOC >::clone(
138  const typename DBTranslatorSet< ALLOC >::allocator_type& alloc) const {
139  ALLOC< DBTranslatorSet< ALLOC > > allocator(alloc);
140  DBTranslatorSet< ALLOC >* set = allocator.allocate(1);
141  try {
142  allocator.construct(set, *this, alloc);
143  } catch (...) {
144  allocator.deallocate(set, 1);
145  throw;
146  }
147  return set;
148  }
149 
150 
152  template < template < typename > class ALLOC >
153  DBTranslatorSet< ALLOC >* DBTranslatorSet< ALLOC >::clone() const {
154  return clone(this->getAllocator());
155  }
156 
157 
159  template < template < typename > class ALLOC >
161  clear();
162  GUM_DESTRUCTOR(DBTranslatorSet);
163  }
164 
165 
167  template < template < typename > class ALLOC >
168  DBTranslatorSet< ALLOC >& DBTranslatorSet< ALLOC >::
169  operator=(const DBTranslatorSet< ALLOC >& from) {
170  if (this != &from) {
171  clear();
172  __copy(from, this->getAllocator());
173  }
174 
175  return *this;
176  }
177 
178 
180  template < template < typename > class ALLOC >
181  INLINE DBTranslatorSet< ALLOC >& DBTranslatorSet< ALLOC >::
182  operator=(DBTranslatorSet< ALLOC >&& from) {
183  if (this != &from) {
184  clear();
185  __translators = std::move(from.__translators);
186  __columns = std::move(from.__columns);
187  __highest_column = from.__highest_column;
188  }
189 
190  return *this;
191  }
192 
193 
195  template < template < typename > class ALLOC >
196  INLINE DBTranslator< ALLOC >& DBTranslatorSet< ALLOC >::
197  operator[](const std::size_t k) {
198  return *(__translators[k]);
199  }
200 
201 
203  template < template < typename > class ALLOC >
204  INLINE const DBTranslator< ALLOC >& DBTranslatorSet< ALLOC >::
205  operator[](const std::size_t k) const {
206  return *(__translators[k]);
207  }
208 
209 
211  template < template < typename > class ALLOC >
212  template < template < template < typename > class > class Translator >
213  std::size_t DBTranslatorSet< ALLOC >::insertTranslator(
214  const Translator< ALLOC >& translator,
215  const std::size_t column,
216  const bool unique_column) {
217  // if the unique_column parameter is set to true and there exists already
218  // another translator that parses the column, raise a DuplicateElement
219  // exception
220  const std::size_t size = __translators.size();
221  if (unique_column) {
222  for (std::size_t i = std::size_t(0); i < size; ++i) {
223  if (__columns[i] == column)
224  GUM_ERROR(DuplicateElement,
225  "There already exists a DBTranslator that parses Column"
226  << column);
227  }
228  }
229 
230  // reserve some place for the new translator
231  __translators.reserve(size + 1);
232  __columns.reserve(size + 1);
233 
234  // create and add the new translator
235  ALLOC< DBTranslator< ALLOC > > allocator(this->getAllocator());
236  DBTranslator< ALLOC >* new_translator = translator.clone(allocator);
237 
238  __translators.resize(size + 1);
239  __columns.resize(size + 1);
240  __translators[size] = new_translator;
241  __columns[size] = column;
242 
243  // update the highest column
244  if (column > __highest_column) __highest_column = column;
245 
246  return size;
247  }
248 
249 
251  template < template < typename > class ALLOC >
252  template < template < typename > class XALLOC >
254  const Variable& var,
255  const std::size_t column,
256  const std::vector< std::string, XALLOC< std::string > >& missing_symbols,
257  const bool unique_column) {
258  // create the translatator, depending on the type of the variable
259  switch (var.varType()) {
260  case VarType::Labelized: {
261  const LabelizedVariable& xvar =
262  static_cast< const LabelizedVariable& >(var);
263  DBTranslator4LabelizedVariable< ALLOC > translator(xvar,
264  missing_symbols);
265  return insertTranslator(translator, column, unique_column);
266  }
267 
268  case VarType::Discretized: {
269  const IDiscretizedVariable& xvar =
270  static_cast< const IDiscretizedVariable& >(var);
271  DBTranslator4DiscretizedVariable< ALLOC > translator(xvar,
272  missing_symbols);
273  return insertTranslator(translator, column, unique_column);
274  }
275 
276  case VarType::Range: {
277  const RangeVariable& xvar = static_cast< const RangeVariable& >(var);
278  DBTranslator4RangeVariable< ALLOC > translator(xvar, missing_symbols);
279  return insertTranslator(translator, column, unique_column);
280  }
281 
282  case VarType::Continuous: {
283  const IContinuousVariable& xvar =
284  static_cast< const IContinuousVariable& >(var);
285  DBTranslator4ContinuousVariable< ALLOC > translator(xvar,
286  missing_symbols);
287  return insertTranslator(translator, column, unique_column);
288  }
289 
290  default:
291  GUM_ERROR(NotImplementedYet,
292  "The insertion of the translator for Variable "
293  << var.name()
294  << " is impossible because a translator "
295  "for such variable is not implemented yet");
296  }
297  }
298 
299 
301  template < template < typename > class ALLOC >
303  const Variable& var, const std::size_t column, const bool unique_column) {
304  const std::vector< std::string, ALLOC< std::string > > missing;
305  return this->insertTranslator(var, column, missing, unique_column);
306  }
307 
308 
310  template < template < typename > class ALLOC >
311  void DBTranslatorSet< ALLOC >::eraseTranslator(const std::size_t k,
312  const bool k_is_input_col) {
313  ALLOC< DBTranslator< ALLOC > > allocator(this->getAllocator());
314  const std::size_t nb_trans = __translators.size();
315 
316  if (!k_is_input_col) {
317  if (nb_trans < k) return;
318 
319  // remove the translator and its corresponding column
320  allocator.destroy(__translators[k]);
321  allocator.deallocate(__translators[k], 1);
322 
323  const std::size_t colk = __columns[k];
324  __translators.erase(__translators.begin() + k);
325  __columns.erase(__columns.begin() + k);
326 
327  // if the highest column index corresponded to the kth translator,
328  // we must recomput it
329  if (__highest_column == colk) {
330  __highest_column = std::size_t(0);
331  for (const auto col : __columns)
332  if (__highest_column < col) __highest_column = col;
333  }
334  } else {
335  // remove all the translators parsing the kth column
336  auto iter_trans = __translators.rbegin();
337  bool translator_found = false;
338  for (auto iter_col = __columns.rbegin(); iter_col != __columns.rend();
339  ++iter_col, ++iter_trans) {
340  if (*iter_col == k) {
341  // remove the translator and its corresponding column
342  allocator.destroy(*iter_trans);
343  allocator.deallocate(*iter_trans, 1);
344 
345  __translators.erase((iter_trans + 1).base());
346  __columns.erase((iter_col + 1).base());
347  translator_found = true;
348  }
349  }
350 
351  // if the highest column index corresponded to one of the translators
352  // removed, we must recompute it
353  if (translator_found && (k == __highest_column)) {
354  __highest_column = std::size_t(0);
355  for (const auto col : __columns)
356  if (__highest_column < col) __highest_column = col;
357  }
358  }
359  }
360 
361 
363  template < template < typename > class ALLOC >
364  template < template < typename > class OTHER_ALLOC >
365  INLINE DBTranslatedValue DBTranslatorSet< ALLOC >::translate(
366  const std::vector< std::string, OTHER_ALLOC< std::string > >& row,
367  const std::size_t k) const {
368  return __translators[k]->translate(row[__columns[k]]);
369  }
370 
371 
373  template < template < typename > class ALLOC >
374  template < template < typename > class OTHER_ALLOC >
375  INLINE DBTranslatedValue DBTranslatorSet< ALLOC >::translateSafe(
376  const std::vector< std::string, OTHER_ALLOC< std::string > >& row,
377  const std::size_t k) const {
378  if (__translators.size() <= k)
379  GUM_ERROR(UndefinedElement, "Translator #" << k << " could not be found");
380  return __translators[k]->translate(row[__columns[k]]);
381  }
382 
383 
385  template < template < typename > class ALLOC >
386  INLINE std::string DBTranslatorSet< ALLOC >::translateBack(
387  const DBTranslatedValue translated_val, const std::size_t k) const {
388  return __translators[k]->translateBack(translated_val);
389  }
390 
391 
393  template < template < typename > class ALLOC >
395  const DBTranslatedValue translated_val, const std::size_t k) const {
396  if (__translators.size() <= k)
397  GUM_ERROR(UndefinedElement, "Translator #" << k << "could not be found");
398  return __translators[k]->translateBack(translated_val);
399  }
400 
401 
402  // indicates whether the kth translator considers a translated_val
403  // as a missing value
404  template < template < typename > class ALLOC >
406  const DBTranslatedValue translated_val, const std::size_t k) const {
407  return __translators[k]->isMissingValue(translated_val);
408  }
409 
410 
411  // indicates whether the kth translator considers a translated_val
412  // as a missing value
413  template < template < typename > class ALLOC >
415  const DBTranslatedValue translated_val, const std::size_t k) const {
416  if (__translators.size() <= k)
417  GUM_ERROR(UndefinedElement, "Translator #" << k << "could not be found");
418  return __translators[k]->isMissingValue(translated_val);
419  }
420 
421 
423  template < template < typename > class ALLOC >
424  INLINE DBTranslator< ALLOC >&
425  DBTranslatorSet< ALLOC >::translator(const std::size_t k) {
426  return *(__translators[k]);
427  }
428 
429 
431  template < template < typename > class ALLOC >
432  INLINE const DBTranslator< ALLOC >&
433  DBTranslatorSet< ALLOC >::translator(const std::size_t k) const {
434  return *(__translators[k]);
435  }
436 
437 
439  template < template < typename > class ALLOC >
440  INLINE DBTranslator< ALLOC >&
441  DBTranslatorSet< ALLOC >::translatorSafe(const std::size_t k) {
442  if (__translators.size() <= k)
443  GUM_ERROR(UndefinedElement, "Translator #" << k << "could not be found");
444  return *(__translators[k]);
445  }
446 
447 
449  template < template < typename > class ALLOC >
450  INLINE const DBTranslator< ALLOC >&
451  DBTranslatorSet< ALLOC >::translatorSafe(const std::size_t k) const {
452  if (__translators.size() <= k)
453  GUM_ERROR(UndefinedElement, "Translator #" << k << "could not be found");
454  return *(__translators[k]);
455  }
456 
457 
459  template < template < typename > class ALLOC >
460  INLINE std::size_t
461  DBTranslatorSet< ALLOC >::domainSize(const std::size_t k) const {
462  return __translators[k]->domainSize();
463  }
464 
465 
467  template < template < typename > class ALLOC >
468  INLINE std::size_t
469  DBTranslatorSet< ALLOC >::domainSizeSafe(const std::size_t k) const {
470  if (__translators.size() <= k)
471  GUM_ERROR(UndefinedElement, "Variable #" << k << "could not be found");
472  return __translators[k]->domainSize();
473  }
474 
475 
477  template < template < typename > class ALLOC >
478  INLINE const Variable&
479  DBTranslatorSet< ALLOC >::variable(const std::size_t k) const {
480  return *(__translators[k]->variable());
481  }
482 
483 
485  template < template < typename > class ALLOC >
486  INLINE const Variable&
487  DBTranslatorSet< ALLOC >::variableSafe(const std::size_t k) const {
488  if (__translators.size() <= k)
489  GUM_ERROR(UndefinedElement, "Variable #" << k << "could not be found");
490  return *(__translators[k]->variable());
491  }
492 
493 
494  // indicates whether a reordering is needed to make the kth translator
495  // sorted by lexicographical order
496  template < template < typename > class ALLOC >
497  INLINE bool
498  DBTranslatorSet< ALLOC >::needsReordering(const std::size_t k) const {
499  return __translators[k]->needsReordering();
500  }
501 
502 
503  // indicates whether a reordering is needed to make the kth translator
504  // sorted by lexicographical order
505  template < template < typename > class ALLOC >
506  INLINE bool
507  DBTranslatorSet< ALLOC >::needsReorderingSafe(const std::size_t k) const {
508  if (__translators.size() <= k)
509  GUM_ERROR(UndefinedElement, "Variable #" << k << "could not be found");
510  return __translators[k]->needsReordering();
511  }
512 
513 
514  // performs a reordering of the dictionary and returns a mapping
515  // from the old translated values to the new ones.
516  template < template < typename > class ALLOC >
517  INLINE HashTable< std::size_t,
518  std::size_t,
519  ALLOC< std::pair< std::size_t, std::size_t > > >
520  DBTranslatorSet< ALLOC >::reorder(const std::size_t k) {
521  return __translators[k]->reorder();
522  }
523 
524 
525  // performs a reordering of the dictionary and returns a mapping
526  // from the old translated values to the new ones.
527  template < template < typename > class ALLOC >
528  INLINE HashTable< std::size_t,
529  std::size_t,
530  ALLOC< std::pair< std::size_t, std::size_t > > >
531  DBTranslatorSet< ALLOC >::reorderSafe(const std::size_t k) {
532  if (__translators.size() <= k)
533  GUM_ERROR(UndefinedElement, "Variable #" << k << "could not be found");
534  return __translators[k]->reorder();
535  }
536 
537 
540  template < template < typename > class ALLOC >
541  INLINE std::size_t
542  DBTranslatorSet< ALLOC >::inputColumn(const std::size_t k) const {
543  return __columns[k];
544  }
545 
546 
549  template < template < typename > class ALLOC >
550  INLINE std::size_t
551  DBTranslatorSet< ALLOC >::inputColumnSafe(const std::size_t k) const {
552  if (__translators.size() <= k)
553  GUM_ERROR(UndefinedElement, "Column #" << k << "could not be found");
554  return __columns[k];
555  }
556 
557 
559  template < template < typename > class ALLOC >
560  INLINE std::size_t DBTranslatorSet< ALLOC >::highestInputColumn() const {
561  return __highest_column;
562  }
563 
564 
566  template < template < typename > class ALLOC >
567  INLINE std::size_t DBTranslatorSet< ALLOC >::nbTranslators() const {
568  return __columns.size();
569  }
570 
571 
573  template < template < typename > class ALLOC >
574  INLINE std::size_t DBTranslatorSet< ALLOC >::size() const {
575  return __columns.size();
576  }
577 
579  template < template < typename > class ALLOC >
580  INLINE const
581  std::vector< DBTranslator< ALLOC >*, ALLOC< DBTranslator< ALLOC >* > >&
583  return __translators;
584  }
585 
586  } /* namespace learning */
587 
588 } /* namespace gum */
589 
590 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
HashTable< std::size_t, std::size_t, ALLOC< std::pair< std::size_t, std::size_t > > > reorder(const std::size_t k)
performs a reordering of the dictionary and returns a mapping from the old translated values to the n...
const Variable & variable(const std::size_t k) const
returns the variable stored into the kth translator
const std::vector< DBTranslator< ALLOC > *, ALLOC< DBTranslator< ALLOC > *> > & translators() const
returns the set of translators
void eraseTranslator(const std::size_t k, const bool k_is_input_col=false)
erases either the kth translator or those parsing the kth column of the input database ...
DBTranslatorSet< ALLOC > & operator=(const DBTranslatorSet< ALLOC > &from)
copy operator
std::string translateBack(const DBTranslatedValue translated_val, const std::size_t k) const
returns the original string that was translated into translated_val
const Variable & variableSafe(const std::size_t k) const
returns the variable stored into the kth translator
std::size_t domainSizeSafe(const std::size_t k) const
returns the domain size of the variable stored into the kth translator
std::size_t highestInputColumn() const
returns the largest input database column index read by the translators
DBTranslator< ALLOC > & translatorSafe(const std::size_t k)
returns the kth translator
STL namespace.
typename DBTranslator< ALLOC >::allocator_type allocator_type
type for the allocators passed in arguments of methods
std::size_t inputColumnSafe(const std::size_t k) const
returns the column of the input database that will be read by the kth translator
std::size_t nbTranslators() const
returns the number of translators stored into the set
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
DBTranslatorSet(const allocator_type &alloc=allocator_type())
default constructor
DBTranslator< ALLOC > & operator[](const std::size_t k)
returns the kth translator
std::size_t domainSize(const std::size_t k) const
returns the domain size of the variable stored into the kth translator
DBTranslator< ALLOC > & translator(const std::size_t k)
returns the kth translator
bool isMissingValueSafe(const DBTranslatedValue translated_val, const std::size_t k) const
similar to method isMissingValue, except that it checks that the kth translator exists ...
allocator_type getAllocator() const
returns the allocator used by the translator set
std::size_t insertTranslator(const Translator< ALLOC > &translator, const std::size_t column, const bool unique_column=true)
inserts a new translator at the end of the translator set
bool needsReordering(const std::size_t k) const
indicates whether a reordering is needed to make the kth translator sorted
virtual ~DBTranslatorSet()
destructor
std::size_t inputColumn(const std::size_t k) const
returns the column of the input database that will be read by the kth translator
std::string translateBackSafe(const DBTranslatedValue translated_val, const std::size_t k) const
similar to method translateBack, except that it checks that the kth translator exists ...
std::size_t size() const
returns the number of translators stored into the set
DBTranslatedValue translateSafe(const std::vector< std::string, OTHER_ALLOC< std::string > > &row, const std::size_t k) const
similar to method translate, except that it checks that the kth translator exists ...
bool needsReorderingSafe(const std::size_t k) const
same as method needsReordering but checks that the kth translator exists
DBTranslatedValue translate(const std::vector< std::string, OTHER_ALLOC< std::string > > &row, const std::size_t k) const
ask the kth translator to translate a string in a row of the database
void clear()
remove all the translators
HashTable< std::size_t, std::size_t, ALLOC< std::pair< std::size_t, std::size_t > > > reorderSafe(const std::size_t k)
same as method reorder but checks that the kth translator exists
virtual DBTranslatorSet< ALLOC > * clone() const
virtual copy constructor
bool isMissingValue(const DBTranslatedValue translated_val, const std::size_t k) const
indicates whether the kth translator considers a translated_val as a missing value ...
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52