27 #ifndef DOXYGEN_SHOULD_SKIP_THIS 38 template <
typename T_DATA,
template <
typename >
class ALLOC >
40 const IDatabaseTable< T_DATA, ALLOC >& db) :
41 DBHandler< T_DATA, ALLOC >(),
42 __db(&db), __row(&(db.content())),
43 __end_index(
std::size_t(__row->size())) {
44 GUM_CONSTRUCTOR(IDatabaseTable::Handler);
49 template <
typename T_DATA,
template <
typename >
class ALLOC >
50 INLINE IDatabaseTable< T_DATA, ALLOC >::Handler::Handler(
51 const typename IDatabaseTable< T_DATA, ALLOC >::Handler& h) :
52 DBHandler< T_DATA, ALLOC >(),
53 __db(h.__db), __row(h.__row), __index(h.__index),
54 __begin_index(h.__begin_index), __end_index(h.__end_index) {
55 GUM_CONS_CPY(IDatabaseTable::Handler);
60 template <
typename T_DATA,
template <
typename >
class ALLOC >
61 INLINE IDatabaseTable< T_DATA, ALLOC >::Handler::Handler(
62 typename IDatabaseTable< T_DATA, ALLOC >::Handler&& h) :
63 DBHandler< T_DATA, ALLOC >(),
64 __db(h.__db), __row(h.__row), __index(h.__index),
65 __begin_index(h.__begin_index), __end_index(h.__end_index) {
66 GUM_CONS_MOV(IDatabaseTable::Handler);
71 template <
typename T_DATA,
template <
typename >
class ALLOC >
72 INLINE IDatabaseTable< T_DATA, ALLOC >::Handler::~Handler() {
73 GUM_DESTRUCTOR(IDatabaseTable::Handler);
78 template <
typename T_DATA,
template <
typename >
class ALLOC >
79 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
80 IDatabaseTable< T_DATA, ALLOC >::Handler::
81 operator=(
const typename IDatabaseTable< T_DATA, ALLOC >::Handler& h) {
85 __begin_index = h.__begin_index;
86 __end_index = h.__end_index;
92 template <
typename T_DATA,
template <
typename >
class ALLOC >
93 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
94 IDatabaseTable< T_DATA, ALLOC >::Handler::
95 operator=(
typename IDatabaseTable< T_DATA, ALLOC >::Handler&& h) {
99 __begin_index = h.__begin_index;
100 __end_index = h.__end_index;
106 template <
typename T_DATA,
template <
typename >
class ALLOC >
107 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::const_reference
109 return __row->operator[](__index);
114 template <
typename T_DATA,
template <
typename >
class ALLOC >
115 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::const_pointer
116 IDatabaseTable< T_DATA, ALLOC >::Handler::operator->()
const {
117 return &(__row->operator[](__index));
122 template <
typename T_DATA,
template <
typename >
class ALLOC >
123 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
124 IDatabaseTable< T_DATA, ALLOC >::Handler::operator++() {
131 template <
typename T_DATA,
template <
typename >
class ALLOC >
132 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
133 IDatabaseTable< T_DATA, ALLOC >::Handler::operator--() {
134 if (__index > __begin_index) --__index;
140 template <
typename T_DATA,
template <
typename >
class ALLOC >
141 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
142 IDatabaseTable< T_DATA, ALLOC >::Handler::operator+=(
const std::size_t i) {
149 template <
typename T_DATA,
template <
typename >
class ALLOC >
150 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
151 IDatabaseTable< T_DATA, ALLOC >::Handler::operator-=(
const std::size_t i) {
152 if (__index >= __begin_index + i)
155 __index = __begin_index;
161 template <
typename T_DATA,
template <
typename >
class ALLOC >
164 return __index == handler.__index;
169 template <
typename T_DATA,
template <
typename >
class ALLOC >
172 return __index != handler.__index;
177 template <
typename T_DATA,
template <
typename >
class ALLOC >
178 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::Handler::size()
const {
179 return __end_index - __begin_index;
184 template <
typename T_DATA,
template <
typename >
class ALLOC >
185 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::Handler::DBSize()
const {
186 if (__row !=
nullptr)
187 return __row->size();
189 return std::size_t(0);
194 template <
typename T_DATA,
template <
typename >
class ALLOC >
195 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::const_reference
196 IDatabaseTable< T_DATA, ALLOC >::Handler::rowSafe()
const {
197 if (__index >= __end_index) {
198 GUM_ERROR(OutOfBounds,
"the handler has reached its end");
201 return __row->operator[](__index);
206 template <
typename T_DATA,
template <
typename >
class ALLOC >
207 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::reference
208 IDatabaseTable< T_DATA, ALLOC >::Handler::rowSafe() {
209 if (__index >= __end_index) {
210 GUM_ERROR(OutOfBounds,
"the handler has reached its end");
213 return const_cast< Matrix< T_DATA >*
>(__row)->
operator[](__index);
218 template <
typename T_DATA,
template <
typename >
class ALLOC >
219 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::const_reference
220 IDatabaseTable< T_DATA, ALLOC >::Handler::row()
const {
221 return __row->operator[](__index);
226 template <
typename T_DATA,
template <
typename >
class ALLOC >
227 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::reference
228 IDatabaseTable< T_DATA, ALLOC >::Handler::row() {
229 return const_cast< Matrix< T_DATA >*
>(__row)->
operator[](__index);
234 template <
typename T_DATA,
template <
typename >
class ALLOC >
235 INLINE
void IDatabaseTable< T_DATA, ALLOC >::Handler::nextRow() {
241 template <
typename T_DATA,
template <
typename >
class ALLOC >
242 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::Handler::numRow()
const {
243 return (__index >= __begin_index) ? __index - __begin_index : 0;
247 template <
typename T_DATA,
template <
typename >
class ALLOC >
248 INLINE
bool IDatabaseTable< T_DATA, ALLOC >::Handler::hasRows()
const {
249 return (__index < __end_index);
253 template <
typename T_DATA,
template <
typename >
class ALLOC >
254 INLINE
void IDatabaseTable< T_DATA, ALLOC >::Handler::reset() {
255 __index = __begin_index;
261 template <
typename T_DATA,
template <
typename >
class ALLOC >
262 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler
263 IDatabaseTable< T_DATA, ALLOC >::Handler::begin()
const {
264 Handler handler(*
this);
272 template <
typename T_DATA,
template <
typename >
class ALLOC >
273 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler
274 IDatabaseTable< T_DATA, ALLOC >::Handler::end()
const {
275 Handler handler(*
this);
276 handler.__index = __end_index;
282 template <
typename T_DATA,
template <
typename >
class ALLOC >
284 IDatabaseTable< T_DATA, ALLOC >::Handler::setRange(std::size_t begin,
289 if (__row ==
nullptr) {
290 GUM_ERROR(NullElement,
"the handler does not point to any database");
292 if (end > __row->size()) {
294 "the database has fewer rows (" 295 << __row->size() <<
") than the upper range (" << end
296 <<
") specified to the handler");
299 __begin_index = begin;
306 template <
typename T_DATA,
template <
typename >
class ALLOC >
307 INLINE std::pair< std::size_t, std::size_t >
308 IDatabaseTable< T_DATA, ALLOC >::Handler::range()
const {
309 return std::pair< std::size_t, std::size_t >(__begin_index, __end_index);
314 template <
typename T_DATA,
template <
typename >
class ALLOC >
315 INLINE
const typename IDatabaseTable< T_DATA, ALLOC >::Handler::
317 IDatabaseTable< T_DATA, ALLOC >::Handler::variableNames()
const {
318 return __db->variableNames();
323 template <
typename T_DATA,
template <
typename >
class ALLOC >
325 IDatabaseTable< T_DATA, ALLOC >::Handler::nbVariables()
const {
327 return __db->variableNames().size();
334 template <
typename T_DATA,
template <
typename >
class ALLOC >
335 INLINE
const IDatabaseTable< T_DATA, ALLOC >&
336 IDatabaseTable< T_DATA, ALLOC >::Handler::database()
const {
337 if (__db ==
nullptr) {
339 "The database handler does not point toward a database");
350 template <
typename T_DATA,
template <
typename >
class ALLOC >
351 INLINE
void IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::__attachHandler() {
352 if (this->__db !=
nullptr) { this->__db->__attachHandler(
this); }
357 template <
typename T_DATA,
template <
typename >
class ALLOC >
358 INLINE
void IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::__detachHandler() {
359 if (this->__db !=
nullptr) { this->__db->__detachHandler(
this); }
364 template <
typename T_DATA,
template <
typename >
class ALLOC >
365 INLINE IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::HandlerSafe(
366 const IDatabaseTable< T_DATA, ALLOC >& db) :
367 IDatabaseTable< T_DATA, ALLOC >::Handler(db) {
369 GUM_CONSTRUCTOR(IDatabaseTable::HandlerSafe);
374 template <
typename T_DATA,
template <
typename >
class ALLOC >
375 INLINE IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::HandlerSafe(
376 const typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe& h) :
377 IDatabaseTable< T_DATA, ALLOC >::Handler(h) {
379 GUM_CONS_CPY(IDatabaseTable::HandlerSafe);
384 template <
typename T_DATA,
template <
typename >
class ALLOC >
385 INLINE IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::HandlerSafe(
386 typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&& h) :
387 IDatabaseTable< T_DATA, ALLOC >::Handler(
std::move(h)) {
389 GUM_CONS_MOV(IDatabaseTable::HandlerSafe);
394 template <
typename T_DATA,
template <
typename >
class ALLOC >
395 INLINE IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::~HandlerSafe() {
397 GUM_DESTRUCTOR(IDatabaseTable::HandlerSafe);
402 template <
typename T_DATA,
template <
typename >
class ALLOC >
403 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
404 IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::operator=(
405 const typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe& h) {
406 if (this->__db != h.__db) {
412 IDatabaseTable< T_DATA, ALLOC >::Handler::operator=(h);
418 template <
typename T_DATA,
template <
typename >
class ALLOC >
419 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
420 IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::
421 operator=(
const typename IDatabaseTable< T_DATA, ALLOC >::Handler& h) {
422 return this->operator=(
423 dynamic_cast< const IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
>(h));
428 template <
typename T_DATA,
template <
typename >
class ALLOC >
429 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
430 IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::
431 operator=(
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&& h) {
432 if (this->__db != h.__db) {
438 IDatabaseTable< T_DATA, ALLOC >::Handler::operator=(std::move(h));
444 template <
typename T_DATA,
template <
typename >
class ALLOC >
445 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
446 IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::
447 operator=(
typename IDatabaseTable< T_DATA, ALLOC >::Handler&& h) {
448 return this->operator=(std::move(
449 dynamic_cast< IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
>(h)));
458 template <
typename T_DATA,
template <
typename >
class ALLOC >
459 INLINE ALLOC< T_DATA > IDatabaseTable< T_DATA, ALLOC >::getAllocator()
const {
460 return ALLOC< T_DATA >(*this);
465 template <
typename T_DATA,
template <
typename >
class ALLOC >
466 void IDatabaseTable< T_DATA, ALLOC >::__createEndIterators() {
467 const IDatabaseTable< T_DATA, ALLOC >& db = *
this;
468 ALLOC< iterator > allocator1(*
this);
469 __end = allocator1.allocate(1);
471 allocator1.construct(__end, db);
473 allocator1.deallocate(__end, 1);
477 ALLOC< iterator_safe > allocator2(*
this);
479 __end_safe = allocator2.allocate(1);
481 allocator2.construct(__end_safe, *
this);
483 allocator2.deallocate(__end_safe, 1);
487 allocator1.destroy(__end);
488 allocator1.deallocate(__end, 1);
495 template <
typename T_DATA,
template <
typename >
class ALLOC >
496 template <
template <
typename >
class VARALLOC,
497 template <
typename >
499 IDatabaseTable< T_DATA, ALLOC >::IDatabaseTable(
500 const typename IDatabaseTable< T_DATA, ALLOC >::template MissingValType<
501 MISSALLOC >& missing_symbols,
502 const std::vector< std::string, VARALLOC< std::string > >& var_names,
503 const ALLOC< T_DATA >& alloc) :
504 ALLOC< T_DATA >(alloc),
505 _variable_names(alloc), _rows(alloc), _missing_symbols(alloc),
506 _has_row_missing_val(alloc), __list_of_safe_handlers(alloc) {
508 _variable_names.reserve(var_names.size());
509 for (
const auto& name : var_names)
510 _variable_names.push_back(name);
513 _missing_symbols.reserve(missing_symbols.size());
514 for (
const auto& missing_symbol : missing_symbols)
515 _missing_symbols.push_back(missing_symbol);
518 __createEndIterators();
520 GUM_CONSTRUCTOR(IDatabaseTable);
525 template <
typename T_DATA,
template <
typename >
class ALLOC >
526 IDatabaseTable< T_DATA, ALLOC >::IDatabaseTable(
527 const IDatabaseTable< T_DATA, ALLOC >& from,
528 const typename IDatabaseTable< T_DATA, ALLOC >::allocator_type& alloc) :
529 ALLOC< T_DATA >(alloc),
530 _variable_names(from._variable_names, alloc), _rows(from._rows, alloc),
531 _missing_symbols(from._missing_symbols, alloc),
532 _has_row_missing_val(from._has_row_missing_val, alloc),
533 _max_nb_threads(from._max_nb_threads),
534 _min_nb_rows_per_thread(from._min_nb_rows_per_thread),
535 __list_of_safe_handlers(alloc) {
537 __createEndIterators();
539 GUM_CONS_CPY(IDatabaseTable);
544 template <
typename T_DATA,
template <
typename >
class ALLOC >
545 IDatabaseTable< T_DATA, ALLOC >::IDatabaseTable(
546 const IDatabaseTable< T_DATA, ALLOC >& from) :
547 IDatabaseTable< T_DATA, ALLOC >(from, from.getAllocator()) {}
551 template <
typename T_DATA,
template <
typename >
class ALLOC >
552 IDatabaseTable< T_DATA, ALLOC >::IDatabaseTable(
553 IDatabaseTable< T_DATA, ALLOC >&& from,
554 const typename IDatabaseTable< T_DATA, ALLOC >::allocator_type& alloc) :
555 ALLOC< T_DATA >(alloc),
556 _variable_names(
std::move(from._variable_names), alloc),
557 _rows(
std::move(from._rows), alloc),
558 _missing_symbols(
std::move(from._missing_symbols), alloc),
559 _has_row_missing_val(
std::move(from._has_row_missing_val), alloc),
560 _max_nb_threads(from._max_nb_threads),
561 _min_nb_rows_per_thread(from._min_nb_rows_per_thread),
562 __list_of_safe_handlers(alloc) {
564 __createEndIterators();
566 GUM_CONS_MOV(IDatabaseTable);
571 template <
typename T_DATA,
template <
typename >
class ALLOC >
572 IDatabaseTable< T_DATA, ALLOC >::IDatabaseTable(
573 IDatabaseTable< T_DATA, ALLOC >&& from) :
574 IDatabaseTable< T_DATA, ALLOC >(
std::move(from), from.getAllocator()) {}
578 template <
typename T_DATA,
template <
typename >
class ALLOC >
579 IDatabaseTable< T_DATA, ALLOC >::~IDatabaseTable() {
581 __safe_handlers_mutex.lock();
582 for (
auto handler : __list_of_safe_handlers) {
583 handler->__db =
nullptr;
584 handler->__row =
nullptr;
585 handler->__end_index = 0;
586 handler->__index = 0;
588 __safe_handlers_mutex.unlock();
590 ALLOC< iterator > allocator1(this->getAllocator());
591 allocator1.destroy(__end);
592 allocator1.deallocate(__end, 1);
594 ALLOC< iterator_safe > allocator2(this->getAllocator());
595 allocator2.destroy(__end_safe);
596 allocator2.deallocate(__end_safe, 1);
598 GUM_DESTRUCTOR(IDatabaseTable);
603 template <
typename T_DATA,
template <
typename >
class ALLOC >
604 IDatabaseTable< T_DATA, ALLOC >& IDatabaseTable< T_DATA, ALLOC >::
605 operator=(
const IDatabaseTable< T_DATA, ALLOC >& from) {
608 __safe_handlers_mutex.lock();
609 for (
auto handler : __list_of_safe_handlers) {
610 handler->__db =
nullptr;
611 handler->__row =
nullptr;
612 handler->__end_index = 0;
613 handler->__index = 0;
615 __list_of_safe_handlers.clear();
616 __safe_handlers_mutex.unlock();
619 _variable_names = from._variable_names;
620 _missing_symbols = from._missing_symbols;
621 _has_row_missing_val = from._has_row_missing_val;
622 _max_nb_threads = from._max_nb_threads;
623 _min_nb_rows_per_thread = from._min_nb_rows_per_thread;
626 const std::size_t db_size = _rows.size();
627 __end->__index = db_size;
628 __end->__end_index = db_size;
629 __end_safe->__index = db_size;
630 __end_safe->__end_index = db_size;
638 template <
typename T_DATA,
template <
typename >
class ALLOC >
639 IDatabaseTable< T_DATA, ALLOC >& IDatabaseTable< T_DATA, ALLOC >::
640 operator=(IDatabaseTable< T_DATA, ALLOC >&& from) {
643 __safe_handlers_mutex.lock();
644 for (
auto handler : __list_of_safe_handlers) {
645 handler->__db =
nullptr;
646 handler->__row =
nullptr;
647 handler->__end_index = 0;
648 handler->__index = 0;
650 __safe_handlers_mutex.unlock();
652 _rows = std::move(from._rows);
653 _variable_names = std::move(from._variable_names);
654 _missing_symbols = std::move(from._missing_symbols);
655 _has_row_missing_val = std::move(from._has_row_missing_val);
656 _max_nb_threads = from._max_nb_threads;
657 _min_nb_rows_per_thread = from._min_nb_rows_per_thread;
660 const std::size_t db_size = _rows.size();
661 __end->__index = db_size;
662 __end->__end_index = db_size;
663 __end_safe->__index = db_size;
664 __end_safe->__end_index = db_size;
672 template <
typename T_DATA,
template <
typename >
class ALLOC >
673 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler
674 IDatabaseTable< T_DATA, ALLOC >::begin()
const {
675 return Handler(*
this);
680 template <
typename T_DATA,
template <
typename >
class ALLOC >
681 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe
682 IDatabaseTable< T_DATA, ALLOC >::beginSafe()
const {
683 return HandlerSafe(*
this);
688 template <
typename T_DATA,
template <
typename >
class ALLOC >
689 INLINE
const typename IDatabaseTable< T_DATA, ALLOC >::Handler&
690 IDatabaseTable< T_DATA, ALLOC >::end() const noexcept {
696 template <
typename T_DATA,
template <
typename >
class ALLOC >
697 INLINE
const typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
698 IDatabaseTable< T_DATA, ALLOC >::endSafe() const noexcept {
704 template <
typename T_DATA,
template <
typename >
class ALLOC >
705 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler
706 IDatabaseTable< T_DATA, ALLOC >::handler()
const {
707 return Handler(*
this);
712 template <
typename T_DATA,
template <
typename >
class ALLOC >
713 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe
714 IDatabaseTable< T_DATA, ALLOC >::handlerSafe()
const {
715 return HandlerSafe(*
this);
720 template <
typename T_DATA,
template <
typename >
class ALLOC >
721 INLINE
const typename IDatabaseTable< T_DATA,
722 ALLOC >::template Matrix< T_DATA >&
723 IDatabaseTable< T_DATA, ALLOC >::content() const noexcept {
729 template <
typename T_DATA,
template <
typename >
class ALLOC >
730 bool IDatabaseTable< T_DATA, ALLOC >::hasMissingValues()
const {
731 for (
const auto& status : _has_row_missing_val)
732 if (status == IsMissing::True)
return true;
738 template <
typename T_DATA,
template <
typename >
class ALLOC >
739 INLINE
bool IDatabaseTable< T_DATA, ALLOC >::hasMissingValues(
740 const std::size_t k)
const {
741 return _has_row_missing_val[k] == IsMissing::True;
746 template <
typename T_DATA,
template <
typename >
class ALLOC >
747 INLINE
const std::vector< std::string, ALLOC< std::string > >&
748 IDatabaseTable< T_DATA, ALLOC >::variableNames() const noexcept {
749 return _variable_names;
754 template <
typename T_DATA,
template <
typename >
class ALLOC >
755 template <
template <
typename >
class OTHER_ALLOC >
756 void IDatabaseTable< T_DATA, ALLOC >::setVariableNames(
757 const std::vector< std::string, OTHER_ALLOC< std::string > >& names,
758 const bool from_external_object) {
761 const std::size_t size = names.size();
763 for (std::size_t i = 0; i < size; ++i)
764 variable_names[i] = names[i];
766 this->setVariableNames(variable_names, from_external_object);
771 template <
typename T_DATA,
template <
typename >
class ALLOC >
772 INLINE
const std::string&
773 IDatabaseTable< T_DATA, ALLOC >::variableName(
const std::size_t k)
const {
774 if (_variable_names.size() <= k)
775 GUM_ERROR(OutOfBounds,
"the database does not contain Column #" << k);
776 return _variable_names[k];
781 template <
typename T_DATA,
template <
typename >
class ALLOC >
782 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::columnFromVariableName(
783 const std::string& name)
const {
784 const std::size_t size = _variable_names.size();
785 for (std::size_t i = 0; i < size; ++i)
786 if (_variable_names[i] == name)
return i;
789 "the database contains no column whose name is " << name);
794 template <
typename T_DATA,
template <
typename >
class ALLOC >
796 typename IDatabaseTable< T_DATA, ALLOC >::template DBVector< std::size_t >
797 IDatabaseTable< T_DATA, ALLOC >::columnsFromVariableName(
798 const std::string& name)
const {
799 const std::size_t size = _variable_names.size();
800 DBVector< std::size_t > cols;
801 for (std::size_t i = 0; i < size; ++i)
802 if (_variable_names[i] == name) cols.push_back(i);
806 "the database contains no column whose name is " << name);
813 template <
typename T_DATA,
template <
typename >
class ALLOC >
814 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::nbVariables() const
816 return _variable_names.size();
821 template <
typename T_DATA,
template <
typename >
class ALLOC >
822 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::size() const noexcept {
828 template <
typename T_DATA,
template <
typename >
class ALLOC >
829 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::nbRows() const noexcept {
835 template <
typename T_DATA,
template <
typename >
class ALLOC >
836 INLINE
bool IDatabaseTable< T_DATA, ALLOC >::empty() const noexcept {
837 return _rows.empty();
842 template <
typename T_DATA,
template <
typename >
class ALLOC >
843 void IDatabaseTable< T_DATA, ALLOC >::__updateHandlers(
844 std::size_t new_size)
const {
845 const std::size_t db_size = _rows.size();
847 __safe_handlers_mutex.lock();
848 for (
auto handler : __list_of_safe_handlers) {
849 if ((handler->__end_index == db_size)
850 || (handler->__end_index > new_size)) {
851 handler->__end_index = new_size;
857 __safe_handlers_mutex.unlock();
860 __end->__index = new_size;
861 __end->__end_index = new_size;
862 __end_safe->__index = new_size;
863 __end_safe->__end_index = new_size;
868 template <
typename T_DATA,
template <
typename >
class ALLOC >
869 INLINE
void IDatabaseTable< T_DATA, ALLOC >::__attachHandler(
870 HandlerSafe* handler)
const {
871 __safe_handlers_mutex.lock();
872 __list_of_safe_handlers.push_back(handler);
873 __safe_handlers_mutex.unlock();
878 template <
typename T_DATA,
template <
typename >
class ALLOC >
879 void IDatabaseTable< T_DATA, ALLOC >::__detachHandler(
880 HandlerSafe* handler)
const {
881 __safe_handlers_mutex.lock();
883 for (
auto iter = __list_of_safe_handlers.rbegin();
884 iter != __list_of_safe_handlers.rend();
886 if (*iter == handler) {
887 *iter = __list_of_safe_handlers.back();
888 __list_of_safe_handlers.pop_back();
893 __safe_handlers_mutex.unlock();
898 template <
typename T_DATA,
template <
typename >
class ALLOC >
899 INLINE
bool IDatabaseTable< T_DATA, ALLOC >::_isRowSizeOK(
900 const std::size_t size)
const {
901 return (size == _variable_names.size());
906 template <
typename T_DATA,
template <
typename >
class ALLOC >
907 template <
template <
typename >
class OTHER_ALLOC >
908 void IDatabaseTable< T_DATA, ALLOC >::insertRow(
909 const std::vector< std::string, OTHER_ALLOC< std::string > >& new_row) {
910 const std::size_t size = new_row.size();
911 std::vector< std::string, ALLOC< std::string > > good_typed_row(size);
912 for (std::size_t i = 0; i < size; ++i)
913 good_typed_row[i] = new_row[i];
914 this->insertRow(good_typed_row);
919 template <
typename T_DATA,
template <
typename >
class ALLOC >
920 void IDatabaseTable< T_DATA, ALLOC >::insertRow(
921 typename IDatabaseTable< T_DATA, ALLOC >::template Row< T_DATA >&& new_row,
922 const typename IDatabaseTable< T_DATA, ALLOC >::IsMissing
925 if (!_isRowSizeOK(new_row.size()))
927 "the new row is of size " 929 <<
", which is different from the number of columns " 930 <<
"of the database, i.e., " << _variable_names.size());
932 __updateHandlers(_rows.size() + 1);
933 _rows.push_back(std::move(new_row));
935 _has_row_missing_val.push_back(contains_missing);
944 template <
typename T_DATA,
template <
typename >
class ALLOC >
945 INLINE
void IDatabaseTable< T_DATA, ALLOC >::insertRow(
946 const typename IDatabaseTable< T_DATA, ALLOC >::template Row< T_DATA >& row,
947 const typename IDatabaseTable< T_DATA, ALLOC >::IsMissing
950 typename IDatabaseTable< T_DATA, ALLOC >::template Row< T_DATA >(row),
956 template <
typename T_DATA,
template <
typename >
class ALLOC >
957 void IDatabaseTable< T_DATA, ALLOC >::insertRows(
958 typename IDatabaseTable< T_DATA, ALLOC >::template Matrix< T_DATA >&&
960 const typename IDatabaseTable< T_DATA, ALLOC >::template DBVector<
961 typename IDatabaseTable< T_DATA, ALLOC >::IsMissing >&
962 rows_have_missing_vals) {
963 if (new_rows.empty())
return;
967 if (rows_have_missing_vals.size() != new_rows.size())
970 "the number of new rows (i.e., " 972 <<
") is different from the number of missing values indicators (" 973 << rows_have_missing_vals.size());
976 const std::size_t new_size = new_rows[0].size();
978 for (
const auto& row : new_rows) {
979 if (row.size() != new_size) {
981 "all the new rows do not have the same number of columns");
987 if (!_isRowSizeOK(new_size)) {
991 <<
" columns, which is different from the number of columns " 992 <<
"of the database, i.e., " << _variable_names.size());
995 const std::size_t nb_new_rows = new_rows.size();
996 const std::size_t new_db_size = _rows.size() + nb_new_rows;
998 _rows.reserve(new_db_size);
999 _has_row_missing_val.reserve(new_db_size);
1001 for (std::size_t i = std::size_t(0); i < nb_new_rows; ++i) {
1002 _rows.push_back(std::move(new_rows[i]));
1003 _has_row_missing_val.push_back(rows_have_missing_vals[i]);
1006 __updateHandlers(new_db_size);
1011 template <
typename T_DATA,
template <
typename >
class ALLOC >
1012 void IDatabaseTable< T_DATA, ALLOC >::insertRows(
1013 const typename IDatabaseTable< T_DATA, ALLOC >::template Matrix< T_DATA >&
1015 const typename IDatabaseTable< T_DATA, ALLOC >::template DBVector<
1016 typename IDatabaseTable< T_DATA, ALLOC >::IsMissing >&
1017 rows_have_missing_vals) {
1018 if (new_rows.empty())
return;
1022 if (rows_have_missing_vals.size() != new_rows.size())
1025 "the number of new rows (i.e., " 1027 <<
") is different from the number of missing values indicators (" 1028 << rows_have_missing_vals.size());
1031 const std::size_t new_size = new_rows[0].size();
1033 for (
const auto& row : new_rows) {
1034 if (row.size() != new_size) {
1036 "all the new rows do not have the same number of columns");
1042 std::size_t db_size = _rows.size();
1044 if (!_isRowSizeOK(new_size)) {
1046 "the new rows have " 1048 <<
" columns, which is different from the number of columns " 1049 <<
"of the database, i.e., " << _variable_names.size());
1052 const std::size_t nb_new_rows = new_rows.size();
1053 const std::size_t new_db_size = _rows.size() + nb_new_rows;
1055 _rows.reserve(new_db_size);
1056 _has_row_missing_val.reserve(new_db_size);
1058 for (std::size_t i = std::size_t(0); i < nb_new_rows; ++i) {
1059 _rows.push_back(new_rows[i]);
1060 _has_row_missing_val.push_back(rows_have_missing_vals[i]);
1063 __updateHandlers(db_size);
1068 template <
typename T_DATA,
template <
typename >
class ALLOC >
1069 INLINE
void IDatabaseTable< T_DATA, ALLOC >::eraseRow(std::size_t index) {
1070 const std::size_t db_size = _rows.size();
1072 if (index < db_size) {
1073 __updateHandlers(db_size - 1);
1074 _rows.erase(_rows.begin() + index);
1075 _has_row_missing_val.erase(_has_row_missing_val.begin() + index);
1081 template <
typename T_DATA,
template <
typename >
class ALLOC >
1082 INLINE
void IDatabaseTable< T_DATA, ALLOC >::eraseLastRow() {
1083 const std::size_t db_size = _rows.size();
1086 __updateHandlers(db_size - 1);
1088 _has_row_missing_val.pop_back();
1094 template <
typename T_DATA,
template <
typename >
class ALLOC >
1095 INLINE
void IDatabaseTable< T_DATA, ALLOC >::eraseFirstRow() {
1096 const std::size_t db_size = _rows.size();
1099 __updateHandlers(db_size - 1);
1100 _rows.erase(_rows.begin());
1101 _has_row_missing_val.erase(_has_row_missing_val.begin());
1107 template <
typename T_DATA,
template <
typename >
class ALLOC >
1108 INLINE
void IDatabaseTable< T_DATA, ALLOC >::eraseAllRows() {
1109 __updateHandlers(0);
1111 _has_row_missing_val.clear();
1116 template <
typename T_DATA,
template <
typename >
class ALLOC >
1118 IDatabaseTable< T_DATA, ALLOC >::eraseFirstRows(
const std::size_t nb_rows) {
1119 const std::size_t db_size = _rows.size();
1121 if (nb_rows >= db_size) {
1124 __updateHandlers(db_size - nb_rows);
1125 _rows.erase(_rows.begin(), _rows.begin() + nb_rows);
1126 _has_row_missing_val.erase(_has_row_missing_val.begin(),
1127 _has_row_missing_val.begin() + nb_rows);
1133 template <
typename T_DATA,
template <
typename >
class ALLOC >
1135 IDatabaseTable< T_DATA, ALLOC >::eraseLastRows(
const std::size_t nb_rows) {
1136 const std::size_t db_size = _rows.size();
1138 if (nb_rows >= db_size) {
1141 __updateHandlers(db_size - nb_rows);
1142 _rows.erase(_rows.begin() + (db_size - nb_rows), _rows.begin() + db_size);
1143 _has_row_missing_val.erase(_has_row_missing_val.begin()
1144 + (db_size - nb_rows),
1145 _has_row_missing_val.begin() + db_size);
1151 template <
typename T_DATA,
template <
typename >
class ALLOC >
1152 INLINE
void IDatabaseTable< T_DATA, ALLOC >::eraseRows(std::size_t deb,
1156 const std::size_t db_size = _rows.size();
1158 if (end >= db_size) {
1159 if (deb >= db_size) {
1162 eraseLastRows(db_size - deb);
1165 __updateHandlers(db_size - (end - deb));
1166 _rows.erase(_rows.begin() + deb, _rows.begin() + end);
1167 _has_row_missing_val.erase(_has_row_missing_val.begin() + deb,
1168 _has_row_missing_val.begin() + end);
1174 template <
typename T_DATA,
template <
typename >
class ALLOC >
1175 INLINE
void IDatabaseTable< T_DATA, ALLOC >::clear() {
1176 __updateHandlers(0);
1178 _has_row_missing_val.clear();
1179 _variable_names.clear();
1184 template <
typename T_DATA,
template <
typename >
class ALLOC >
1185 INLINE
const std::vector< std::string, ALLOC< std::string > >&
1186 IDatabaseTable< T_DATA, ALLOC >::missingSymbols()
const {
1187 return _missing_symbols;
1192 template <
typename T_DATA,
template <
typename >
class ALLOC >
1193 void IDatabaseTable< T_DATA, ALLOC >::setMaxNbThreads(
1194 const std::size_t nb)
const {
1195 if (nb == std::size_t(0))
1196 _max_nb_threads = std::size_t(1);
1198 _max_nb_threads = nb;
1203 template <
typename T_DATA,
template <
typename >
class ALLOC >
1204 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::nbThreads()
const {
1205 return _max_nb_threads;
1211 template <
typename T_DATA,
template <
typename >
class ALLOC >
1212 void IDatabaseTable< T_DATA, ALLOC >::setMinNbRowsPerThread(
1213 const std::size_t nb)
const {
1214 if (nb == std::size_t(0))
1215 _min_nb_rows_per_thread = std::size_t(1);
1217 _min_nb_rows_per_thread = nb;
1222 template <
typename T_DATA,
template <
typename >
class ALLOC >
1224 IDatabaseTable< T_DATA, ALLOC >::minNbRowsPerThread()
const {
1225 return _min_nb_rows_per_thread;
1230 template <
template <
typename >
class ALLOC >
1231 void IDatabaseTableInsert4DBCell< ALLOC, true >::insertRows(
1232 const typename IDatabaseTableInsert4DBCell< ALLOC, true >::
1234 for (
const auto& new_row : new_rows)
1235 this->insertRow(new_row);
1240 template <
template <
typename >
class ALLOC >
1241 void IDatabaseTableInsert4DBCell< ALLOC, false >::insertRows(
1242 const typename IDatabaseTableInsert4DBCell< ALLOC, false >::
1244 for (
const auto& new_row : new_rows)
1245 this->insertRow(new_row);
1250 template <
typename T_DATA,
template <
typename >
class ALLOC >
1252 IDatabaseTable< T_DATA, ALLOC >::setAllRowsWeight(
const double new_weight) {
1255 std::vector< std::pair< std::size_t, std::size_t > > ranges;
1256 const std::size_t db_size = nbRows();
1257 std::size_t nb_threads = db_size / _min_nb_rows_per_thread;
1260 else if (nb_threads > _max_nb_threads)
1261 nb_threads = _max_nb_threads;
1262 std::size_t nb_rows_per_thread = db_size / nb_threads;
1263 std::size_t rest_rows = db_size - nb_rows_per_thread * nb_threads;
1267 std::size_t begin_index = std::size_t(0);
1268 for (std::size_t i = std::size_t(0); i < nb_threads; ++i) {
1269 std::size_t end_index = begin_index + nb_rows_per_thread;
1270 if (rest_rows != std::size_t(0)) {
1275 std::pair< std::size_t, std::size_t >(begin_index, end_index));
1276 begin_index = end_index;
1284 for (std::size_t i = std::size_t(0); i < nb_threads; ++i) {
1285 # pragma omp parallel num_threads(int(nb_threads)) 1289 const std::size_t begin_index = ranges[this_thread].first;
1290 const std::size_t end_index = ranges[this_thread].second;
1292 for (std::size_t i = begin_index; i < end_index; ++i) {
1293 _rows[i].setWeight(new_weight);
unsigned int getThreadNumber()
Get the calling thread id.
void swap(HashTable< LpCol, double > *&a, HashTable< LpCol, double > *&b)
Swap the addresses of two pointers to hashTables.
gum is the global namespace for all aGrUM entities
bool operator==(const TiXmlString &a, const TiXmlString &b)
Handler(const IDatabaseTable< T_DATA, ALLOC > &db)
default constructor
LpExpr operator*(const SCALAR &lhs, const LpCol &rhs)
Overload of operator * between a scalar and a variable.
bool operator!=(const TiXmlString &a, const TiXmlString &b)
The common class for the tabular database tables.
#define GUM_ERROR(type, msg)