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