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 
27 TQItem::~TQItem() {}
28 
29 static void deleteitem(TQItem* i) { // only one, semantics changed
30  assert(i);
31  tpool_->hpfree(i);
32 }
33 
34 bool TQItem::check() {
35 #if DOCHECK
36 #endif
37  return true;
38 }
39 
40 static void prnt(const TQItem* b, int level) {
41  int i;
42  for (i = 0; i < level; ++i) {
43  Printf(" ");
44  }
45  Printf("%g %c %d Q=%p D=%p\n", b->t_, b->data_ ? 'x' : 'o', b->cnt_, b, b->data_);
46 }
47 
48 static void chk(TQItem* b, int level) {
49  if (!b->check()) {
50  hoc_execerror("chk failed", errmess_);
51  }
52 }
53 
55  if (!tpool_) {
56  tpool_ = new TQItemPool(1000);
57  }
58  sptree_ = new SPTREE;
59  spinit(sptree_);
60  least_ = 0;
61 
62 #if COLLECT_TQueue_STATISTICS
63  nmove = ninsert = nrem = nleast = nbal = ncmplxrem = 0;
65 #endif
66 }
67 
69  TQItem* q;
70  while ((q = spdeq(&sptree_->root)) != nil) {
71  deleteitem(q);
72  }
73  delete sptree_;
74 }
75 
76 void TQueue::print() {
77 #if FAST_LEAST
78  if (least_) {
79  prnt(least_, 0);
80  }
81 #endif
83 }
84 
85 void TQueue::forall_callback(void (*f)(const TQItem*, int)) {
86 #if FAST_LEAST
87  if (least_) {
88  f(least_, 0);
89  }
90 #endif
91  spscan(f, nil, sptree_);
92 }
93 
94 void TQueue::check(const char* mes) {}
95 
96 #if !FAST_LEAST
97 double TQueue::least_t() {
98  TQItem* b = least();
99  if (b) {
100  return b->t_;
101  } else {
102  return 1e15;
103  }
104 }
105 
107  STAT(nleast)
108  return sphead(sptree_);
109 }
110 #endif
111 
112 #if FAST_LEAST
113 TQItem* TQueue::second_least(double t) {
114  assert(least_);
115  TQItem* b = sphead(sptree_);
116  if (b && b->t_ == t) {
117  return b;
118  }
119  return 0;
120 }
121 #endif
122 
123 void TQueue::move_least(double tnew) {
124  TQItem* b = least();
125  if (b) {
126 #if FAST_LEAST
127  b->t_ = tnew;
128  TQItem* nl = sphead(sptree_);
129  if (nl) {
130  if (tnew > nl->t_) {
131  least_ = spdeq(&sptree_->root);
132  spenq(b, sptree_);
133  }
134  }
135 #else
136  move(b, tnew);
137 #endif
138  }
139 }
140 
141 void TQueue::move(TQItem* i, double tnew) {
142  STAT(nmove)
143 #if FAST_LEAST
144  if (i == least_) {
145  move_least(tnew);
146  } else if (tnew < least_->t_) {
147  spdelete(i, sptree_);
148  i->t_ = tnew;
149  spenq(least_, sptree_);
150  least_ = i;
151  } else
152 #endif
153  {
154  spdelete(i, sptree_);
155  i->t_ = tnew;
156  spenq(i, sptree_);
157  }
158 }
159 
160 void TQueue::statistics() {
161 #if COLLECT_TQueue_STATISTICS
162  Printf("insertions=%lu moves=%lu removals=%lu calls to least=%lu\n",
163  ninsert,
164  nmove,
165  nrem,
166  nleast);
167  Printf("calls to find=%lu\n", nfind);
168  Printf("comparisons=%lu\n", sptree_->enqcmps);
169 #else
170  Printf("Turn on COLLECT_TQueue_STATISTICS_ in tqueue.h\n");
171 #endif
172 }
173 
174 void TQueue::spike_stat(double* d) {
175 #if COLLECT_TQueue_STATISTICS
176  d[0] = ninsert;
177  d[1] = nmove;
178  d[2] = nrem;
179 #endif
180 }
181 
182 TQItem* TQueue::insert(double t, void* d) {
183  STAT(ninsert);
184  TQItem* i = tpool_->alloc();
185  i->data_ = d;
186  i->t_ = t;
187  i->cnt_ = 0;
188 #if FAST_LEAST
189  if (t < least_t()) {
190  if (least()) {
191  spenq(least(), sptree_);
192  }
193  least_ = i;
194  } else {
195  spenq(i, sptree_);
196  }
197 #else
198  spenq(i, sptree_);
199 #endif
200  return i;
201 }
202 
203 void TQueue::remove(TQItem* q) {
204  STAT(nrem);
205  if (q) {
206 #if FAST_LEAST
207  if (q == least_) {
208  if (sptree_->root) {
209  least_ = spdeq(&sptree_->root);
210  } else {
211  least_ = nil;
212  }
213  } else {
214  spdelete(q, sptree_);
215  }
216 #else
217  spdelete(q, sptree_);
218 #endif
219  tpool_->hpfree(q);
220  }
221 }
222 
223 TQItem* TQueue::find(double t) {
224  STAT(nfind)
225 #if FAST_LEAST
226  if (t == least_t()) {
227  return least();
228  }
229 #endif
230  TQItem* q;
231  q = splookup(t, sptree_);
232  return (q);
233 }
#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
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
unsigned long ninsert
Definition: bbtqueue.h:58
void print()
Definition: bbtqueue.cpp:109
unsigned long nrem
Definition: bbtqueue.h:58
unsigned long nfastmove
Definition: bbtqueue.h:59
SPTREE * sptree_
Definition: spt2queue.h:61
TQItem * find(double t)
Definition: bbtqueue.cpp:217
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
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: sptqueue.cpp:29
static void prnt(const TQItem *b, int level)
Definition: sptqueue.cpp:40
static void chk(TQItem *b, int level)
Definition: sptqueue.cpp:48
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 * spenq(SPBLK *n, SPTREE< SPBLK > *q)
Definition: sptree.h:169
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