51#ifndef DOXYGEN_SHOULD_SKIP_THIS
62 template <
typename T_DATA >
64 DBHandler< T_DATA >(), _db_(&db), _row_(&(db.content())),
65 _end_index_(std::size_t(_row_->size())) {
66 GUM_CONSTRUCTOR(IDatabaseTable::Handler);
70 template <
typename T_DATA >
71 IDatabaseTable< T_DATA >::Handler::Handler(
72 const typename IDatabaseTable< T_DATA >::Handler& h) :
73 DBHandler< T_DATA >(), _db_(h._db_), _row_(h._row_), _index_(h._index_),
74 _begin_index_(h._begin_index_), _end_index_(h._end_index_) {
75 GUM_CONS_CPY(IDatabaseTable::Handler);
79 template <
typename T_DATA >
80 IDatabaseTable< T_DATA >::Handler::Handler(
typename IDatabaseTable< T_DATA >::Handler&& h) :
81 DBHandler< T_DATA >(), _db_(h._db_), _row_(h._row_), _index_(h._index_),
82 _begin_index_(h._begin_index_), _end_index_(h._end_index_) {
83 GUM_CONS_MOV(IDatabaseTable::Handler);
87 template <
typename T_DATA >
88 IDatabaseTable< T_DATA >::Handler::~Handler() {
89 GUM_DESTRUCTOR(IDatabaseTable::Handler);
93 template <
typename T_DATA >
94 typename IDatabaseTable< T_DATA >::Handler& IDatabaseTable< T_DATA >::Handler::operator=(
95 const typename IDatabaseTable< T_DATA >::Handler& h) {
99 _begin_index_ = h._begin_index_;
100 _end_index_ = h._end_index_;
105 template <
typename T_DATA >
106 typename IDatabaseTable< T_DATA >::Handler& IDatabaseTable< T_DATA >::Handler::operator=(
107 typename IDatabaseTable< T_DATA >::Handler&& h) {
111 _begin_index_ = h._begin_index_;
112 _end_index_ = h._end_index_;
117 template <
typename T_DATA >
118 typename IDatabaseTable< T_DATA >::Handler::const_reference
119 IDatabaseTable< T_DATA >::Handler::operator*()
const {
120 return _row_->operator[](_index_);
124 template <
typename T_DATA >
125 typename IDatabaseTable< T_DATA >::Handler::const_pointer
126 IDatabaseTable< T_DATA >::Handler::operator->()
const {
127 return &(_row_->operator[](_index_));
131 template <
typename T_DATA >
132 typename IDatabaseTable< T_DATA >::Handler& IDatabaseTable< T_DATA >::Handler::operator++() {
138 template <
typename T_DATA >
139 typename IDatabaseTable< T_DATA >::Handler& IDatabaseTable< T_DATA >::Handler::operator--() {
140 if (_index_ > _begin_index_) --_index_;
145 template <
typename T_DATA >
146 typename IDatabaseTable< T_DATA >::Handler&
147 IDatabaseTable< T_DATA >::Handler::operator+=(
const std::size_t i) {
153 template <
typename T_DATA >
154 typename IDatabaseTable< T_DATA >::Handler&
155 IDatabaseTable< T_DATA >::Handler::operator-=(
const std::size_t i) {
156 if (_index_ >= _begin_index_ + i) _index_ -= i;
157 else _index_ = _begin_index_;
162 template <
typename T_DATA >
163 bool IDatabaseTable< T_DATA >::Handler::operator==(
const Handler& handler)
const {
164 return _index_ == handler._index_;
168 template <
typename T_DATA >
169 bool IDatabaseTable< T_DATA >::Handler::operator!=(
const Handler& handler)
const {
170 return _index_ != handler._index_;
174 template <
typename T_DATA >
175 std::size_t IDatabaseTable< T_DATA >::Handler::size()
const {
176 return _end_index_ - _begin_index_;
180 template <
typename T_DATA >
181 std::size_t IDatabaseTable< T_DATA >::Handler::DBSize()
const {
182 if (_row_ !=
nullptr)
return _row_->size();
183 else return std::size_t(0);
187 template <
typename T_DATA >
188 typename IDatabaseTable< T_DATA >::Handler::const_reference
189 IDatabaseTable< T_DATA >::Handler::rowSafe()
const {
192 return _row_->operator[](_index_);
196 template <
typename T_DATA >
197 typename IDatabaseTable< T_DATA >::Handler::reference
198 IDatabaseTable< T_DATA >::Handler::rowSafe() {
201 return const_cast< Matrix< T_DATA >*
>(_row_)->
operator[](_index_);
205 template <
typename T_DATA >
206 typename IDatabaseTable< T_DATA >::Handler::const_reference
207 IDatabaseTable< T_DATA >::Handler::row()
const {
208 return _row_->operator[](_index_);
212 template <
typename T_DATA >
213 typename IDatabaseTable< T_DATA >::Handler::reference IDatabaseTable< T_DATA >::Handler::row() {
214 return const_cast< Matrix< T_DATA >*
>(_row_)->
operator[](_index_);
218 template <
typename T_DATA >
219 void IDatabaseTable< T_DATA >::Handler::nextRow() {
224 template <
typename T_DATA >
225 std::size_t IDatabaseTable< T_DATA >::Handler::numRow()
const {
226 return (_index_ >= _begin_index_) ? _index_ - _begin_index_ : 0;
230 template <
typename T_DATA >
231 bool IDatabaseTable< T_DATA >::Handler::hasRows()
const {
232 return (_index_ < _end_index_);
236 template <
typename T_DATA >
237 void IDatabaseTable< T_DATA >::Handler::reset() {
238 _index_ = _begin_index_;
243 template <
typename T_DATA >
244 typename IDatabaseTable< T_DATA >::Handler IDatabaseTable< T_DATA >::Handler::begin()
const {
245 Handler handler(*
this);
252 template <
typename T_DATA >
253 typename IDatabaseTable< T_DATA >::Handler IDatabaseTable< T_DATA >::Handler::end()
const {
254 Handler handler(*
this);
255 handler._index_ = _end_index_;
260 template <
typename T_DATA >
261 void IDatabaseTable< T_DATA >::Handler::setRange(std::size_t first, std::size_t last) {
262 if (first > last) std::swap(first, last);
267 if (last > _row_->size())
269 "the database has fewer rows (" << _row_->size() <<
") than the upper range ("
270 << last <<
") specified to the handler")
272 _begin_index_ = first;
278 template < typename T_DATA >
279 std::pair<
std::
size_t,
std::
size_t > IDatabaseTable< T_DATA >::Handler::range()
const {
280 return std::pair< std::size_t, std::size_t >(_begin_index_, _end_index_);
284 template <
typename T_DATA >
286 IDatabaseTable< T_DATA >::Handler::variableNames()
const {
287 return _db_->variableNames();
291 template <
typename T_DATA >
292 std::size_t IDatabaseTable< T_DATA >::Handler::nbVariables()
const {
293 if (_db_ !=
nullptr)
return _db_->variableNames().size();
298 template <
typename T_DATA >
299 const IDatabaseTable< T_DATA >& IDatabaseTable< T_DATA >::Handler::database()
const {
300 if (_db_ ==
nullptr) {
311 template <
typename T_DATA >
312 void IDatabaseTable< T_DATA >::HandlerSafe::_attachHandler_() {
313 if (this->_db_ !=
nullptr) { this->_db_->_attachHandler_(
this); }
317 template <
typename T_DATA >
318 void IDatabaseTable< T_DATA >::HandlerSafe::_detachHandler_() {
319 if (this->_db_ !=
nullptr) { this->_db_->_detachHandler_(
this); }
323 template <
typename T_DATA >
324 IDatabaseTable< T_DATA >::HandlerSafe::HandlerSafe(
const IDatabaseTable< T_DATA >& db) :
325 IDatabaseTable< T_DATA >::Handler(db) {
327 GUM_CONSTRUCTOR(IDatabaseTable::HandlerSafe);
331 template <
typename T_DATA >
332 IDatabaseTable< T_DATA >::HandlerSafe::HandlerSafe(
333 const typename IDatabaseTable< T_DATA >::HandlerSafe& h) :
334 IDatabaseTable< T_DATA >::Handler(h) {
336 GUM_CONS_CPY(IDatabaseTable::HandlerSafe);
340 template <
typename T_DATA >
341 IDatabaseTable< T_DATA >::HandlerSafe::HandlerSafe(
342 typename IDatabaseTable< T_DATA >::HandlerSafe&& h) :
343 IDatabaseTable< T_DATA >::Handler(
std::move(h)) {
345 GUM_CONS_MOV(IDatabaseTable::HandlerSafe);
349 template <
typename T_DATA >
350 IDatabaseTable< T_DATA >::HandlerSafe::~HandlerSafe() {
352 GUM_DESTRUCTOR(IDatabaseTable::HandlerSafe);
356 template <
typename T_DATA >
357 typename IDatabaseTable< T_DATA >::HandlerSafe&
358 IDatabaseTable< T_DATA >::HandlerSafe::operator=(
359 const typename IDatabaseTable< T_DATA >::HandlerSafe& h) {
360 if (this->_db_ != h._db_) {
366 IDatabaseTable< T_DATA >::Handler::operator=(h);
371 template <
typename T_DATA >
372 typename IDatabaseTable< T_DATA >::HandlerSafe&
373 IDatabaseTable< T_DATA >::HandlerSafe::operator=(
374 const typename IDatabaseTable< T_DATA >::Handler& h) {
375 return this->operator=(
dynamic_cast< const IDatabaseTable< T_DATA >::HandlerSafe&
>(h));
379 template <
typename T_DATA >
380 typename IDatabaseTable< T_DATA >::HandlerSafe&
381 IDatabaseTable< T_DATA >::HandlerSafe::operator=(
382 typename IDatabaseTable< T_DATA >::HandlerSafe&& h) {
383 if (this->_db_ != h._db_) {
389 IDatabaseTable< T_DATA >::Handler::operator=(std::move(h));
394 template <
typename T_DATA >
395 typename IDatabaseTable< T_DATA >::HandlerSafe&
396 IDatabaseTable< T_DATA >::HandlerSafe::operator=(
397 typename IDatabaseTable< T_DATA >::Handler&& h) {
398 return this->operator=(std::move(
dynamic_cast< IDatabaseTable< T_DATA >::HandlerSafe&
>(h)));
406 template <
typename T_DATA >
407 void IDatabaseTable< T_DATA >::_createEndIterators_() {
408 _end_ =
new iterator(*
this);
410 _end_safe_ =
new iterator_safe(*
this);
418 template <
typename T_DATA >
419 IDatabaseTable< T_DATA >::IDatabaseTable(
420 const typename IDatabaseTable< T_DATA >::MissingValType& missing_symbols,
421 const std::vector< std::string >& var_names) :
422 variable_names_(var_names), missing_symbols_(missing_symbols) {
424 _createEndIterators_();
426 GUM_CONSTRUCTOR(IDatabaseTable);
430 template <
typename T_DATA >
431 IDatabaseTable< T_DATA >::IDatabaseTable(
const IDatabaseTable< T_DATA >& from) :
432 variable_names_(from.variable_names_), rows_(from.rows_),
433 missing_symbols_(from.missing_symbols_), has_row_missing_val_(from.has_row_missing_val_),
434 max_nb_threads_(from.max_nb_threads_),
435 min_nb_rows_per_thread_(from.min_nb_rows_per_thread_) {
437 _createEndIterators_();
439 GUM_CONS_CPY(IDatabaseTable);
443 template <
typename T_DATA >
444 IDatabaseTable< T_DATA >::IDatabaseTable(IDatabaseTable< T_DATA >&& from) :
445 variable_names_(
std::move(from.variable_names_)), rows_(
std::move(from.rows_)),
446 missing_symbols_(
std::move(from.missing_symbols_)),
447 has_row_missing_val_(
std::move(from.has_row_missing_val_)),
448 max_nb_threads_(from.max_nb_threads_),
449 min_nb_rows_per_thread_(from.min_nb_rows_per_thread_) {
451 _createEndIterators_();
453 GUM_CONS_MOV(IDatabaseTable);
457 template <
typename T_DATA >
458 IDatabaseTable< T_DATA >::~IDatabaseTable() {
460 _safe_handlers_mutex_.lock();
461 for (
auto handler: _list_of_safe_handlers_) {
462 handler->_db_ =
nullptr;
463 handler->_row_ =
nullptr;
464 handler->_end_index_ = 0;
465 handler->_index_ = 0;
467 _safe_handlers_mutex_.unlock();
472 GUM_DESTRUCTOR(IDatabaseTable);
476 template <
typename T_DATA >
477 IDatabaseTable< T_DATA >&
478 IDatabaseTable< T_DATA >::operator=(
const IDatabaseTable< T_DATA >& from) {
481 _safe_handlers_mutex_.lock();
482 for (
auto handler: _list_of_safe_handlers_) {
483 handler->_db_ =
nullptr;
484 handler->_row_ =
nullptr;
485 handler->_end_index_ = 0;
486 handler->_index_ = 0;
488 _list_of_safe_handlers_.clear();
489 _safe_handlers_mutex_.unlock();
492 variable_names_ = from.variable_names_;
493 missing_symbols_ = from.missing_symbols_;
494 has_row_missing_val_ = from.has_row_missing_val_;
495 max_nb_threads_ = from.max_nb_threads_;
496 min_nb_rows_per_thread_ = from.min_nb_rows_per_thread_;
499 const std::size_t db_size = rows_.size();
500 _end_->_index_ = db_size;
501 _end_->_end_index_ = db_size;
502 _end_safe_->_index_ = db_size;
503 _end_safe_->_end_index_ = db_size;
510 template <
typename T_DATA >
511 IDatabaseTable< T_DATA >& IDatabaseTable< T_DATA >::operator=(IDatabaseTable< T_DATA >&& from) {
514 _safe_handlers_mutex_.lock();
515 for (
auto handler: _list_of_safe_handlers_) {
516 handler->_db_ =
nullptr;
517 handler->_row_ =
nullptr;
518 handler->_end_index_ = 0;
519 handler->_index_ = 0;
521 _safe_handlers_mutex_.unlock();
523 rows_ = std::move(from.rows_);
524 variable_names_ = std::move(from.variable_names_);
525 missing_symbols_ = std::move(from.missing_symbols_);
526 has_row_missing_val_ = std::move(from.has_row_missing_val_);
527 max_nb_threads_ = from.max_nb_threads_;
528 min_nb_rows_per_thread_ = from.min_nb_rows_per_thread_;
531 const std::size_t db_size = rows_.size();
532 _end_->_index_ = db_size;
533 _end_->_end_index_ = db_size;
534 _end_safe_->_index_ = db_size;
535 _end_safe_->_end_index_ = db_size;
542 template <
typename T_DATA >
543 typename IDatabaseTable< T_DATA >::Handler IDatabaseTable< T_DATA >::begin()
const {
544 return Handler(*
this);
548 template <
typename T_DATA >
549 typename IDatabaseTable< T_DATA >::HandlerSafe IDatabaseTable< T_DATA >::beginSafe()
const {
550 return HandlerSafe(*
this);
554 template <
typename T_DATA >
555 const typename IDatabaseTable< T_DATA >::Handler&
556 IDatabaseTable< T_DATA >::end() const noexcept {
561 template <
typename T_DATA >
562 const typename IDatabaseTable< T_DATA >::HandlerSafe&
563 IDatabaseTable< T_DATA >::endSafe() const noexcept {
568 template <
typename T_DATA >
569 typename IDatabaseTable< T_DATA >::Handler IDatabaseTable< T_DATA >::handler()
const {
570 return Handler(*
this);
574 template <
typename T_DATA >
575 typename IDatabaseTable< T_DATA >::HandlerSafe IDatabaseTable< T_DATA >::handlerSafe()
const {
576 return HandlerSafe(*
this);
580 template <
typename T_DATA >
581 const typename IDatabaseTable< T_DATA >::template Matrix< T_DATA >&
582 IDatabaseTable< T_DATA >::content() const noexcept {
587 template <
typename T_DATA >
588 bool IDatabaseTable< T_DATA >::hasMissingValues()
const {
589 for (
const auto& status: has_row_missing_val_)
590 if (status == IsMissing::True)
return true;
595 template <
typename T_DATA >
596 bool IDatabaseTable< T_DATA >::hasMissingValues(
const std::size_t k)
const {
597 return has_row_missing_val_[k] == IsMissing::True;
601 template <
typename T_DATA >
602 const std::vector< std::string >& IDatabaseTable< T_DATA >::variableNames() const noexcept {
603 return variable_names_;
607 template <
typename T_DATA >
608 const std::string& IDatabaseTable< T_DATA >::variableName(
const std::size_t k)
const {
609 if (variable_names_.size() <= k)
611 return variable_names_[k];
615 template <
typename T_DATA >
616 std::size_t IDatabaseTable< T_DATA >::columnFromVariableName(std::string_view name)
const {
617 const std::size_t size = variable_names_.size();
618 for (std::size_t i = 0; i < size; ++i)
619 if (variable_names_[i] == name)
return i;
625 template <
typename T_DATA >
626 typename IDatabaseTable< T_DATA >::template DBVector< std::size_t >
627 IDatabaseTable< T_DATA >::columnsFromVariableName(std::string_view name)
const {
628 const std::size_t size = variable_names_.size();
629 DBVector< std::size_t > cols;
630 for (std::size_t i = 0; i < size; ++i)
631 if (variable_names_[i] == name) cols.push_back(i);
640 template <
typename T_DATA >
641 std::size_t IDatabaseTable< T_DATA >::nbVariables() const noexcept {
642 return variable_names_.size();
646 template <
typename T_DATA >
647 std::size_t IDatabaseTable< T_DATA >::size() const noexcept {
652 template <
typename T_DATA >
653 std::size_t IDatabaseTable< T_DATA >::nbRows() const noexcept {
658 template <
typename T_DATA >
659 bool IDatabaseTable< T_DATA >::empty() const noexcept {
660 return rows_.empty();
664 template <
typename T_DATA >
665 void IDatabaseTable< T_DATA >::_updateHandlers_(std::size_t new_size)
const {
666 const std::size_t db_size = rows_.size();
668 _safe_handlers_mutex_.lock();
669 for (
auto handler: _list_of_safe_handlers_) {
670 if ((handler->_end_index_ == db_size) || (handler->_end_index_ > new_size)) {
671 handler->_end_index_ = new_size;
677 _safe_handlers_mutex_.unlock();
680 _end_->_index_ = new_size;
681 _end_->_end_index_ = new_size;
682 _end_safe_->_index_ = new_size;
683 _end_safe_->_end_index_ = new_size;
687 template <
typename T_DATA >
688 void IDatabaseTable< T_DATA >::_attachHandler_(HandlerSafe* handler)
const {
689 _safe_handlers_mutex_.lock();
690 _list_of_safe_handlers_.push_back(handler);
691 _safe_handlers_mutex_.unlock();
695 template <
typename T_DATA >
696 void IDatabaseTable< T_DATA >::_detachHandler_(HandlerSafe* handler)
const {
697 _safe_handlers_mutex_.lock();
699 for (
auto iter = _list_of_safe_handlers_.rbegin(); iter != _list_of_safe_handlers_.rend();
701 if (*iter == handler) {
702 *iter = _list_of_safe_handlers_.back();
703 _list_of_safe_handlers_.pop_back();
708 _safe_handlers_mutex_.unlock();
712 template <
typename T_DATA >
713 bool IDatabaseTable< T_DATA >::isRowSizeOK_(
const std::size_t size)
const {
714 return (size == variable_names_.size());
718 template <
typename T_DATA >
719 void IDatabaseTable< T_DATA >::insertRow(
720 const typename IDatabaseTable< T_DATA >::template Row< T_DATA >& row,
721 const typename IDatabaseTable< T_DATA >::IsMissing contains_missing) {
723 this->insertRow(
typename IDatabaseTable< T_DATA >::template Row< T_DATA >(row),
728 template <
typename T_DATA >
729 void IDatabaseTable< T_DATA >::insertRow(
730 typename IDatabaseTable< T_DATA >::template Row< T_DATA >&& new_row,
731 const typename IDatabaseTable< T_DATA >::IsMissing contains_missing) {
733 if (!isRowSizeOK_(new_row.size()))
735 "the new row is of size " << new_row.size()
736 <<
", which is different from the number of columns "
737 <<
"of the database, i.e., " << variable_names_.size());
739 _updateHandlers_(rows_.size() + 1);
740 rows_.push_back(std::move(new_row));
742 has_row_missing_val_.push_back(contains_missing);
750 template <
typename T_DATA >
751 void IDatabaseTable< T_DATA >::insertRows(
752 typename IDatabaseTable< T_DATA >::template Matrix< T_DATA >&& new_rows,
753 const typename IDatabaseTable< T_DATA >::template DBVector<
754 typename IDatabaseTable< T_DATA >::IsMissing >& rows_have_missing_vals) {
755 if (new_rows.empty())
return;
759 if (rows_have_missing_vals.size() != new_rows.size())
761 "the number of new rows (i.e., "
763 <<
") is different from the number of missing values indicators ("
764 << rows_have_missing_vals.size());
767 const std::size_t new_size = new_rows[0].size();
769 for (
const auto& row: new_rows) {
770 if (row.size() != new_size) {
777 if (!isRowSizeOK_(new_size)) {
779 "the new rows have " << new_size
780 <<
" columns, which is different from the number of columns "
781 <<
"of the database, i.e., " << variable_names_.size());
784 const std::size_t nb_new_rows = new_rows.size();
785 const std::size_t new_db_size = rows_.size() + nb_new_rows;
787 rows_.reserve(new_db_size);
788 has_row_missing_val_.reserve(new_db_size);
790 for (std::size_t i = std::size_t(0); i < nb_new_rows; ++i) {
791 rows_.push_back(std::move(new_rows[i]));
792 has_row_missing_val_.push_back(rows_have_missing_vals[i]);
795 _updateHandlers_(new_db_size);
799 template <
typename T_DATA >
800 void IDatabaseTable< T_DATA >::insertRows(
801 const typename IDatabaseTable< T_DATA >::template Matrix< T_DATA >& new_rows,
802 const typename IDatabaseTable< T_DATA >::template DBVector<
803 typename IDatabaseTable< T_DATA >::IsMissing >& rows_have_missing_vals) {
804 if (new_rows.empty())
return;
808 if (rows_have_missing_vals.size() != new_rows.size())
810 "the number of new rows (i.e., "
812 <<
") is different from the number of missing values indicators ("
813 << rows_have_missing_vals.size());
816 const std::size_t new_size = new_rows[0].size();
818 for (
const auto& row: new_rows) {
819 if (row.size() != new_size) {
826 std::size_t db_size = rows_.size();
828 if (!isRowSizeOK_(new_size)) {
830 "the new rows have " << new_size
831 <<
" columns, which is different from the number of columns "
832 <<
"of the database, i.e., " << variable_names_.size());
835 const std::size_t nb_new_rows = new_rows.size();
836 const std::size_t new_db_size = rows_.size() + nb_new_rows;
838 rows_.reserve(new_db_size);
839 has_row_missing_val_.reserve(new_db_size);
841 for (std::size_t i = std::size_t(0); i < nb_new_rows; ++i) {
842 rows_.push_back(new_rows[i]);
843 has_row_missing_val_.push_back(rows_have_missing_vals[i]);
846 _updateHandlers_(db_size);
850 template <
typename T_DATA >
851 void IDatabaseTable< T_DATA >::eraseRow(std::size_t index) {
852 const std::size_t db_size = rows_.size();
854 if (index < db_size) {
855 _updateHandlers_(db_size - 1);
856 rows_.erase(rows_.begin() + index);
857 has_row_missing_val_.erase(has_row_missing_val_.begin() + index);
862 template <
typename T_DATA >
863 void IDatabaseTable< T_DATA >::eraseLastRow() {
864 const std::size_t db_size = rows_.size();
867 _updateHandlers_(db_size - 1);
869 has_row_missing_val_.pop_back();
874 template <
typename T_DATA >
875 void IDatabaseTable< T_DATA >::eraseFirstRow() {
876 const std::size_t db_size = rows_.size();
879 _updateHandlers_(db_size - 1);
880 rows_.erase(rows_.begin());
881 has_row_missing_val_.erase(has_row_missing_val_.begin());
886 template <
typename T_DATA >
887 void IDatabaseTable< T_DATA >::eraseAllRows() {
890 has_row_missing_val_.clear();
894 template <
typename T_DATA >
895 void IDatabaseTable< T_DATA >::eraseFirstRows(
const std::size_t nb_rows) {
896 const std::size_t db_size = rows_.size();
898 if (nb_rows >= db_size) {
901 _updateHandlers_(db_size - nb_rows);
902 rows_.erase(rows_.begin(), rows_.begin() + nb_rows);
903 has_row_missing_val_.erase(has_row_missing_val_.begin(),
904 has_row_missing_val_.begin() + nb_rows);
909 template <
typename T_DATA >
910 void IDatabaseTable< T_DATA >::eraseLastRows(
const std::size_t nb_rows) {
911 const std::size_t db_size = rows_.size();
913 if (nb_rows >= db_size) {
916 _updateHandlers_(db_size - nb_rows);
917 rows_.erase(rows_.begin() + (db_size - nb_rows), rows_.begin() + db_size);
918 has_row_missing_val_.erase(has_row_missing_val_.begin() + (db_size - nb_rows),
919 has_row_missing_val_.begin() + db_size);
924 template <
typename T_DATA >
925 void IDatabaseTable< T_DATA >::eraseRows(std::size_t deb, std::size_t end) {
926 if (deb > end) std::swap(deb, end);
928 const std::size_t db_size = rows_.size();
930 if (end >= db_size) {
931 if (deb >= db_size) {
934 eraseLastRows(db_size - deb);
937 _updateHandlers_(db_size - (end - deb));
938 rows_.erase(rows_.begin() + deb, rows_.begin() + end);
939 has_row_missing_val_.erase(has_row_missing_val_.begin() + deb,
940 has_row_missing_val_.begin() + end);
945 template <
typename T_DATA >
946 void IDatabaseTable< T_DATA >::clear() {
949 has_row_missing_val_.clear();
950 variable_names_.clear();
954 template <
typename T_DATA >
955 const std::vector< std::string >& IDatabaseTable< T_DATA >::missingSymbols()
const {
956 return missing_symbols_;
960 template <
typename T_DATA >
961 void IDatabaseTable< T_DATA >::setMaxNbThreads(
const std::size_t nb)
const {
962 if (nb == std::size_t(0)) max_nb_threads_ = std::size_t(1);
963 else max_nb_threads_ = nb;
967 template <
typename T_DATA >
968 std::size_t IDatabaseTable< T_DATA >::nbThreads()
const {
969 return max_nb_threads_;
974 template <
typename T_DATA >
975 void IDatabaseTable< T_DATA >::setMinNbRowsPerThread(
const std::size_t nb)
const {
976 if (nb == std::size_t(0)) min_nb_rows_per_thread_ = std::size_t(1);
977 else min_nb_rows_per_thread_ = nb;
981 template <
typename T_DATA >
982 std::size_t IDatabaseTable< T_DATA >::minNbRowsPerThread()
const {
983 return min_nb_rows_per_thread_;
987 template <
typename T_DATA >
988 std::size_t IDatabaseTable< T_DATA >::nbProcessingThreads_()
const {
989 const std::size_t db_size = nbRows();
990 std::size_t nb_threads = db_size / min_nb_rows_per_thread_;
991 if (nb_threads < 1) nb_threads = 1;
992 else if (nb_threads > max_nb_threads_) nb_threads = max_nb_threads_;
998 template <
typename T_DATA >
999 std::vector< std::pair< std::size_t, std::size_t > >
1000 IDatabaseTable< T_DATA >::rangesProcessingThreads_(
const std::size_t nb_threads)
const {
1001 std::vector< std::pair< std::size_t, std::size_t > > ranges;
1002 const std::size_t db_size = nbRows();
1003 std::size_t nb_rows_per_thread = db_size / nb_threads;
1004 std::size_t rest_rows = db_size - nb_rows_per_thread * nb_threads;
1008 std::size_t begin_index = std::size_t(0);
1009 for (std::size_t i = std::size_t(0); i < nb_threads; ++i) {
1010 std::size_t end_index = begin_index + nb_rows_per_thread;
1011 if (rest_rows != std::size_t(0)) {
1015 ranges.push_back(std::pair< std::size_t, std::size_t >(begin_index, end_index));
1016 begin_index = end_index;
1023 template <
typename T_DATA >
1024 void IDatabaseTable< T_DATA >::setAllRowsWeight(
const double new_weight) {
1026 const std::size_t nb_threads = nbProcessingThreads_();
1027 const std::vector< std::pair< std::size_t, std::size_t > > ranges
1028 = rangesProcessingThreads_(nb_threads);
1032 auto threadedAssign = [
this, &ranges, new_weight](
const std::size_t this_thread,
1033 const std::size_t nb_threads) ->
void {
1034 const std::size_t begin_index = ranges[this_thread].first;
1035 const std::size_t end_index = ranges[this_thread].second;
1037 for (std::size_t i = begin_index; i < end_index; ++i) {
1038 this->rows_[i].setWeight(new_weight);
1043 ThreadExecutor::execute(nb_threads, threadedAssign);
1047 template <
typename T_DATA >
1048 void IDatabaseTable< T_DATA >::setWeight(
const std::size_t i,
const double weight) {
1050 const std::size_t dbsize = nbRows();
1053 "it is impossible to set the weight of record #"
1054 << i <<
" because the database contains only " << nbRows() <<
" records");
1060 "it is impossible to set " << weight <<
" as a weight of record #" << i
1061 <<
" because this weight is negative");
1064 rows_[i].setWeight(weight);
1068 template <
typename T_DATA >
1069 double IDatabaseTable< T_DATA >::weight(
const std::size_t i)
const {
1071 const std::size_t dbsize = nbRows();
1074 "it is impossible to get the weight of record #"
1075 << i <<
" because the database contains only " << nbRows() <<
" records");
1078 return rows_[i].weight();
1082 template <
typename T_DATA >
1083 double IDatabaseTable< T_DATA >::weight()
const {
1085 for (
const auto& row: rows_)
The common class for the tabular database tables.
Exception : a pointer or a reference on a nullptr (0) object.
Exception : out of bound.
Exception : problem with size.
Exception : a looked-for element could not be found.
The base class for all database handlers.
Handler(const IDatabaseTable< T_DATA > &db)
default constructor
The common class for the tabular database tables.
#define GUM_ERROR(type, msg)
include the inlined functions if necessary
gum is the global namespace for all aGrUM entities