CoreNEURON
tqueue.ipp
Go to the documentation of this file.
1 /*
2 # =============================================================================
3 # Copyright (c) 2016 - 2022 Blue Brain Project/EPFL
4 #
5 # See top-level LICENSE file for details.
6 # =============================================================================.
7 */
8 
9 #ifndef tqueue_ipp_
10 #define tqueue_ipp_
11 
12 #include <cstdio>
13 #include <cstdlib>
14 #include <cstring>
15 #include <cstdarg>
16 
19 
20 namespace coreneuron {
21 // splay tree + bin queue limited to fixed step method
22 // for event-sets or priority queues
23 // this starts from the sptqueue.cpp file and adds a bin queue
24 
25 /* Derived from David Brower's c translation of pascal code by
26 Douglas Jones.
27 */
28 /* The original c code is included from this file but note that instead
29 of struct _spblk, we are really using TQItem
30 */
31 
32 template <container C>
34  nshift_ = 0;
35  sptree_ = new SPTREE;
36  spinit(sptree_);
37  binq_ = new BinQ;
38  least_ = 0;
39 }
40 
41 template <container C>
43  SPBLK *q, *q2;
44  /// Clear the binq
45  for (q = binq_->first(); q; q = q2) {
46  q2 = binq_->next(q);
47  binq_->remove(q);
48  delete q;
49  }
50  delete binq_;
51 
52  if (least_) {
53  delete least_;
54  least_ = nullptr;
55  }
56 
57  /// Clear the splay tree
58  while ((q = spdeq(&sptree_->root)) != nullptr) {
59  delete q;
60  }
61  delete sptree_;
62 
63  /// Clear the priority queue
64  while (pq_que_.size()) {
65  delete pq_que_.top().second;
66  pq_que_.pop();
67  }
68 }
69 
70 template <container C>
72  TQItem* i = new TQItem;
73  i->data_ = d;
74  i->t_ = td;
75  binq_->enqueue(td, i);
76  return i;
77 }
78 
79 /// Splay tree priority queue implementation
80 template <>
81 inline void TQueue<spltree>::move_least_nolock(double tnew) {
82  TQItem* b = least();
83  if (b) {
84  b->t_ = tnew;
85  TQItem* nl;
86  nl = sphead(sptree_);
87  if (nl && (tnew > nl->t_)) {
88  least_ = spdeq(&sptree_->root);
89  spenq(b, sptree_);
90  }
91  }
92 }
93 
94 /// STL priority queue implementation
95 template <>
96 inline void TQueue<pq_que>::move_least_nolock(double tnew) {
97  TQItem* b = least();
98  if (b) {
99  b->t_ = tnew;
100  TQItem* nl;
101  nl = pq_que_.top().second;
102  if (nl && (tnew > nl->t_)) {
103  least_ = nl;
104  pq_que_.pop();
105  pq_que_.push(make_TQPair(b));
106  }
107  }
108 }
109 
110 /// Splay tree priority queue implementation
111 template <>
112 inline void TQueue<spltree>::move(TQItem* i, double tnew) {
113  if (i == least_) {
114  move_least_nolock(tnew);
115  } else if (tnew < least_->t_) {
116  spdelete(i, sptree_);
117  i->t_ = tnew;
118  spenq(least_, sptree_);
119  least_ = i;
120  } else {
121  spdelete(i, sptree_);
122  i->t_ = tnew;
123  spenq(i, sptree_);
124  }
125 }
126 
127 /// STL priority queue implementation
128 template <>
129 inline void TQueue<pq_que>::move(TQItem* i, double tnew) {
130  if (i == least_) {
131  move_least_nolock(tnew);
132  } else if (tnew < least_->t_) {
133  TQItem* qmove = new TQItem;
134  qmove->data_ = i->data_;
135  qmove->t_ = tnew;
136  qmove->cnt_ = i->cnt_;
137  i->t_ = -1.;
138  pq_que_.push(make_TQPair(least_));
139  least_ = qmove;
140  } else {
141  TQItem* qmove = new TQItem;
142  qmove->data_ = i->data_;
143  qmove->t_ = tnew;
144  qmove->cnt_ = i->cnt_;
145  i->t_ = -1.;
146  pq_que_.push(make_TQPair(qmove));
147  }
148 }
149 
150 /// Splay tree priority queue implementation
151 template <>
153  TQItem* i = new TQItem;
154  i->data_ = d;
155  i->t_ = tt;
156  i->cnt_ = -1;
157  if (tt < least_t_nolock()) {
158  if (least_) {
159  /// Probably storing both time and event which has the time is redundant, but the event
160  /// is then returned
161  /// to the upper level call stack function. If we were to eliminate i->t_ and i->cnt_
162  /// fields,
163  /// we need to make sure we are not braking anything.
164  spenq(least_, sptree_);
165  }
166  least_ = i;
167  } else {
168  spenq(i, sptree_);
169  }
170  return i;
171 }
172 
173 /// STL priority queue implementation
174 template <>
176  TQItem* i = new TQItem;
177  i->data_ = d;
178  i->t_ = tt;
179  i->cnt_ = -1;
180  if (tt < least_t_nolock()) {
181  if (least_) {
182  /// Probably storing both time and event which has the time is redundant, but the event
183  /// is then returned
184  /// to the upper level call stack function. If we were to eliminate i->t_ and i->cnt_
185  /// fields,
186  /// we need to make sure we are not braking anything.
187  pq_que_.push(make_TQPair(least_));
188  }
189  least_ = i;
190  } else {
191  pq_que_.push(make_TQPair(i));
192  }
193  return i;
194 }
195 
196 /// Splay tree priority queue implementation
197 template <>
199  if (q) {
200  if (q == least_) {
201  if (sptree_->root) {
202  least_ = spdeq(&sptree_->root);
203  } else {
204  least_ = nullptr;
205  }
206  } else {
207  spdelete(q, sptree_);
208  }
209  delete q;
210  }
211 }
212 
213 /// STL priority queue implementation
214 template <>
216  if (q) {
217  if (q == least_) {
218  if (pq_que_.size()) {
219  least_ = pq_que_.top().second;
220  pq_que_.pop();
221  } else {
222  least_ = nullptr;
223  }
224  } else {
225  q->t_ = -1.;
226  }
227  }
228 }
229 
230 /// Splay tree priority queue implementation
231 template <>
232 inline TQItem* TQueue<spltree>::atomic_dq(double tt) {
233  TQItem* q = nullptr;
234  if (least_ && least_->t_ <= tt) {
235  q = least_;
236  if (sptree_->root) {
237  least_ = spdeq(&sptree_->root);
238  } else {
239  least_ = nullptr;
240  }
241  }
242  return q;
243 }
244 
245 /// STL priority queue implementation
246 template <>
247 inline TQItem* TQueue<pq_que>::atomic_dq(double tt) {
248  TQItem* q = nullptr;
249  if (least_ && least_->t_ <= tt) {
250  q = least_;
251  // int qsize = pq_que_.size();
252  // printf("map size: %d\n", msize);
253  /// This while loop is to delete events whose times have been moved with the ::move
254  /// function,
255  /// but in fact events were left in the queue since the only function available is pop
256  while (pq_que_.size() && pq_que_.top().second->t_ < 0.) {
257  delete pq_que_.top().second;
258  pq_que_.pop();
259  }
260  if (pq_que_.size()) {
261  least_ = pq_que_.top().second;
262  pq_que_.pop();
263  } else {
264  least_ = nullptr;
265  }
266  }
267  return q;
268 }
269 } // namespace coreneuron
270 #endif
coreneuron::TQueue::atomic_dq
TQItem * atomic_dq(double til)
coreneuron::TQueue::enqueue_bin
TQItem * enqueue_bin(double t, DiscreteEvent *data)
Definition: tqueue.ipp:71
coreneuron::TQItem
Definition: tqueue.hpp:69
tqueue.hpp
coreneuron::TQItem::t_
double t_
Definition: tqueue.hpp:72
coreneuron
THIS FILE IS AUTO GENERATED DONT MODIFY IT.
Definition: corenrn_parameters.cpp:12
coreneuron::TQueue::remove
void remove(TQItem *)
coreneuron::i
int i
Definition: cellorder.cpp:485
coreneuron::TQueue::insert
TQItem * insert(double t, DiscreteEvent *data)
coreneuron::SPTREE
Definition: tqueue.hpp:47
coreneuron::spenq
SPBLK * spenq(SPBLK *n, SPTREE *q)
Definition: tqueue.cpp:197
coreneuron::sphead
SPBLK * sphead(SPTREE *q)
Definition: tqueue.cpp:503
coreneuron::DiscreteEvent
Definition: netcon.hpp:33
coreneuron::spdelete
void spdelete(SPBLK *n, SPTREE *q)
Definition: tqueue.cpp:532
coreneuron::spdeq
SPBLK * spdeq(SPBLK **np)
Definition: tqueue.cpp:325
coreneuron::TQItem::cnt_
int cnt_
Definition: tqueue.hpp:76
coreneuron::BinQ
Definition: tqueue.hpp:88
coreneuron::TQueue::~TQueue
~TQueue()
Definition: tqueue.ipp:42
coreneuron::spinit
void spinit(SPTREE *q)
Definition: tqueue.cpp:180
coreneuron::TQueue::move
void move(TQItem *, double tnew)
SPBLK
#define SPBLK
Definition: tqueue.hpp:40
coreneuron::TQueue::move_least_nolock
void move_least_nolock(double tnew)
multicore.hpp
coreneuron::TQItem::data_
DiscreteEvent * data_
Definition: tqueue.hpp:71
coreneuron::TQueue::TQueue
TQueue()
Definition: tqueue.ipp:33