50#ifndef DOXYGEN_SHOULD_SKIP_THIS
61 template <
typename T_DATA >
63 DBHandler< T_DATA >(), _db_(&db), _row_(&(db.content())),
64 _end_index_(std::size_t(_row_->size())) {
65 GUM_CONSTRUCTOR(IDatabaseTable::Handler);
69 template <
typename T_DATA >
70 INLINE IDatabaseTable< T_DATA >::Handler::Handler(
71 const typename IDatabaseTable< T_DATA >::Handler& h) :
72 DBHandler< T_DATA >(), _db_(h._db_), _row_(h._row_), _index_(h._index_),
73 _begin_index_(h._begin_index_), _end_index_(h._end_index_) {
74 GUM_CONS_CPY(IDatabaseTable::Handler);
78 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 INLINE IDatabaseTable< T_DATA >::Handler::~Handler() {
89 GUM_DESTRUCTOR(IDatabaseTable::Handler);
93 template <
typename T_DATA >
94 INLINE
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 INLINE
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 INLINE
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 INLINE
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 INLINE
typename IDatabaseTable< T_DATA >::Handler&
133 IDatabaseTable< T_DATA >::Handler::operator++() {
139 template <
typename T_DATA >
140 INLINE
typename IDatabaseTable< T_DATA >::Handler&
141 IDatabaseTable< T_DATA >::Handler::operator--() {
142 if (_index_ > _begin_index_) --_index_;
147 template <
typename T_DATA >
148 INLINE
typename IDatabaseTable< T_DATA >::Handler&
149 IDatabaseTable< T_DATA >::Handler::operator+=(
const std::size_t i) {
155 template <
typename T_DATA >
156 INLINE
typename IDatabaseTable< T_DATA >::Handler&
157 IDatabaseTable< T_DATA >::Handler::operator-=(
const std::size_t i) {
158 if (_index_ >= _begin_index_ + i) _index_ -= i;
159 else _index_ = _begin_index_;
164 template <
typename T_DATA >
165 INLINE
bool IDatabaseTable< T_DATA >::Handler::operator==(
const Handler& handler)
const {
166 return _index_ == handler._index_;
170 template <
typename T_DATA >
171 INLINE
bool IDatabaseTable< T_DATA >::Handler::operator!=(
const Handler& handler)
const {
172 return _index_ != handler._index_;
176 template <
typename T_DATA >
177 INLINE std::size_t IDatabaseTable< T_DATA >::Handler::size()
const {
178 return _end_index_ - _begin_index_;
182 template <
typename T_DATA >
183 INLINE std::size_t IDatabaseTable< T_DATA >::Handler::DBSize()
const {
184 if (_row_ !=
nullptr)
return _row_->size();
185 else return std::size_t(0);
189 template <
typename T_DATA >
190 INLINE
typename IDatabaseTable< T_DATA >::Handler::const_reference
191 IDatabaseTable< T_DATA >::Handler::rowSafe()
const {
194 return _row_->operator[](_index_);
198 template <
typename T_DATA >
199 INLINE
typename IDatabaseTable< T_DATA >::Handler::reference
200 IDatabaseTable< T_DATA >::Handler::rowSafe() {
203 return const_cast< Matrix< T_DATA >*
>(_row_)->
operator[](_index_);
207 template <
typename T_DATA >
208 INLINE
typename IDatabaseTable< T_DATA >::Handler::const_reference
209 IDatabaseTable< T_DATA >::Handler::row()
const {
210 return _row_->operator[](_index_);
214 template <
typename T_DATA >
215 INLINE
typename IDatabaseTable< T_DATA >::Handler::reference
216 IDatabaseTable< T_DATA >::Handler::row() {
217 return const_cast< Matrix< T_DATA >*
>(_row_)->
operator[](_index_);
221 template <
typename T_DATA >
222 INLINE
void IDatabaseTable< T_DATA >::Handler::nextRow() {
227 template <
typename T_DATA >
228 INLINE std::size_t IDatabaseTable< T_DATA >::Handler::numRow()
const {
229 return (_index_ >= _begin_index_) ? _index_ - _begin_index_ : 0;
233 template <
typename T_DATA >
234 INLINE
bool IDatabaseTable< T_DATA >::Handler::hasRows()
const {
235 return (_index_ < _end_index_);
239 template <
typename T_DATA >
240 INLINE
void IDatabaseTable< T_DATA >::Handler::reset() {
241 _index_ = _begin_index_;
246 template <
typename T_DATA >
247 INLINE
typename IDatabaseTable< T_DATA >::Handler
248 IDatabaseTable< T_DATA >::Handler::begin()
const {
249 Handler handler(*
this);
256 template <
typename T_DATA >
257 INLINE
typename IDatabaseTable< T_DATA >::Handler
258 IDatabaseTable< T_DATA >::Handler::end()
const {
259 Handler handler(*
this);
260 handler._index_ = _end_index_;
265 template <
typename T_DATA >
266 INLINE
void IDatabaseTable< T_DATA >::Handler::setRange(std::size_t first, std::size_t last) {
267 if (first > last) std::swap(first, last);
272 if (last > _row_->size())
274 "the database has fewer rows (" << _row_->size() <<
") than the upper range ("
275 << last <<
") specified to the handler")
277 _begin_index_ = first;
283 template < typename T_DATA >
284 INLINE
std::pair<
std::
size_t,
std::
size_t > IDatabaseTable< T_DATA >::Handler::range()
const {
285 return std::pair< std::size_t, std::size_t >(_begin_index_, _end_index_);
289 template <
typename T_DATA >
291 IDatabaseTable< T_DATA >::Handler::variableNames()
const {
292 return _db_->variableNames();
296 template <
typename T_DATA >
297 INLINE std::size_t IDatabaseTable< T_DATA >::Handler::nbVariables()
const {
298 if (_db_ !=
nullptr)
return _db_->variableNames().size();
303 template <
typename T_DATA >
304 INLINE
const IDatabaseTable< T_DATA >& IDatabaseTable< T_DATA >::Handler::database()
const {
305 if (_db_ ==
nullptr) {
316 template <
typename T_DATA >
317 INLINE
void IDatabaseTable< T_DATA >::HandlerSafe::_attachHandler_() {
318 if (this->_db_ !=
nullptr) { this->_db_->_attachHandler_(
this); }
322 template <
typename T_DATA >
323 INLINE
void IDatabaseTable< T_DATA >::HandlerSafe::_detachHandler_() {
324 if (this->_db_ !=
nullptr) { this->_db_->_detachHandler_(
this); }
328 template <
typename T_DATA >
329 INLINE IDatabaseTable< T_DATA >::HandlerSafe::HandlerSafe(
const IDatabaseTable< T_DATA >& db) :
330 IDatabaseTable< T_DATA >::Handler(db) {
332 GUM_CONSTRUCTOR(IDatabaseTable::HandlerSafe);
336 template <
typename T_DATA >
337 INLINE IDatabaseTable< T_DATA >::HandlerSafe::HandlerSafe(
338 const typename IDatabaseTable< T_DATA >::HandlerSafe& h) :
339 IDatabaseTable< T_DATA >::Handler(h) {
341 GUM_CONS_CPY(IDatabaseTable::HandlerSafe);
345 template <
typename T_DATA >
346 INLINE IDatabaseTable< T_DATA >::HandlerSafe::HandlerSafe(
347 typename IDatabaseTable< T_DATA >::HandlerSafe&& h) :
348 IDatabaseTable< T_DATA >::Handler(
std::move(h)) {
350 GUM_CONS_MOV(IDatabaseTable::HandlerSafe);
354 template <
typename T_DATA >
355 INLINE IDatabaseTable< T_DATA >::HandlerSafe::~HandlerSafe() {
357 GUM_DESTRUCTOR(IDatabaseTable::HandlerSafe);
361 template <
typename T_DATA >
362 INLINE
typename IDatabaseTable< T_DATA >::HandlerSafe&
363 IDatabaseTable< T_DATA >::HandlerSafe::operator=(
364 const typename IDatabaseTable< T_DATA >::HandlerSafe& h) {
365 if (this->_db_ != h._db_) {
371 IDatabaseTable< T_DATA >::Handler::operator=(h);
376 template <
typename T_DATA >
377 INLINE
typename IDatabaseTable< T_DATA >::HandlerSafe&
378 IDatabaseTable< T_DATA >::HandlerSafe::operator=(
379 const typename IDatabaseTable< T_DATA >::Handler& h) {
380 return this->operator=(
dynamic_cast< const IDatabaseTable< T_DATA >::HandlerSafe&
>(h));
384 template <
typename T_DATA >
385 INLINE
typename IDatabaseTable< T_DATA >::HandlerSafe&
386 IDatabaseTable< T_DATA >::HandlerSafe::operator=(
387 typename IDatabaseTable< T_DATA >::HandlerSafe&& h) {
388 if (this->_db_ != h._db_) {
394 IDatabaseTable< T_DATA >::Handler::operator=(std::move(h));
399 template <
typename T_DATA >
400 INLINE
typename IDatabaseTable< T_DATA >::HandlerSafe&
401 IDatabaseTable< T_DATA >::HandlerSafe::operator=(
402 typename IDatabaseTable< T_DATA >::Handler&& h) {
403 return this->operator=(std::move(
dynamic_cast< IDatabaseTable< T_DATA >::HandlerSafe&
>(h)));
411 template <
typename T_DATA >
412 void IDatabaseTable< T_DATA >::_createEndIterators_() {
413 _end_ =
new iterator(*
this);
415 _end_safe_ =
new iterator_safe(*
this);
423 template <
typename T_DATA >
424 IDatabaseTable< T_DATA >::IDatabaseTable(
425 const typename IDatabaseTable< T_DATA >::MissingValType& missing_symbols,
426 const std::vector< std::string >& var_names) :
427 variable_names_(var_names), missing_symbols_(missing_symbols) {
429 _createEndIterators_();
431 GUM_CONSTRUCTOR(IDatabaseTable);
435 template <
typename T_DATA >
436 IDatabaseTable< T_DATA >::IDatabaseTable(
const IDatabaseTable< T_DATA >& from) :
437 variable_names_(from.variable_names_), rows_(from.rows_),
438 missing_symbols_(from.missing_symbols_), has_row_missing_val_(from.has_row_missing_val_),
439 max_nb_threads_(from.max_nb_threads_),
440 min_nb_rows_per_thread_(from.min_nb_rows_per_thread_) {
442 _createEndIterators_();
444 GUM_CONS_CPY(IDatabaseTable);
448 template <
typename T_DATA >
449 IDatabaseTable< T_DATA >::IDatabaseTable(IDatabaseTable< T_DATA >&& from) :
450 variable_names_(
std::move(from.variable_names_)), rows_(
std::move(from.rows_)),
451 missing_symbols_(
std::move(from.missing_symbols_)),
452 has_row_missing_val_(
std::move(from.has_row_missing_val_)),
453 max_nb_threads_(from.max_nb_threads_),
454 min_nb_rows_per_thread_(from.min_nb_rows_per_thread_) {
456 _createEndIterators_();
458 GUM_CONS_MOV(IDatabaseTable);
462 template <
typename T_DATA >
463 IDatabaseTable< T_DATA >::~IDatabaseTable() {
465 _safe_handlers_mutex_.lock();
466 for (
auto handler: _list_of_safe_handlers_) {
467 handler->_db_ =
nullptr;
468 handler->_row_ =
nullptr;
469 handler->_end_index_ = 0;
470 handler->_index_ = 0;
472 _safe_handlers_mutex_.unlock();
477 GUM_DESTRUCTOR(IDatabaseTable);
481 template <
typename T_DATA >
482 IDatabaseTable< T_DATA >&
483 IDatabaseTable< T_DATA >::operator=(
const IDatabaseTable< T_DATA >& from) {
486 _safe_handlers_mutex_.lock();
487 for (
auto handler: _list_of_safe_handlers_) {
488 handler->_db_ =
nullptr;
489 handler->_row_ =
nullptr;
490 handler->_end_index_ = 0;
491 handler->_index_ = 0;
493 _list_of_safe_handlers_.clear();
494 _safe_handlers_mutex_.unlock();
497 variable_names_ = from.variable_names_;
498 missing_symbols_ = from.missing_symbols_;
499 has_row_missing_val_ = from.has_row_missing_val_;
500 max_nb_threads_ = from.max_nb_threads_;
501 min_nb_rows_per_thread_ = from.min_nb_rows_per_thread_;
504 const std::size_t db_size = rows_.size();
505 _end_->_index_ = db_size;
506 _end_->_end_index_ = db_size;
507 _end_safe_->_index_ = db_size;
508 _end_safe_->_end_index_ = db_size;
515 template <
typename T_DATA >
516 IDatabaseTable< T_DATA >& IDatabaseTable< T_DATA >::operator=(IDatabaseTable< T_DATA >&& from) {
519 _safe_handlers_mutex_.lock();
520 for (
auto handler: _list_of_safe_handlers_) {
521 handler->_db_ =
nullptr;
522 handler->_row_ =
nullptr;
523 handler->_end_index_ = 0;
524 handler->_index_ = 0;
526 _safe_handlers_mutex_.unlock();
528 rows_ = std::move(from.rows_);
529 variable_names_ = std::move(from.variable_names_);
530 missing_symbols_ = std::move(from.missing_symbols_);
531 has_row_missing_val_ = std::move(from.has_row_missing_val_);
532 max_nb_threads_ = from.max_nb_threads_;
533 min_nb_rows_per_thread_ = from.min_nb_rows_per_thread_;
536 const std::size_t db_size = rows_.size();
537 _end_->_index_ = db_size;
538 _end_->_end_index_ = db_size;
539 _end_safe_->_index_ = db_size;
540 _end_safe_->_end_index_ = db_size;
547 template <
typename T_DATA >
548 INLINE
typename IDatabaseTable< T_DATA >::Handler IDatabaseTable< T_DATA >::begin()
const {
549 return Handler(*
this);
553 template <
typename T_DATA >
554 INLINE
typename IDatabaseTable< T_DATA >::HandlerSafe
555 IDatabaseTable< T_DATA >::beginSafe()
const {
556 return HandlerSafe(*
this);
560 template <
typename T_DATA >
561 INLINE
const typename IDatabaseTable< T_DATA >::Handler&
562 IDatabaseTable< T_DATA >::end() const noexcept {
567 template <
typename T_DATA >
568 INLINE
const typename IDatabaseTable< T_DATA >::HandlerSafe&
569 IDatabaseTable< T_DATA >::endSafe() const noexcept {
574 template <
typename T_DATA >
575 INLINE
typename IDatabaseTable< T_DATA >::Handler IDatabaseTable< T_DATA >::handler()
const {
576 return Handler(*
this);
580 template <
typename T_DATA >
581 INLINE
typename IDatabaseTable< T_DATA >::HandlerSafe
582 IDatabaseTable< T_DATA >::handlerSafe()
const {
583 return HandlerSafe(*
this);
587 template <
typename T_DATA >
588 INLINE
const typename IDatabaseTable< T_DATA >::template Matrix< T_DATA >&
589 IDatabaseTable< T_DATA >::content() const noexcept {
594 template <
typename T_DATA >
595 bool IDatabaseTable< T_DATA >::hasMissingValues()
const {
596 for (
const auto& status: has_row_missing_val_)
597 if (status == IsMissing::True)
return true;
602 template <
typename T_DATA >
603 INLINE
bool IDatabaseTable< T_DATA >::hasMissingValues(
const std::size_t k)
const {
604 return has_row_missing_val_[k] == IsMissing::True;
608 template <
typename T_DATA >
609 INLINE
const std::vector< std::string >&
610 IDatabaseTable< T_DATA >::variableNames() const noexcept {
611 return variable_names_;
615 template <
typename T_DATA >
616 INLINE
const std::string& IDatabaseTable< T_DATA >::variableName(
const std::size_t k)
const {
617 if (variable_names_.size() <= k)
619 return variable_names_[k];
623 template <
typename T_DATA >
625 IDatabaseTable< T_DATA >::columnFromVariableName(
const std::string& name)
const {
626 const std::size_t size = variable_names_.size();
627 for (std::size_t i = 0; i < size; ++i)
628 if (variable_names_[i] == name)
return i;
634 template <
typename T_DATA >
635 INLINE
typename IDatabaseTable< T_DATA >::template DBVector< std::size_t >
636 IDatabaseTable< T_DATA >::columnsFromVariableName(
const std::string& name)
const {
637 const std::size_t size = variable_names_.size();
638 DBVector< std::size_t > cols;
639 for (std::size_t i = 0; i < size; ++i)
640 if (variable_names_[i] == name) cols.push_back(i);
649 template <
typename T_DATA >
650 INLINE std::size_t IDatabaseTable< T_DATA >::nbVariables() const noexcept {
651 return variable_names_.size();
655 template <
typename T_DATA >
656 INLINE std::size_t IDatabaseTable< T_DATA >::size() const noexcept {
661 template <
typename T_DATA >
662 INLINE std::size_t IDatabaseTable< T_DATA >::nbRows() const noexcept {
667 template <
typename T_DATA >
668 INLINE
bool IDatabaseTable< T_DATA >::empty() const noexcept {
669 return rows_.empty();
673 template <
typename T_DATA >
674 void IDatabaseTable< T_DATA >::_updateHandlers_(std::size_t new_size)
const {
675 const std::size_t db_size = rows_.size();
677 _safe_handlers_mutex_.lock();
678 for (
auto handler: _list_of_safe_handlers_) {
679 if ((handler->_end_index_ == db_size) || (handler->_end_index_ > new_size)) {
680 handler->_end_index_ = new_size;
686 _safe_handlers_mutex_.unlock();
689 _end_->_index_ = new_size;
690 _end_->_end_index_ = new_size;
691 _end_safe_->_index_ = new_size;
692 _end_safe_->_end_index_ = new_size;
696 template <
typename T_DATA >
697 INLINE
void IDatabaseTable< T_DATA >::_attachHandler_(HandlerSafe* handler)
const {
698 _safe_handlers_mutex_.lock();
699 _list_of_safe_handlers_.push_back(handler);
700 _safe_handlers_mutex_.unlock();
704 template <
typename T_DATA >
705 void IDatabaseTable< T_DATA >::_detachHandler_(HandlerSafe* handler)
const {
706 _safe_handlers_mutex_.lock();
708 for (
auto iter = _list_of_safe_handlers_.rbegin(); iter != _list_of_safe_handlers_.rend();
710 if (*iter == handler) {
711 *iter = _list_of_safe_handlers_.back();
712 _list_of_safe_handlers_.pop_back();
717 _safe_handlers_mutex_.unlock();
721 template <
typename T_DATA >
722 INLINE
bool IDatabaseTable< T_DATA >::isRowSizeOK_(
const std::size_t size)
const {
723 return (size == variable_names_.size());
727 template <
typename T_DATA >
728 INLINE
void IDatabaseTable< T_DATA >::insertRow(
729 const typename IDatabaseTable< T_DATA >::template Row< T_DATA >& row,
730 const typename IDatabaseTable< T_DATA >::IsMissing contains_missing) {
732 this->insertRow(
typename IDatabaseTable< T_DATA >::template Row< T_DATA >(row),
737 template <
typename T_DATA >
738 void IDatabaseTable< T_DATA >::insertRow(
739 typename IDatabaseTable< T_DATA >::template Row< T_DATA >&& new_row,
740 const typename IDatabaseTable< T_DATA >::IsMissing contains_missing) {
742 if (!isRowSizeOK_(new_row.size()))
744 "the new row is of size " << new_row.size()
745 <<
", which is different from the number of columns "
746 <<
"of the database, i.e., " << variable_names_.size());
748 _updateHandlers_(rows_.size() + 1);
749 rows_.push_back(std::move(new_row));
751 has_row_missing_val_.push_back(contains_missing);
759 template <
typename T_DATA >
760 void IDatabaseTable< T_DATA >::insertRows(
761 typename IDatabaseTable< T_DATA >::template Matrix< T_DATA >&& new_rows,
762 const typename IDatabaseTable< T_DATA >::template DBVector<
763 typename IDatabaseTable< T_DATA >::IsMissing >& rows_have_missing_vals) {
764 if (new_rows.empty())
return;
768 if (rows_have_missing_vals.size() != new_rows.size())
770 "the number of new rows (i.e., "
772 <<
") is different from the number of missing values indicators ("
773 << rows_have_missing_vals.size());
776 const std::size_t new_size = new_rows[0].size();
778 for (
const auto& row: new_rows) {
779 if (row.size() != new_size) {
786 if (!isRowSizeOK_(new_size)) {
788 "the new rows have " << new_size
789 <<
" columns, which is different from the number of columns "
790 <<
"of the database, i.e., " << variable_names_.size());
793 const std::size_t nb_new_rows = new_rows.size();
794 const std::size_t new_db_size = rows_.size() + nb_new_rows;
796 rows_.reserve(new_db_size);
797 has_row_missing_val_.reserve(new_db_size);
799 for (std::size_t i = std::size_t(0); i < nb_new_rows; ++i) {
800 rows_.push_back(std::move(new_rows[i]));
801 has_row_missing_val_.push_back(rows_have_missing_vals[i]);
804 _updateHandlers_(new_db_size);
808 template <
typename T_DATA >
809 void IDatabaseTable< T_DATA >::insertRows(
810 const typename IDatabaseTable< T_DATA >::template Matrix< T_DATA >& new_rows,
811 const typename IDatabaseTable< T_DATA >::template DBVector<
812 typename IDatabaseTable< T_DATA >::IsMissing >& rows_have_missing_vals) {
813 if (new_rows.empty())
return;
817 if (rows_have_missing_vals.size() != new_rows.size())
819 "the number of new rows (i.e., "
821 <<
") is different from the number of missing values indicators ("
822 << rows_have_missing_vals.size());
825 const std::size_t new_size = new_rows[0].size();
827 for (
const auto& row: new_rows) {
828 if (row.size() != new_size) {
835 std::size_t db_size = rows_.size();
837 if (!isRowSizeOK_(new_size)) {
839 "the new rows have " << new_size
840 <<
" columns, which is different from the number of columns "
841 <<
"of the database, i.e., " << variable_names_.size());
844 const std::size_t nb_new_rows = new_rows.size();
845 const std::size_t new_db_size = rows_.size() + nb_new_rows;
847 rows_.reserve(new_db_size);
848 has_row_missing_val_.reserve(new_db_size);
850 for (std::size_t i = std::size_t(0); i < nb_new_rows; ++i) {
851 rows_.push_back(new_rows[i]);
852 has_row_missing_val_.push_back(rows_have_missing_vals[i]);
855 _updateHandlers_(db_size);
859 template <
typename T_DATA >
860 INLINE
void IDatabaseTable< T_DATA >::eraseRow(std::size_t index) {
861 const std::size_t db_size = rows_.size();
863 if (index < db_size) {
864 _updateHandlers_(db_size - 1);
865 rows_.erase(rows_.begin() + index);
866 has_row_missing_val_.erase(has_row_missing_val_.begin() + index);
871 template <
typename T_DATA >
872 INLINE
void IDatabaseTable< T_DATA >::eraseLastRow() {
873 const std::size_t db_size = rows_.size();
876 _updateHandlers_(db_size - 1);
878 has_row_missing_val_.pop_back();
883 template <
typename T_DATA >
884 INLINE
void IDatabaseTable< T_DATA >::eraseFirstRow() {
885 const std::size_t db_size = rows_.size();
888 _updateHandlers_(db_size - 1);
889 rows_.erase(rows_.begin());
890 has_row_missing_val_.erase(has_row_missing_val_.begin());
895 template <
typename T_DATA >
896 INLINE
void IDatabaseTable< T_DATA >::eraseAllRows() {
899 has_row_missing_val_.clear();
903 template <
typename T_DATA >
904 INLINE
void IDatabaseTable< T_DATA >::eraseFirstRows(
const std::size_t nb_rows) {
905 const std::size_t db_size = rows_.size();
907 if (nb_rows >= db_size) {
910 _updateHandlers_(db_size - nb_rows);
911 rows_.erase(rows_.begin(), rows_.begin() + nb_rows);
912 has_row_missing_val_.erase(has_row_missing_val_.begin(),
913 has_row_missing_val_.begin() + nb_rows);
918 template <
typename T_DATA >
919 INLINE
void IDatabaseTable< T_DATA >::eraseLastRows(
const std::size_t nb_rows) {
920 const std::size_t db_size = rows_.size();
922 if (nb_rows >= db_size) {
925 _updateHandlers_(db_size - nb_rows);
926 rows_.erase(rows_.begin() + (db_size - nb_rows), rows_.begin() + db_size);
927 has_row_missing_val_.erase(has_row_missing_val_.begin() + (db_size - nb_rows),
928 has_row_missing_val_.begin() + db_size);
933 template <
typename T_DATA >
934 INLINE
void IDatabaseTable< T_DATA >::eraseRows(std::size_t deb, std::size_t end) {
935 if (deb > end) std::swap(deb, end);
937 const std::size_t db_size = rows_.size();
939 if (end >= db_size) {
940 if (deb >= db_size) {
943 eraseLastRows(db_size - deb);
946 _updateHandlers_(db_size - (end - deb));
947 rows_.erase(rows_.begin() + deb, rows_.begin() + end);
948 has_row_missing_val_.erase(has_row_missing_val_.begin() + deb,
949 has_row_missing_val_.begin() + end);
954 template <
typename T_DATA >
955 INLINE
void IDatabaseTable< T_DATA >::clear() {
958 has_row_missing_val_.clear();
959 variable_names_.clear();
963 template <
typename T_DATA >
964 INLINE
const std::vector< std::string >& IDatabaseTable< T_DATA >::missingSymbols()
const {
965 return missing_symbols_;
969 template <
typename T_DATA >
970 void IDatabaseTable< T_DATA >::setMaxNbThreads(
const std::size_t nb)
const {
971 if (nb == std::size_t(0)) max_nb_threads_ = std::size_t(1);
972 else max_nb_threads_ = nb;
976 template <
typename T_DATA >
977 INLINE std::size_t IDatabaseTable< T_DATA >::nbThreads()
const {
978 return max_nb_threads_;
983 template <
typename T_DATA >
984 void IDatabaseTable< T_DATA >::setMinNbRowsPerThread(
const std::size_t nb)
const {
985 if (nb == std::size_t(0)) min_nb_rows_per_thread_ = std::size_t(1);
986 else min_nb_rows_per_thread_ = nb;
990 template <
typename T_DATA >
991 INLINE std::size_t IDatabaseTable< T_DATA >::minNbRowsPerThread()
const {
992 return min_nb_rows_per_thread_;
996 template <
typename T_DATA >
997 std::size_t IDatabaseTable< T_DATA >::nbProcessingThreads_()
const {
998 const std::size_t db_size = nbRows();
999 std::size_t nb_threads = db_size / min_nb_rows_per_thread_;
1000 if (nb_threads < 1) nb_threads = 1;
1001 else if (nb_threads > max_nb_threads_) nb_threads = max_nb_threads_;
1007 template <
typename T_DATA >
1008 std::vector< std::pair< std::size_t, std::size_t > >
1009 IDatabaseTable< T_DATA >::rangesProcessingThreads_(
const std::size_t nb_threads)
const {
1010 std::vector< std::pair< std::size_t, std::size_t > > ranges;
1011 const std::size_t db_size = nbRows();
1012 std::size_t nb_rows_per_thread = db_size / nb_threads;
1013 std::size_t rest_rows = db_size - nb_rows_per_thread * nb_threads;
1017 std::size_t begin_index = std::size_t(0);
1018 for (std::size_t i = std::size_t(0); i < nb_threads; ++i) {
1019 std::size_t end_index = begin_index + nb_rows_per_thread;
1020 if (rest_rows != std::size_t(0)) {
1024 ranges.push_back(std::pair< std::size_t, std::size_t >(begin_index, end_index));
1025 begin_index = end_index;
1032 template <
typename T_DATA >
1033 void IDatabaseTable< T_DATA >::setAllRowsWeight(
const double new_weight) {
1035 const std::size_t nb_threads = nbProcessingThreads_();
1036 const std::vector< std::pair< std::size_t, std::size_t > > ranges
1037 = rangesProcessingThreads_(nb_threads);
1041 auto threadedAssign = [
this, &ranges, new_weight](
const std::size_t this_thread,
1042 const std::size_t nb_threads) ->
void {
1043 const std::size_t begin_index = ranges[this_thread].first;
1044 const std::size_t end_index = ranges[this_thread].second;
1046 for (std::size_t i = begin_index; i < end_index; ++i) {
1047 this->rows_[i].setWeight(new_weight);
1052 ThreadExecutor::execute(nb_threads, threadedAssign);
1056 template <
typename T_DATA >
1057 void IDatabaseTable< T_DATA >::setWeight(
const std::size_t i,
const double weight) {
1059 const std::size_t dbsize = nbRows();
1062 "it is impossible to set the weight of record #"
1063 << i <<
" because the database contains only " << nbRows() <<
" records");
1069 "it is impossible to set " << weight <<
" as a weight of record #" << i
1070 <<
" because this weight is negative");
1073 rows_[i].setWeight(weight);
1077 template <
typename T_DATA >
1078 double IDatabaseTable< T_DATA >::weight(
const std::size_t i)
const {
1080 const std::size_t dbsize = nbRows();
1083 "it is impossible to get the weight of record #"
1084 << i <<
" because the database contains only " << nbRows() <<
" records");
1087 return rows_[i].weight();
1091 template <
typename T_DATA >
1092 double IDatabaseTable< T_DATA >::weight()
const {
1094 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