Microsimulation API

/home/marcle/src/R/microsimulation/src/pqueue.cpp
Go to the documentation of this file.
1 #include<Rcpp.h>
2 namespace ssim {
3
4 using namespace Rcpp;
5
6 struct pqueueElement {
7 double priority;
8 long _order;
9 bool active;
10 SEXP event;
11 pqueueElement(double priority, long order, bool active, SEXP event)
12 : priority(priority), _order(order), active(active), event(event) { }
13 virtual ~pqueueElement() = default;
14 };
15
16 struct pqueueElementComparator {
17 bool smaller;
18 pqueueElementComparator(bool smaller = true) : smaller(smaller) {}
19 bool operator()(pqueueElement const& msg1, pqueueElement const& msg2) const {
20 return (smaller ? msg1.priority > msg2.priority : msg1.priority < msg2.priority) ||
21 (msg1.priority == msg2.priority && msg1._order > msg2._order);
22 }
23 };
24
25 class pqueue {
26 private:
27 std::vector<pqueueElement> _elements;
28 pqueueElementComparator _compare;
29 long _entryOrder;
30 bool _anyCancelled;
31 using size_type = std::vector<pqueueElement>::size_type;
32 public:
33 explicit pqueue(bool smaller = true) {
34 _compare = pqueueElementComparator(smaller);
35 _entryOrder = 0;
36 _anyCancelled = false;
37 }
41 void pushElement(pqueueElement element)
42 {
43 _elements.push_back(std::move(element));
44 std::push_heap(_elements.begin(), _elements.end(), _compare);
45 }
46 void push(double priority, SEXP event)
47 {
48 pqueueElement element(priority, _entryOrder, true, event);
49 pushElement(std::move(element));
50 // _elements.push_back(std::move(element));
51 // std::push_heap(_elements.begin(), _elements.end(), _compare);
52 _entryOrder++;
53 }
58 pqueueElement popElement()
59 {
60 try {
61 if (empty()) {
62 throw std::length_error("Empty priority queue");
63 }
64 while(!_elements.empty()) {
65 std::pop_heap(_elements.begin(), _elements.end(), _compare);
66 pqueueElement result = std::move(_elements.back());
67 _elements.pop_back();
68 if (result.active)
69 return result; // change: std::move *not* used here
70 }
71 } catch(std::exception &ex) {
72 forward_exception_to_r(ex);
73 } catch(...) {
74 ::Rf_error("c++ exception (unknown reason)");
75 }
76 return _elements[0]; // never called (prevents -Wreturn-type warning)
77 }
81 List pop() {
82 pqueueElement element = std::move(popElement());
83 return List::create(_["priority"]=element.priority, _["event"]=element.event);
84 }
88 bool empty() {
89 if (_elements.empty()) return true; // empty queue
90 else if (!_anyCancelled) return false; // queue not empty and no cancelled events
91 else { // loop through to see if any of the elements are active
92 for(size_type i=0; i<_elements.size(); i++)
93 if(_elements[i].active) return false; // at least one active events
94 return true; // no active events
95 }
96 }
100 void clear () {
101 _elements.clear(); // assumes that elements are safe pointers
102 }
106 void cancel(Rcpp::Function predicate) {
107 if (!empty())
108 for(size_type i=0; i<_elements.size(); i++) {
109 if (as<bool>(predicate(_elements[i].event)))
110 _elements[i].active = false;
111 }
112 _anyCancelled = true;
113 }
118 template<class F>
119 void for_each(F f, bool remake = false) {
120 std::for_each(_elements.begin(), _elements.end(), f);
121 if (remake)
122 std::make_heap(_elements.begin(), _elements.end(), _compare);
123 }
124 virtual ~pqueue() = default;
125 };
126
127 RcppExport
128 SEXP pqueue__new(SEXP _lower) {
129 bool lower = as<bool>(_lower);
130 Rcpp::XPtr<pqueue> ptr(new pqueue(lower));
131 return wrap(ptr);
132 }
133 RcppExport
134 SEXP pqueue__push(SEXP _ptr, SEXP _priority, SEXP event) {
135 XPtr<pqueue> ptr = as<XPtr<pqueue> >(_ptr);
136 double priority = as<double>(_priority);
137 ptr->push(priority, event);
138 return R_NilValue;
139 }
140 RcppExport
141 SEXP pqueue__pop(SEXP _ptr) {
142 XPtr<pqueue> ptr = as<XPtr<pqueue> >(_ptr);
143 return wrap(ptr->pop());
144 }
145 RcppExport
146 SEXP pqueue__cancel(SEXP _ptr, SEXP _predicate) {
147 XPtr<pqueue> ptr = as<XPtr<pqueue> >(_ptr);
148 Function predicate = as<Function>(_predicate);
149 ptr->cancel(predicate);
150 return R_NilValue;
151 }
152 RcppExport
153 SEXP pqueue__empty(SEXP _ptr) {
154 XPtr<pqueue> ptr = as<XPtr<pqueue> >(_ptr);
155 return wrap(ptr->empty());
156 }
157 RcppExport
158 SEXP pqueue__clear(SEXP _ptr) {
159 XPtr<pqueue> ptr = as<XPtr<pqueue> >(_ptr);
160 ptr->clear();
161 return R_NilValue;
162 }
163
164 } // namespace ssim
ssim::pqueue::pushElement
void pushElement(pqueueElement element)
Definition: pqueue.cpp:41
ssim::pqueue::size_type
std::vector< pqueueElement >::size_type size_type
Definition: pqueue.cpp:31
ssim::pqueue__clear
RcppExport SEXP pqueue__clear(SEXP _ptr)
Definition: pqueue.cpp:158
ssim::pqueue__cancel
RcppExport SEXP pqueue__cancel(SEXP _ptr, SEXP _predicate)
Definition: pqueue.cpp:146
ssim::pqueue::pqueue
pqueue(bool smaller=true)
Definition: pqueue.cpp:33
ssim::pqueueElement::_order
long _order
Definition: pqueue.cpp:8
ssim::pqueueElement
Definition: pqueue.cpp:6
ssim::pqueue::_anyCancelled
bool _anyCancelled
Definition: pqueue.cpp:30
ssim::pqueueElement::active
bool active
Definition: pqueue.cpp:9
ssim::pqueue
Definition: pqueue.cpp:25
ssim::pqueue::pop
List pop()
Definition: pqueue.cpp:81
ssim::pqueue::_elements
std::vector< pqueueElement > _elements
Definition: pqueue.cpp:27
ssim::pqueueElementComparator::smaller
bool smaller
Definition: pqueue.cpp:17
ssim::pqueue__pop
RcppExport SEXP pqueue__pop(SEXP _ptr)
Definition: pqueue.cpp:141
ssim::pqueue::for_each
void for_each(F f, bool remake=false)
Definition: pqueue.cpp:119
ssim::pqueue::cancel
void cancel(Rcpp::Function predicate)
Definition: pqueue.cpp:106
Rcpp
Definition: microsimulation.h:77
Rcpp::wrap
SEXP wrap(const std::vector< std::pair< T1, T2 > > v)
ssim::pqueueElementComparator::pqueueElementComparator
pqueueElementComparator(bool smaller=true)
Definition: pqueue.cpp:18
ssim::pqueue::clear
void clear()
Definition: pqueue.cpp:100
ssim::pqueue__new
RcppExport SEXP pqueue__new(SEXP _lower)
Definition: pqueue.cpp:128
ssim::pqueue::push
void push(double priority, SEXP event)
Definition: pqueue.cpp:46
ssim::pqueueElementComparator
Definition: pqueue.cpp:16
ssim::pqueueElement::event
SEXP event
Definition: pqueue.cpp:10
ssim::pqueue::_compare
pqueueElementComparator _compare
Definition: pqueue.cpp:28
ssim::pqueue::popElement
pqueueElement popElement()
Definition: pqueue.cpp:58
ssim::pqueue__push
RcppExport SEXP pqueue__push(SEXP _ptr, SEXP _priority, SEXP event)
Definition: pqueue.cpp:134
ssim::pqueueElementComparator::operator()
bool operator()(pqueueElement const &msg1, pqueueElement const &msg2) const
Definition: pqueue.cpp:19
ssim::pqueueElement::pqueueElement
pqueueElement(double priority, long order, bool active, SEXP event)
Definition: pqueue.cpp:11
ssim::pqueue::empty
bool empty()
Definition: pqueue.cpp:88
ssim
name space for the Siena simulator.
Definition: microsimulation.cc:8
ssim::pqueueElement::priority
double priority
Definition: pqueue.cpp:7
ssim::pqueue__empty
RcppExport SEXP pqueue__empty(SEXP _ptr)
Definition: pqueue.cpp:153
ssim::pqueue::_entryOrder
long _entryOrder
Definition: pqueue.cpp:29