/home/marcle/src/R/microsimulation/src/pqueue.cpp
Go to the documentation of this file.
#include<Rcpp.h>
namespace ssim {
using namespace Rcpp;
struct pqueueElement {
double priority;
long _order;
bool active;
SEXP event;
pqueueElement(double priority, long order, bool active, SEXP event)
: priority(priority), _order(order), active(active), event(event) { }
virtual ~pqueueElement() = default;
};
struct pqueueElementComparator {
bool smaller;
pqueueElementComparator(bool smaller = true) : smaller(smaller) {}
bool operator()(pqueueElement const& msg1, pqueueElement const& msg2) const {
return (smaller ? msg1.priority > msg2.priority : msg1.priority < msg2.priority) ||
(msg1.priority == msg2.priority && msg1._order > msg2._order);
}
};
class pqueue {
private:
std::vector<pqueueElement> _elements;
pqueueElementComparator _compare;
long _entryOrder;
bool _anyCancelled;
using size_type = std::vector<pqueueElement>::size_type;
public:
explicit pqueue(bool smaller = true) {
_compare = pqueueElementComparator(smaller);
_entryOrder = 0;
_anyCancelled = false;
}
void pushElement(pqueueElement element)
{
_elements.push_back(std::move(element));
std::push_heap(_elements.begin(), _elements.end(), _compare);
}
void push(double priority, SEXP event)
{
pqueueElement element(priority, _entryOrder, true, event);
pushElement(std::move(element));
// _elements.push_back(std::move(element));
// std::push_heap(_elements.begin(), _elements.end(), _compare);
_entryOrder++;
}
pqueueElement popElement()
{
try {
if (empty()) {
throw std::length_error("Empty priority queue");
}
while(!_elements.empty()) {
std::pop_heap(_elements.begin(), _elements.end(), _compare);
pqueueElement result = std::move(_elements.back());
_elements.pop_back();
if (result.active)
return result; // change: std::move *not* used here
}
} catch(std::exception &ex) {
forward_exception_to_r(ex);
} catch(...) {
::Rf_error("c++ exception (unknown reason)");
}
return _elements[0]; // never called (prevents -Wreturn-type warning)
}
List pop() {
pqueueElement element = std::move(popElement());
return List::create(_["priority"]=element.priority, _["event"]=element.event);
}
bool empty() {
if (_elements.empty()) return true; // empty queue
else if (!_anyCancelled) return false; // queue not empty and no cancelled events
else { // loop through to see if any of the elements are active
for(size_type i=0; i<_elements.size(); i++)
if(_elements[i].active) return false; // at least one active events
return true; // no active events
}
}
void clear () {
_elements.clear(); // assumes that elements are safe pointers
}
void cancel(Rcpp::Function predicate) {
if (!empty())
for(size_type i=0; i<_elements.size(); i++) {
if (as<bool>(predicate(_elements[i].event)))
_elements[i].active = false;
}
_anyCancelled = true;
}
template<class F>
void for_each(F f, bool remake = false) {
std::for_each(_elements.begin(), _elements.end(), f);
if (remake)
std::make_heap(_elements.begin(), _elements.end(), _compare);
}
virtual ~pqueue() = default;
};
RcppExport
SEXP pqueue__new(SEXP _lower) {
bool lower = as<bool>(_lower);
Rcpp::XPtr<pqueue> ptr(new pqueue(lower));
return wrap(ptr);
}
RcppExport
SEXP pqueue__push(SEXP _ptr, SEXP _priority, SEXP event) {
XPtr<pqueue> ptr = as<XPtr<pqueue> >(_ptr);
double priority = as<double>(_priority);
ptr->push(priority, event);
return R_NilValue;
}
RcppExport
SEXP pqueue__pop(SEXP _ptr) {
XPtr<pqueue> ptr = as<XPtr<pqueue> >(_ptr);
return wrap(ptr->pop());
}
RcppExport
SEXP pqueue__cancel(SEXP _ptr, SEXP _predicate) {
XPtr<pqueue> ptr = as<XPtr<pqueue> >(_ptr);
Function predicate = as<Function>(_predicate);
ptr->cancel(predicate);
return R_NilValue;
}
RcppExport
SEXP pqueue__empty(SEXP _ptr) {
XPtr<pqueue> ptr = as<XPtr<pqueue> >(_ptr);
return wrap(ptr->empty());
}
RcppExport
SEXP pqueue__clear(SEXP _ptr) {
XPtr<pqueue> ptr = as<XPtr<pqueue> >(_ptr);
ptr->clear();
return R_NilValue;
}
} // namespace ssim
ssim::pqueue__clear
RcppExport SEXP pqueue__clear(SEXP _ptr)
Definition: pqueue.cpp:158
ssim::pqueue::pushElement
void pushElement(pqueueElement element)
Definition: pqueue.cpp:41
ssim::pqueue::for_each
void for_each(F f, bool remake=false)
Definition: pqueue.cpp:119
ssim::pqueue__cancel
RcppExport SEXP pqueue__cancel(SEXP _ptr, SEXP _predicate)
Definition: pqueue.cpp:146
ssim::pqueueElement::priority
double priority
Definition: pqueue.cpp:7
ssim::pqueueElementComparator::pqueueElementComparator
pqueueElementComparator(bool smaller=true)
Definition: pqueue.cpp:18
Rcpp::wrap
SEXP wrap(const std::vector< std::pair< T1, T2 > > v)
ssim::pqueueElement::pqueueElement
pqueueElement(double priority, long order, bool active, SEXP event)
Definition: pqueue.cpp:11
ssim::pqueueElement::_order
long _order
Definition: pqueue.cpp:8
ssim::pqueue::pop
List pop()
Definition: pqueue.cpp:81
ssim::pqueue::_entryOrder
long _entryOrder
Definition: pqueue.cpp:29
ssim::pqueue::push
void push(double priority, SEXP event)
Definition: pqueue.cpp:46
ssim::pqueue::popElement
pqueueElement popElement()
Definition: pqueue.cpp:58
ssim::pqueueElement::active
bool active
Definition: pqueue.cpp:9
ssim::pqueueElement::event
SEXP event
Definition: pqueue.cpp:10
ssim::pqueue__pop
RcppExport SEXP pqueue__pop(SEXP _ptr)
Definition: pqueue.cpp:141
ssim::pqueue::pqueue
pqueue(bool smaller=true)
Definition: pqueue.cpp:33
ssim::pqueueElementComparator::smaller
bool smaller
Definition: pqueue.cpp:17
ssim::pqueue::_compare
pqueueElementComparator _compare
Definition: pqueue.cpp:28
ssim::pqueue::cancel
void cancel(Rcpp::Function predicate)
Definition: pqueue.cpp:106
ssim::pqueue::empty
bool empty()
Definition: pqueue.cpp:88
ssim::pqueue__new
RcppExport SEXP pqueue__new(SEXP _lower)
Definition: pqueue.cpp:128
ssim::pqueueElementComparator
Definition: pqueue.cpp:16
ssim::pqueue::_anyCancelled
bool _anyCancelled
Definition: pqueue.cpp:30
ssim::pqueue::_elements
std::vector< pqueueElement > _elements
Definition: pqueue.cpp:27
ssim
name space for the Siena simulator.
Definition: microsimulation.cc:3
ssim::pqueue::size_type
std::vector< pqueueElement >::size_type size_type
Definition: pqueue.cpp:31
ssim::pqueueElement
Definition: pqueue.cpp:6
ssim::pqueue__push
RcppExport SEXP pqueue__push(SEXP _ptr, SEXP _priority, SEXP event)
Definition: pqueue.cpp:134
ssim::pqueue::clear
void clear()
Definition: pqueue.cpp:100
Rcpp
Definition: microsimulation.h:101
ssim::pqueue
Definition: pqueue.cpp:25
ssim::pqueueElementComparator::operator()
bool operator()(pqueueElement const &msg1, pqueueElement const &msg2) const
Definition: pqueue.cpp:19
ssim::pqueue__empty
RcppExport SEXP pqueue__empty(SEXP _ptr)
Definition: pqueue.cpp:153