NEURON
sptqueue.cpp
Go to the documentation of this file.
1 // splay tree for event-sets or priority queues
2 /* Derived from David Brower's c translation of pascal code by
3 Douglas Jones.
4 */
5 /* The original c code is included from this file but note that instead
6 of struct _spblk, we are really using TQItem
7 */
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdarg.h>
13 
14 #define leftlink left_
15 #define rightlink right_
16 #define uplink parent_
17 #define cnt cnt_
18 #define key t_
19 #include <sptree.h>
20 
22  left_ = 0;
23  right_ = 0;
24  parent_ = 0;
25 }
26 
28 }
29 
30 static void deleteitem(TQItem* i) { // only one, semantics changed
31  assert(i);
32  tpool_->hpfree(i);
33 }
34 
35 bool TQItem::check() {
36 #if DOCHECK
37 #endif
38  return true;
39 }
40 
41 static void prnt(const TQItem* b, int level) {
42  int i;
43  for (i=0; i < level; ++i) {
44  Printf(" ");
45  }
46  Printf("%g %c %d Q=%p D=%p\n", b->t_, b->data_?'x':'o', b->cnt_, b, b->data_);
47 }
48 
49 static void chk(TQItem* b, int level) {
50  if (!b->check()) {
51  hoc_execerror("chk failed", errmess_);
52  }
53 }
54 
56  if (!tpool_) {
57  tpool_ = new TQItemPool(1000);
58  }
59  sptree_ = new SPTREE;
60  spinit(sptree_);
61  least_ = 0;
62 
63 #if COLLECT_TQueue_STATISTICS
64  nmove = ninsert = nrem = nleast = nbal = ncmplxrem = 0;
65  nfastmove = ncompare = nleastsrch = nfind = nfindsrch = 0;
66 #endif
67 }
68 
70  TQItem* q;
71  while((q = spdeq(&sptree_->root)) != nil) {
72  deleteitem(q);
73  }
74  delete sptree_;
75 }
76 
77 void TQueue::print() {
78 #if FAST_LEAST
79  if (least_) {
80  prnt(least_, 0);
81  }
82 #endif
83  spscan(prnt, nil, sptree_);
84 }
85 
86 void TQueue::forall_callback(void(*f)(const TQItem*, int)) {
87 #if FAST_LEAST
88  if (least_) {
89  f(least_, 0);
90  }
91 #endif
92  spscan(f, nil, sptree_);
93 }
94 
95 void TQueue::check(const char* mes) {
96 }
97 
98 #if !FAST_LEAST
99 double TQueue::least_t() {
100  TQItem* b = least();
101  if (b) {
102  return b->t_;
103  }else{
104  return 1e15;
105  }
106 }
107 
109  STAT(nleast)
110  return sphead(sptree_);
111 }
112 #endif
113 
114 #if FAST_LEAST
115 TQItem* TQueue::second_least(double t) {
116  assert(least_);
117  TQItem* b = sphead(sptree_);
118  if (b && b->t_ == t) {
119  return b;
120  }
121  return 0;
122 }
123 #endif
124 
125 void TQueue::move_least(double tnew) {
126  TQItem* b = least();
127  if (b) {
128 #if FAST_LEAST
129  b->t_ = tnew;
130  TQItem* nl = sphead(sptree_);
131  if (nl) {
132  if (tnew > nl->t_) {
133  least_ = spdeq(&sptree_->root);
134  spenq(b, sptree_);
135  }
136  }
137 #else
138  move(b, tnew);
139 #endif
140  }
141 }
142 
143 void TQueue::move(TQItem* i, double tnew) {
144  STAT(nmove)
145 #if FAST_LEAST
146  if (i == least_) {
147  move_least(tnew);
148  }else if (tnew < least_->t_) {
149  spdelete(i, sptree_);
150  i->t_ = tnew;
151  spenq(least_, sptree_);
152  least_ = i;
153  }else
154 #endif
155  {
156  spdelete(i, sptree_);
157  i->t_ = tnew;
158  spenq(i, sptree_);
159  }
160 }
161 
162 void TQueue::statistics() {
163 #if COLLECT_TQueue_STATISTICS
164  Printf("insertions=%lu moves=%lu removals=%lu calls to least=%lu\n",
165  ninsert, nmove, nrem, nleast);
166  Printf("calls to find=%lu\n",
167  nfind);
168  Printf("comparisons=%lu\n",
169  sptree_->enqcmps);
170 #else
171  Printf("Turn on COLLECT_TQueue_STATISTICS_ in tqueue.h\n");
172 #endif
173 }
174 
175 void TQueue::spike_stat(double* d) {
176 #if COLLECT_TQueue_STATISTICS
177  d[0] = ninsert;
178  d[1] = nmove;
179  d[2] = nrem;
180 #endif
181 }
182 
183 TQItem* TQueue::insert(double t, void* d) {
184  STAT(ninsert);
185  TQItem* i = tpool_->alloc();
186  i->data_ = d;
187  i->t_ = t;
188  i->cnt_ = 0;
189 #if FAST_LEAST
190  if (t < least_t()) {
191  if (least()) {
192  spenq(least(), sptree_);
193  }
194  least_ = i;
195  }else{
196  spenq(i, sptree_);
197  }
198 #else
199  spenq(i, sptree_);
200 #endif
201  return i;
202 }
203 
204 void TQueue::remove(TQItem* q) {
205  STAT(nrem);
206  if (q) {
207 #if FAST_LEAST
208  if (q == least_) {
209  if (sptree_->root) {
210  least_ = spdeq(&sptree_->root);
211  }else{
212  least_ = nil;
213  }
214  }else{
215  spdelete(q, sptree_);
216  }
217 #else
218  spdelete(q, sptree_);
219 #endif
220  tpool_->hpfree(q);
221  }
222 }
223 
224 TQItem* TQueue::find(double t) {
225  STAT(nfind)
226 #if FAST_LEAST
227  if (t == least_t()) {
228  return least();
229  }
230 #endif
231  TQItem* q;
232  q = splookup(t, sptree_);
233  return(q);
234 }
static void prnt(const TQItem *b, int level)
Definition: sptqueue.cpp:41
#define Printf
Definition: model.h:252
#define assert(ex)
Definition: hocassrt.h:26
SPBLK * spdeq(SPBLK **np)
Definition: sptree.h:320
void spdelete(SPBLK *n, SPTREE< SPBLK > *q)
Definition: sptree.h:772
void print()
Definition: bbtqueue.cpp:114
TQItem * find(double t)
Definition: bbtqueue.cpp:220
TQItem()
Definition: bbtqueue.cpp:3
static void deleteitem(TQItem *i)
Definition: sptqueue.cpp:30
SPBLK * sphead(SPTREE< SPBLK > *q)
Definition: sptree.h:731
double t_
Definition: bbtqueue.h:18
Definition: bbtqueue.h:6
void spinit(SPTREE< SPBLK > *q)
Definition: sptree.h:139
bool check()
Definition: bbtqueue.cpp:30
void statistics()
Definition: bbtqueue.cpp:474
void forall_callback(void(*)(const TQItem *, int))
Definition: bbtqueue.cpp:120
double least_t()
Definition: bbtqueue.cpp:136
TQItem * least()
Definition: bbtqueue.cpp:145
virtual ~TQItem()
Definition: bbtqueue.cpp:9
void spike_stat(double *)
Definition: spt2queue.cpp:170
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
TQItem * insert(double t, void *data_)
Definition: bbtqueue.cpp:391
#define nil
Definition: enter-scope.h:36
virtual void move(const Event &e)
Definition: ocinput.h:19
TQItem * left_
Definition: bbtqueue.h:19
static void chk(TQItem *b, int level)
Definition: sptqueue.cpp:49
Definition: sptbinq.h:17
SPBLK * splookup(double key, SPTREE< SPBLK > *q)
Definition: sptree.h:975
void move_least(double tnew)
Definition: bbtqueue.cpp:181
void spscan(void(*f)(const SPBLK *, int), SPBLK *n, SPTREE< SPBLK > *q)
Definition: sptree.h:1102
static const char * errmess_
Definition: tqueue.cpp:20
TQItem * parent_
Definition: bbtqueue.h:21
virtual ~TQueue()
Definition: bbtqueue.cpp:107
#define i
Definition: md1redef.h:12
#define STAT
Definition: model.h:117
static double least(void *v)
Definition: tqueue.cpp:33
SPBLK * spenq(SPBLK *n, SPTREE< SPBLK > *q)
Definition: sptree.h:176
void * data_
Definition: bbtqueue.h:17
void check(const char *errmess)
Definition: bbtqueue.cpp:126
void remove(TQItem *)
Definition: bbtqueue.cpp:239
double t
Definition: init.cpp:123
size_t q
int cnt_
Definition: spt2queue.h:23
TQueue()
Definition: bbtqueue.cpp:94
void move(TQItem *, double tnew)
Definition: bbtqueue.cpp:188
TQItem * right_
Definition: bbtqueue.h:20