30 #ifndef DOXYGEN_SHOULD_SKIP_THIS 41 template <
typename T_DATA,
template <
typename >
class ALLOC >
43 const IDatabaseTable< T_DATA, ALLOC >& db) :
44 DBHandler< T_DATA, ALLOC >(),
45 __db(&db), __row(&(db.content())),
46 __end_index(
std::size_t(__row->size())) {
47 GUM_CONSTRUCTOR(IDatabaseTable::Handler);
52 template <
typename T_DATA,
template <
typename >
class ALLOC >
53 INLINE IDatabaseTable< T_DATA, ALLOC >::Handler::Handler(
54 const typename IDatabaseTable< T_DATA, ALLOC >::Handler& h) :
55 DBHandler< T_DATA, ALLOC >(),
56 __db(h.__db), __row(h.__row), __index(h.__index),
57 __begin_index(h.__begin_index), __end_index(h.__end_index) {
58 GUM_CONS_CPY(IDatabaseTable::Handler);
63 template <
typename T_DATA,
template <
typename >
class ALLOC >
64 INLINE IDatabaseTable< T_DATA, ALLOC >::Handler::Handler(
65 typename IDatabaseTable< T_DATA, ALLOC >::Handler&& h) :
66 DBHandler< T_DATA, ALLOC >(),
67 __db(h.__db), __row(h.__row), __index(h.__index),
68 __begin_index(h.__begin_index), __end_index(h.__end_index) {
69 GUM_CONS_MOV(IDatabaseTable::Handler);
74 template <
typename T_DATA,
template <
typename >
class ALLOC >
75 INLINE IDatabaseTable< T_DATA, ALLOC >::Handler::~Handler() {
76 GUM_DESTRUCTOR(IDatabaseTable::Handler);
81 template <
typename T_DATA,
template <
typename >
class ALLOC >
82 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
83 IDatabaseTable< T_DATA, ALLOC >::Handler::
84 operator=(
const typename IDatabaseTable< T_DATA, ALLOC >::Handler& h) {
88 __begin_index = h.__begin_index;
89 __end_index = h.__end_index;
95 template <
typename T_DATA,
template <
typename >
class ALLOC >
96 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
97 IDatabaseTable< T_DATA, ALLOC >::Handler::
98 operator=(
typename IDatabaseTable< T_DATA, ALLOC >::Handler&& h) {
102 __begin_index = h.__begin_index;
103 __end_index = h.__end_index;
109 template <
typename T_DATA,
template <
typename >
class ALLOC >
110 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::const_reference
112 return __row->operator[](__index);
117 template <
typename T_DATA,
template <
typename >
class ALLOC >
118 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::const_pointer
119 IDatabaseTable< T_DATA, ALLOC >::Handler::operator->()
const {
120 return &(__row->operator[](__index));
125 template <
typename T_DATA,
template <
typename >
class ALLOC >
126 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
127 IDatabaseTable< T_DATA, ALLOC >::Handler::operator++() {
134 template <
typename T_DATA,
template <
typename >
class ALLOC >
135 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
136 IDatabaseTable< T_DATA, ALLOC >::Handler::operator--() {
137 if (__index > __begin_index) --__index;
143 template <
typename T_DATA,
template <
typename >
class ALLOC >
144 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
145 IDatabaseTable< T_DATA, ALLOC >::Handler::operator+=(
const std::size_t i) {
152 template <
typename T_DATA,
template <
typename >
class ALLOC >
153 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler&
154 IDatabaseTable< T_DATA, ALLOC >::Handler::operator-=(
const std::size_t i) {
155 if (__index >= __begin_index + i)
158 __index = __begin_index;
164 template <
typename T_DATA,
template <
typename >
class ALLOC >
167 return __index == handler.__index;
172 template <
typename T_DATA,
template <
typename >
class ALLOC >
175 return __index != handler.__index;
180 template <
typename T_DATA,
template <
typename >
class ALLOC >
181 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::Handler::size()
const {
182 return __end_index - __begin_index;
187 template <
typename T_DATA,
template <
typename >
class ALLOC >
188 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::Handler::DBSize()
const {
189 if (__row !=
nullptr)
190 return __row->size();
192 return std::size_t(0);
197 template <
typename T_DATA,
template <
typename >
class ALLOC >
198 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::const_reference
199 IDatabaseTable< T_DATA, ALLOC >::Handler::rowSafe()
const {
200 if (__index >= __end_index) {
201 GUM_ERROR(OutOfBounds,
"the handler has reached its end");
204 return __row->operator[](__index);
209 template <
typename T_DATA,
template <
typename >
class ALLOC >
210 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::reference
211 IDatabaseTable< T_DATA, ALLOC >::Handler::rowSafe() {
212 if (__index >= __end_index) {
213 GUM_ERROR(OutOfBounds,
"the handler has reached its end");
216 return const_cast< Matrix< T_DATA >*
>(__row)->
operator[](__index);
221 template <
typename T_DATA,
template <
typename >
class ALLOC >
222 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::const_reference
223 IDatabaseTable< T_DATA, ALLOC >::Handler::row()
const {
224 return __row->operator[](__index);
229 template <
typename T_DATA,
template <
typename >
class ALLOC >
230 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler::reference
231 IDatabaseTable< T_DATA, ALLOC >::Handler::row() {
232 return const_cast< Matrix< T_DATA >*
>(__row)->
operator[](__index);
237 template <
typename T_DATA,
template <
typename >
class ALLOC >
238 INLINE
void IDatabaseTable< T_DATA, ALLOC >::Handler::nextRow() {
244 template <
typename T_DATA,
template <
typename >
class ALLOC >
245 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::Handler::numRow()
const {
246 return (__index >= __begin_index) ? __index - __begin_index : 0;
250 template <
typename T_DATA,
template <
typename >
class ALLOC >
251 INLINE
bool IDatabaseTable< T_DATA, ALLOC >::Handler::hasRows()
const {
252 return (__index < __end_index);
256 template <
typename T_DATA,
template <
typename >
class ALLOC >
257 INLINE
void IDatabaseTable< T_DATA, ALLOC >::Handler::reset() {
258 __index = __begin_index;
264 template <
typename T_DATA,
template <
typename >
class ALLOC >
265 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler
266 IDatabaseTable< T_DATA, ALLOC >::Handler::begin()
const {
267 Handler handler(*
this);
275 template <
typename T_DATA,
template <
typename >
class ALLOC >
276 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler
277 IDatabaseTable< T_DATA, ALLOC >::Handler::end()
const {
278 Handler handler(*
this);
279 handler.__index = __end_index;
285 template <
typename T_DATA,
template <
typename >
class ALLOC >
287 IDatabaseTable< T_DATA, ALLOC >::Handler::setRange(std::size_t begin,
292 if (__row ==
nullptr) {
293 GUM_ERROR(NullElement,
"the handler does not point to any database");
295 if (end > __row->size()) {
297 "the database has fewer rows (" 298 << __row->size() <<
") than the upper range (" << end
299 <<
") specified to the handler");
302 __begin_index = begin;
309 template <
typename T_DATA,
template <
typename >
class ALLOC >
310 INLINE std::pair< std::size_t, std::size_t >
311 IDatabaseTable< T_DATA, ALLOC >::Handler::range()
const {
312 return std::pair< std::size_t, std::size_t >(__begin_index, __end_index);
317 template <
typename T_DATA,
template <
typename >
class ALLOC >
318 INLINE
const typename IDatabaseTable< T_DATA, ALLOC >::Handler::
320 IDatabaseTable< T_DATA, ALLOC >::Handler::variableNames()
const {
321 return __db->variableNames();
326 template <
typename T_DATA,
template <
typename >
class ALLOC >
328 IDatabaseTable< T_DATA, ALLOC >::Handler::nbVariables()
const {
330 return __db->variableNames().size();
337 template <
typename T_DATA,
template <
typename >
class ALLOC >
338 INLINE
const IDatabaseTable< T_DATA, ALLOC >&
339 IDatabaseTable< T_DATA, ALLOC >::Handler::database()
const {
340 if (__db ==
nullptr) {
342 "The database handler does not point toward a database");
353 template <
typename T_DATA,
template <
typename >
class ALLOC >
354 INLINE
void IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::__attachHandler() {
355 if (this->__db !=
nullptr) { this->__db->__attachHandler(
this); }
360 template <
typename T_DATA,
template <
typename >
class ALLOC >
361 INLINE
void IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::__detachHandler() {
362 if (this->__db !=
nullptr) { this->__db->__detachHandler(
this); }
367 template <
typename T_DATA,
template <
typename >
class ALLOC >
368 INLINE IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::HandlerSafe(
369 const IDatabaseTable< T_DATA, ALLOC >& db) :
370 IDatabaseTable< T_DATA, ALLOC >::Handler(db) {
372 GUM_CONSTRUCTOR(IDatabaseTable::HandlerSafe);
377 template <
typename T_DATA,
template <
typename >
class ALLOC >
378 INLINE IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::HandlerSafe(
379 const typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe& h) :
380 IDatabaseTable< T_DATA, ALLOC >::Handler(h) {
382 GUM_CONS_CPY(IDatabaseTable::HandlerSafe);
387 template <
typename T_DATA,
template <
typename >
class ALLOC >
388 INLINE IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::HandlerSafe(
389 typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&& h) :
390 IDatabaseTable< T_DATA, ALLOC >::Handler(
std::move(h)) {
392 GUM_CONS_MOV(IDatabaseTable::HandlerSafe);
397 template <
typename T_DATA,
template <
typename >
class ALLOC >
398 INLINE IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::~HandlerSafe() {
400 GUM_DESTRUCTOR(IDatabaseTable::HandlerSafe);
405 template <
typename T_DATA,
template <
typename >
class ALLOC >
406 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
407 IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::operator=(
408 const typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe& h) {
409 if (this->__db != h.__db) {
415 IDatabaseTable< T_DATA, ALLOC >::Handler::operator=(h);
421 template <
typename T_DATA,
template <
typename >
class ALLOC >
422 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
423 IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::
424 operator=(
const typename IDatabaseTable< T_DATA, ALLOC >::Handler& h) {
425 return this->operator=(
426 dynamic_cast< const IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
>(h));
431 template <
typename T_DATA,
template <
typename >
class ALLOC >
432 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
433 IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::
434 operator=(
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&& h) {
435 if (this->__db != h.__db) {
441 IDatabaseTable< T_DATA, ALLOC >::Handler::operator=(std::move(h));
447 template <
typename T_DATA,
template <
typename >
class ALLOC >
448 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
449 IDatabaseTable< T_DATA, ALLOC >::HandlerSafe::
450 operator=(
typename IDatabaseTable< T_DATA, ALLOC >::Handler&& h) {
451 return this->operator=(std::move(
452 dynamic_cast< IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
>(h)));
461 template <
typename T_DATA,
template <
typename >
class ALLOC >
462 INLINE ALLOC< T_DATA > IDatabaseTable< T_DATA, ALLOC >::getAllocator()
const {
463 return ALLOC< T_DATA >(*this);
468 template <
typename T_DATA,
template <
typename >
class ALLOC >
469 void IDatabaseTable< T_DATA, ALLOC >::__createEndIterators() {
470 const IDatabaseTable< T_DATA, ALLOC >& db = *
this;
471 ALLOC< iterator > allocator1(*
this);
472 __end = allocator1.allocate(1);
474 allocator1.construct(__end, db);
476 allocator1.deallocate(__end, 1);
480 ALLOC< iterator_safe > allocator2(*
this);
482 __end_safe = allocator2.allocate(1);
484 allocator2.construct(__end_safe, *
this);
486 allocator2.deallocate(__end_safe, 1);
490 allocator1.destroy(__end);
491 allocator1.deallocate(__end, 1);
498 template <
typename T_DATA,
template <
typename >
class ALLOC >
499 template <
template <
typename >
class VARALLOC,
500 template <
typename >
502 IDatabaseTable< T_DATA, ALLOC >::IDatabaseTable(
503 const typename IDatabaseTable< T_DATA, ALLOC >::template MissingValType<
504 MISSALLOC >& missing_symbols,
505 const std::vector< std::string, VARALLOC< std::string > >& var_names,
506 const ALLOC< T_DATA >& alloc) :
507 ALLOC< T_DATA >(alloc),
508 _variable_names(alloc), _rows(alloc), _missing_symbols(alloc),
509 _has_row_missing_val(alloc), __list_of_safe_handlers(alloc) {
511 _variable_names.reserve(var_names.size());
512 for (
const auto& name : var_names)
513 _variable_names.push_back(name);
516 _missing_symbols.reserve(missing_symbols.size());
517 for (
const auto& missing_symbol : missing_symbols)
518 _missing_symbols.push_back(missing_symbol);
521 __createEndIterators();
523 GUM_CONSTRUCTOR(IDatabaseTable);
528 template <
typename T_DATA,
template <
typename >
class ALLOC >
529 IDatabaseTable< T_DATA, ALLOC >::IDatabaseTable(
530 const IDatabaseTable< T_DATA, ALLOC >& from,
531 const typename IDatabaseTable< T_DATA, ALLOC >::allocator_type& alloc) :
532 ALLOC< T_DATA >(alloc),
533 _variable_names(from._variable_names, alloc), _rows(from._rows, alloc),
534 _missing_symbols(from._missing_symbols, alloc),
535 _has_row_missing_val(from._has_row_missing_val, alloc),
536 _max_nb_threads(from._max_nb_threads),
537 _min_nb_rows_per_thread(from._min_nb_rows_per_thread),
538 __list_of_safe_handlers(alloc) {
540 __createEndIterators();
542 GUM_CONS_CPY(IDatabaseTable);
547 template <
typename T_DATA,
template <
typename >
class ALLOC >
548 IDatabaseTable< T_DATA, ALLOC >::IDatabaseTable(
549 const IDatabaseTable< T_DATA, ALLOC >& from) :
550 IDatabaseTable< T_DATA, ALLOC >(from, from.getAllocator()) {}
554 template <
typename T_DATA,
template <
typename >
class ALLOC >
555 IDatabaseTable< T_DATA, ALLOC >::IDatabaseTable(
556 IDatabaseTable< T_DATA, ALLOC >&& from,
557 const typename IDatabaseTable< T_DATA, ALLOC >::allocator_type& alloc) :
558 ALLOC< T_DATA >(alloc),
559 _variable_names(
std::move(from._variable_names), alloc),
560 _rows(
std::move(from._rows), alloc),
561 _missing_symbols(
std::move(from._missing_symbols), alloc),
562 _has_row_missing_val(
std::move(from._has_row_missing_val), alloc),
563 _max_nb_threads(from._max_nb_threads),
564 _min_nb_rows_per_thread(from._min_nb_rows_per_thread),
565 __list_of_safe_handlers(alloc) {
567 __createEndIterators();
569 GUM_CONS_MOV(IDatabaseTable);
574 template <
typename T_DATA,
template <
typename >
class ALLOC >
575 IDatabaseTable< T_DATA, ALLOC >::IDatabaseTable(
576 IDatabaseTable< T_DATA, ALLOC >&& from) :
577 IDatabaseTable< T_DATA, ALLOC >(
std::move(from), from.getAllocator()) {}
581 template <
typename T_DATA,
template <
typename >
class ALLOC >
582 IDatabaseTable< T_DATA, ALLOC >::~IDatabaseTable() {
584 __safe_handlers_mutex.lock();
585 for (
auto handler : __list_of_safe_handlers) {
586 handler->__db =
nullptr;
587 handler->__row =
nullptr;
588 handler->__end_index = 0;
589 handler->__index = 0;
591 __safe_handlers_mutex.unlock();
593 ALLOC< iterator > allocator1(this->getAllocator());
594 allocator1.destroy(__end);
595 allocator1.deallocate(__end, 1);
597 ALLOC< iterator_safe > allocator2(this->getAllocator());
598 allocator2.destroy(__end_safe);
599 allocator2.deallocate(__end_safe, 1);
601 GUM_DESTRUCTOR(IDatabaseTable);
606 template <
typename T_DATA,
template <
typename >
class ALLOC >
607 IDatabaseTable< T_DATA, ALLOC >& IDatabaseTable< T_DATA, ALLOC >::
608 operator=(
const IDatabaseTable< T_DATA, ALLOC >& from) {
611 __safe_handlers_mutex.lock();
612 for (
auto handler : __list_of_safe_handlers) {
613 handler->__db =
nullptr;
614 handler->__row =
nullptr;
615 handler->__end_index = 0;
616 handler->__index = 0;
618 __list_of_safe_handlers.clear();
619 __safe_handlers_mutex.unlock();
622 _variable_names = from._variable_names;
623 _missing_symbols = from._missing_symbols;
624 _has_row_missing_val = from._has_row_missing_val;
625 _max_nb_threads = from._max_nb_threads;
626 _min_nb_rows_per_thread = from._min_nb_rows_per_thread;
629 const std::size_t db_size = _rows.size();
630 __end->__index = db_size;
631 __end->__end_index = db_size;
632 __end_safe->__index = db_size;
633 __end_safe->__end_index = db_size;
641 template <
typename T_DATA,
template <
typename >
class ALLOC >
642 IDatabaseTable< T_DATA, ALLOC >& IDatabaseTable< T_DATA, ALLOC >::
643 operator=(IDatabaseTable< T_DATA, ALLOC >&& from) {
646 __safe_handlers_mutex.lock();
647 for (
auto handler : __list_of_safe_handlers) {
648 handler->__db =
nullptr;
649 handler->__row =
nullptr;
650 handler->__end_index = 0;
651 handler->__index = 0;
653 __safe_handlers_mutex.unlock();
655 _rows = std::move(from._rows);
656 _variable_names = std::move(from._variable_names);
657 _missing_symbols = std::move(from._missing_symbols);
658 _has_row_missing_val = std::move(from._has_row_missing_val);
659 _max_nb_threads = from._max_nb_threads;
660 _min_nb_rows_per_thread = from._min_nb_rows_per_thread;
663 const std::size_t db_size = _rows.size();
664 __end->__index = db_size;
665 __end->__end_index = db_size;
666 __end_safe->__index = db_size;
667 __end_safe->__end_index = db_size;
675 template <
typename T_DATA,
template <
typename >
class ALLOC >
676 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler
677 IDatabaseTable< T_DATA, ALLOC >::begin()
const {
678 return Handler(*
this);
683 template <
typename T_DATA,
template <
typename >
class ALLOC >
684 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe
685 IDatabaseTable< T_DATA, ALLOC >::beginSafe()
const {
686 return HandlerSafe(*
this);
691 template <
typename T_DATA,
template <
typename >
class ALLOC >
692 INLINE
const typename IDatabaseTable< T_DATA, ALLOC >::Handler&
693 IDatabaseTable< T_DATA, ALLOC >::end() const noexcept {
699 template <
typename T_DATA,
template <
typename >
class ALLOC >
700 INLINE
const typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe&
701 IDatabaseTable< T_DATA, ALLOC >::endSafe() const noexcept {
707 template <
typename T_DATA,
template <
typename >
class ALLOC >
708 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::Handler
709 IDatabaseTable< T_DATA, ALLOC >::handler()
const {
710 return Handler(*
this);
715 template <
typename T_DATA,
template <
typename >
class ALLOC >
716 INLINE
typename IDatabaseTable< T_DATA, ALLOC >::HandlerSafe
717 IDatabaseTable< T_DATA, ALLOC >::handlerSafe()
const {
718 return HandlerSafe(*
this);
723 template <
typename T_DATA,
template <
typename >
class ALLOC >
724 INLINE
const typename IDatabaseTable< T_DATA,
725 ALLOC >::template Matrix< T_DATA >&
726 IDatabaseTable< T_DATA, ALLOC >::content() const noexcept {
732 template <
typename T_DATA,
template <
typename >
class ALLOC >
733 bool IDatabaseTable< T_DATA, ALLOC >::hasMissingValues()
const {
734 for (
const auto& status : _has_row_missing_val)
735 if (status == IsMissing::True)
return true;
741 template <
typename T_DATA,
template <
typename >
class ALLOC >
742 INLINE
bool IDatabaseTable< T_DATA, ALLOC >::hasMissingValues(
743 const std::size_t k)
const {
744 return _has_row_missing_val[k] == IsMissing::True;
749 template <
typename T_DATA,
template <
typename >
class ALLOC >
750 INLINE
const std::vector< std::string, ALLOC< std::string > >&
751 IDatabaseTable< T_DATA, ALLOC >::variableNames() const noexcept {
752 return _variable_names;
757 template <
typename T_DATA,
template <
typename >
class ALLOC >
758 template <
template <
typename >
class OTHER_ALLOC >
759 void IDatabaseTable< T_DATA, ALLOC >::setVariableNames(
760 const std::vector< std::string, OTHER_ALLOC< std::string > >& names,
761 const bool from_external_object) {
764 const std::size_t size = names.size();
766 for (std::size_t i = 0; i < size; ++i)
767 variable_names[i] = names[i];
769 this->setVariableNames(variable_names, from_external_object);
774 template <
typename T_DATA,
template <
typename >
class ALLOC >
775 INLINE
const std::string&
776 IDatabaseTable< T_DATA, ALLOC >::variableName(
const std::size_t k)
const {
777 if (_variable_names.size() <= k)
778 GUM_ERROR(OutOfBounds,
"the database does not contain Column #" << k);
779 return _variable_names[k];
784 template <
typename T_DATA,
template <
typename >
class ALLOC >
785 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::columnFromVariableName(
786 const std::string& name)
const {
787 const std::size_t size = _variable_names.size();
788 for (std::size_t i = 0; i < size; ++i)
789 if (_variable_names[i] == name)
return i;
792 "the database contains no column whose name is " << name);
797 template <
typename T_DATA,
template <
typename >
class ALLOC >
799 typename IDatabaseTable< T_DATA, ALLOC >::template DBVector< std::size_t >
800 IDatabaseTable< T_DATA, ALLOC >::columnsFromVariableName(
801 const std::string& name)
const {
802 const std::size_t size = _variable_names.size();
803 DBVector< std::size_t > cols;
804 for (std::size_t i = 0; i < size; ++i)
805 if (_variable_names[i] == name) cols.push_back(i);
809 "the database contains no column whose name is " << name);
816 template <
typename T_DATA,
template <
typename >
class ALLOC >
817 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::nbVariables() const
819 return _variable_names.size();
824 template <
typename T_DATA,
template <
typename >
class ALLOC >
825 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::size() const noexcept {
831 template <
typename T_DATA,
template <
typename >
class ALLOC >
832 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::nbRows() const noexcept {
838 template <
typename T_DATA,
template <
typename >
class ALLOC >
839 INLINE
bool IDatabaseTable< T_DATA, ALLOC >::empty() const noexcept {
840 return _rows.empty();
845 template <
typename T_DATA,
template <
typename >
class ALLOC >
846 void IDatabaseTable< T_DATA, ALLOC >::__updateHandlers(
847 std::size_t new_size)
const {
848 const std::size_t db_size = _rows.size();
850 __safe_handlers_mutex.lock();
851 for (
auto handler : __list_of_safe_handlers) {
852 if ((handler->__end_index == db_size)
853 || (handler->__end_index > new_size)) {
854 handler->__end_index = new_size;
860 __safe_handlers_mutex.unlock();
863 __end->__index = new_size;
864 __end->__end_index = new_size;
865 __end_safe->__index = new_size;
866 __end_safe->__end_index = new_size;
871 template <
typename T_DATA,
template <
typename >
class ALLOC >
872 INLINE
void IDatabaseTable< T_DATA, ALLOC >::__attachHandler(
873 HandlerSafe* handler)
const {
874 __safe_handlers_mutex.lock();
875 __list_of_safe_handlers.push_back(handler);
876 __safe_handlers_mutex.unlock();
881 template <
typename T_DATA,
template <
typename >
class ALLOC >
882 void IDatabaseTable< T_DATA, ALLOC >::__detachHandler(
883 HandlerSafe* handler)
const {
884 __safe_handlers_mutex.lock();
886 for (
auto iter = __list_of_safe_handlers.rbegin();
887 iter != __list_of_safe_handlers.rend();
889 if (*iter == handler) {
890 *iter = __list_of_safe_handlers.back();
891 __list_of_safe_handlers.pop_back();
896 __safe_handlers_mutex.unlock();
901 template <
typename T_DATA,
template <
typename >
class ALLOC >
902 INLINE
bool IDatabaseTable< T_DATA, ALLOC >::_isRowSizeOK(
903 const std::size_t size)
const {
904 return (size == _variable_names.size());
909 template <
typename T_DATA,
template <
typename >
class ALLOC >
910 template <
template <
typename >
class OTHER_ALLOC >
911 void IDatabaseTable< T_DATA, ALLOC >::insertRow(
912 const std::vector< std::string, OTHER_ALLOC< std::string > >& new_row) {
913 const std::size_t size = new_row.size();
914 std::vector< std::string, ALLOC< std::string > > good_typed_row(size);
915 for (std::size_t i = 0; i < size; ++i)
916 good_typed_row[i] = new_row[i];
917 this->insertRow(good_typed_row);
922 template <
typename T_DATA,
template <
typename >
class ALLOC >
923 void IDatabaseTable< T_DATA, ALLOC >::insertRow(
924 typename IDatabaseTable< T_DATA, ALLOC >::template Row< T_DATA >&& new_row,
925 const typename IDatabaseTable< T_DATA, ALLOC >::IsMissing
928 if (!_isRowSizeOK(new_row.size()))
930 "the new row is of size " 932 <<
", which is different from the number of columns " 933 <<
"of the database, i.e., " << _variable_names.size());
935 __updateHandlers(_rows.size() + 1);
936 _rows.push_back(std::move(new_row));
938 _has_row_missing_val.push_back(contains_missing);
947 template <
typename T_DATA,
template <
typename >
class ALLOC >
948 INLINE
void IDatabaseTable< T_DATA, ALLOC >::insertRow(
949 const typename IDatabaseTable< T_DATA, ALLOC >::template Row< T_DATA >& row,
950 const typename IDatabaseTable< T_DATA, ALLOC >::IsMissing
953 typename IDatabaseTable< T_DATA, ALLOC >::template Row< T_DATA >(row),
959 template <
typename T_DATA,
template <
typename >
class ALLOC >
960 void IDatabaseTable< T_DATA, ALLOC >::insertRows(
961 typename IDatabaseTable< T_DATA, ALLOC >::template Matrix< T_DATA >&&
963 const typename IDatabaseTable< T_DATA, ALLOC >::template DBVector<
964 typename IDatabaseTable< T_DATA, ALLOC >::IsMissing >&
965 rows_have_missing_vals) {
966 if (new_rows.empty())
return;
970 if (rows_have_missing_vals.size() != new_rows.size())
973 "the number of new rows (i.e., " 975 <<
") is different from the number of missing values indicators (" 976 << rows_have_missing_vals.size());
979 const std::size_t new_size = new_rows[0].size();
981 for (
const auto& row : new_rows) {
982 if (row.size() != new_size) {
984 "all the new rows do not have the same number of columns");
990 if (!_isRowSizeOK(new_size)) {
994 <<
" columns, which is different from the number of columns " 995 <<
"of the database, i.e., " << _variable_names.size());
998 const std::size_t nb_new_rows = new_rows.size();
999 const std::size_t new_db_size = _rows.size() + nb_new_rows;
1001 _rows.reserve(new_db_size);
1002 _has_row_missing_val.reserve(new_db_size);
1004 for (std::size_t i = std::size_t(0); i < nb_new_rows; ++i) {
1005 _rows.push_back(std::move(new_rows[i]));
1006 _has_row_missing_val.push_back(rows_have_missing_vals[i]);
1009 __updateHandlers(new_db_size);
1014 template <
typename T_DATA,
template <
typename >
class ALLOC >
1015 void IDatabaseTable< T_DATA, ALLOC >::insertRows(
1016 const typename IDatabaseTable< T_DATA, ALLOC >::template Matrix< T_DATA >&
1018 const typename IDatabaseTable< T_DATA, ALLOC >::template DBVector<
1019 typename IDatabaseTable< T_DATA, ALLOC >::IsMissing >&
1020 rows_have_missing_vals) {
1021 if (new_rows.empty())
return;
1025 if (rows_have_missing_vals.size() != new_rows.size())
1028 "the number of new rows (i.e., " 1030 <<
") is different from the number of missing values indicators (" 1031 << rows_have_missing_vals.size());
1034 const std::size_t new_size = new_rows[0].size();
1036 for (
const auto& row : new_rows) {
1037 if (row.size() != new_size) {
1039 "all the new rows do not have the same number of columns");
1045 std::size_t db_size = _rows.size();
1047 if (!_isRowSizeOK(new_size)) {
1049 "the new rows have " 1051 <<
" columns, which is different from the number of columns " 1052 <<
"of the database, i.e., " << _variable_names.size());
1055 const std::size_t nb_new_rows = new_rows.size();
1056 const std::size_t new_db_size = _rows.size() + nb_new_rows;
1058 _rows.reserve(new_db_size);
1059 _has_row_missing_val.reserve(new_db_size);
1061 for (std::size_t i = std::size_t(0); i < nb_new_rows; ++i) {
1062 _rows.push_back(new_rows[i]);
1063 _has_row_missing_val.push_back(rows_have_missing_vals[i]);
1066 __updateHandlers(db_size);
1071 template <
typename T_DATA,
template <
typename >
class ALLOC >
1072 INLINE
void IDatabaseTable< T_DATA, ALLOC >::eraseRow(std::size_t index) {
1073 const std::size_t db_size = _rows.size();
1075 if (index < db_size) {
1076 __updateHandlers(db_size - 1);
1077 _rows.erase(_rows.begin() + index);
1078 _has_row_missing_val.erase(_has_row_missing_val.begin() + index);
1084 template <
typename T_DATA,
template <
typename >
class ALLOC >
1085 INLINE
void IDatabaseTable< T_DATA, ALLOC >::eraseLastRow() {
1086 const std::size_t db_size = _rows.size();
1089 __updateHandlers(db_size - 1);
1091 _has_row_missing_val.pop_back();
1097 template <
typename T_DATA,
template <
typename >
class ALLOC >
1098 INLINE
void IDatabaseTable< T_DATA, ALLOC >::eraseFirstRow() {
1099 const std::size_t db_size = _rows.size();
1102 __updateHandlers(db_size - 1);
1103 _rows.erase(_rows.begin());
1104 _has_row_missing_val.erase(_has_row_missing_val.begin());
1110 template <
typename T_DATA,
template <
typename >
class ALLOC >
1111 INLINE
void IDatabaseTable< T_DATA, ALLOC >::eraseAllRows() {
1112 __updateHandlers(0);
1114 _has_row_missing_val.clear();
1119 template <
typename T_DATA,
template <
typename >
class ALLOC >
1121 IDatabaseTable< T_DATA, ALLOC >::eraseFirstRows(
const std::size_t nb_rows) {
1122 const std::size_t db_size = _rows.size();
1124 if (nb_rows >= db_size) {
1127 __updateHandlers(db_size - nb_rows);
1128 _rows.erase(_rows.begin(), _rows.begin() + nb_rows);
1129 _has_row_missing_val.erase(_has_row_missing_val.begin(),
1130 _has_row_missing_val.begin() + nb_rows);
1136 template <
typename T_DATA,
template <
typename >
class ALLOC >
1138 IDatabaseTable< T_DATA, ALLOC >::eraseLastRows(
const std::size_t nb_rows) {
1139 const std::size_t db_size = _rows.size();
1141 if (nb_rows >= db_size) {
1144 __updateHandlers(db_size - nb_rows);
1145 _rows.erase(_rows.begin() + (db_size - nb_rows), _rows.begin() + db_size);
1146 _has_row_missing_val.erase(_has_row_missing_val.begin()
1147 + (db_size - nb_rows),
1148 _has_row_missing_val.begin() + db_size);
1154 template <
typename T_DATA,
template <
typename >
class ALLOC >
1155 INLINE
void IDatabaseTable< T_DATA, ALLOC >::eraseRows(std::size_t deb,
1159 const std::size_t db_size = _rows.size();
1161 if (end >= db_size) {
1162 if (deb >= db_size) {
1165 eraseLastRows(db_size - deb);
1168 __updateHandlers(db_size - (end - deb));
1169 _rows.erase(_rows.begin() + deb, _rows.begin() + end);
1170 _has_row_missing_val.erase(_has_row_missing_val.begin() + deb,
1171 _has_row_missing_val.begin() + end);
1177 template <
typename T_DATA,
template <
typename >
class ALLOC >
1178 INLINE
void IDatabaseTable< T_DATA, ALLOC >::clear() {
1179 __updateHandlers(0);
1181 _has_row_missing_val.clear();
1182 _variable_names.clear();
1187 template <
typename T_DATA,
template <
typename >
class ALLOC >
1188 INLINE
const std::vector< std::string, ALLOC< std::string > >&
1189 IDatabaseTable< T_DATA, ALLOC >::missingSymbols()
const {
1190 return _missing_symbols;
1195 template <
typename T_DATA,
template <
typename >
class ALLOC >
1196 void IDatabaseTable< T_DATA, ALLOC >::setMaxNbThreads(
1197 const std::size_t nb)
const {
1198 if (nb == std::size_t(0))
1199 _max_nb_threads = std::size_t(1);
1201 _max_nb_threads = nb;
1206 template <
typename T_DATA,
template <
typename >
class ALLOC >
1207 INLINE std::size_t IDatabaseTable< T_DATA, ALLOC >::nbThreads()
const {
1208 return _max_nb_threads;
1214 template <
typename T_DATA,
template <
typename >
class ALLOC >
1215 void IDatabaseTable< T_DATA, ALLOC >::setMinNbRowsPerThread(
1216 const std::size_t nb)
const {
1217 if (nb == std::size_t(0))
1218 _min_nb_rows_per_thread = std::size_t(1);
1220 _min_nb_rows_per_thread = nb;
1225 template <
typename T_DATA,
template <
typename >
class ALLOC >
1227 IDatabaseTable< T_DATA, ALLOC >::minNbRowsPerThread()
const {
1228 return _min_nb_rows_per_thread;
1233 template <
template <
typename >
class ALLOC >
1234 void IDatabaseTableInsert4DBCell< ALLOC, true >::insertRows(
1235 const typename IDatabaseTableInsert4DBCell< ALLOC, true >::
1237 for (
const auto& new_row : new_rows)
1238 this->insertRow(new_row);
1243 template <
template <
typename >
class ALLOC >
1244 void IDatabaseTableInsert4DBCell< ALLOC, false >::insertRows(
1245 const typename IDatabaseTableInsert4DBCell< ALLOC, false >::
1247 for (
const auto& new_row : new_rows)
1248 this->insertRow(new_row);
1253 template <
typename T_DATA,
template <
typename >
class ALLOC >
1255 IDatabaseTable< T_DATA, ALLOC >::setAllRowsWeight(
const double new_weight) {
1258 std::vector< std::pair< std::size_t, std::size_t > > ranges;
1259 const std::size_t db_size = nbRows();
1260 std::size_t nb_threads = db_size / _min_nb_rows_per_thread;
1263 else if (nb_threads > _max_nb_threads)
1264 nb_threads = _max_nb_threads;
1265 std::size_t nb_rows_per_thread = db_size / nb_threads;
1266 std::size_t rest_rows = db_size - nb_rows_per_thread * nb_threads;
1270 std::size_t begin_index = std::size_t(0);
1271 for (std::size_t i = std::size_t(0); i < nb_threads; ++i) {
1272 std::size_t end_index = begin_index + nb_rows_per_thread;
1273 if (rest_rows != std::size_t(0)) {
1278 std::pair< std::size_t, std::size_t >(begin_index, end_index));
1279 begin_index = end_index;
1287 # pragma omp parallel num_threads(int(nb_threads)) 1291 const std::size_t begin_index = ranges[this_thread].first;
1292 const std::size_t end_index = ranges[this_thread].second;
1294 for (std::size_t i = begin_index; i < end_index; ++i) {
1295 _rows[i].setWeight(new_weight);
1301 template <
typename T_DATA,
template <
typename >
class ALLOC >
1302 void IDatabaseTable< T_DATA, ALLOC >::setWeight(
const std::size_t i,
1303 const double weight) {
1305 const std::size_t dbsize = nbRows();
1309 case 1: str =
"st";
break;
1310 case 2: str =
"nd";
break;
1311 default: str =
"th";
1314 "it is impossible to set the weight of the " 1315 << i << str <<
" record because the database contains only " 1316 << nbRows() <<
" records");
1323 case 1: str =
"st";
break;
1324 case 2: str =
"nd";
break;
1325 default: str =
"th";
1328 "it is impossible to set " 1329 << weight <<
" as a weight of the " << i << str
1330 <<
" record because this weight is negative");
1333 _rows[i].setWeight(weight);
1338 template <
typename T_DATA,
template <
typename >
class ALLOC >
1339 double IDatabaseTable< T_DATA, ALLOC >::weight(
const std::size_t i)
const {
1341 const std::size_t dbsize = nbRows();
1345 case 1: str =
"st";
break;
1346 case 2: str =
"nd";
break;
1347 default: str =
"th";
1350 "it is impossible to get the weight of the " 1351 << i << str <<
" record because the database contains only " 1352 << nbRows() <<
" records");
1355 return _rows[i].weight();
1360 template <
typename T_DATA,
template <
typename >
class ALLOC >
1361 double IDatabaseTable< T_DATA, ALLOC >::weight()
const {
1363 for (
const auto& row : _rows)
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.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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)
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
#define GUM_ERROR(type, msg)