ROSS
splay.c
Go to the documentation of this file.
1 /*
2  * queue-splay.c :- splay tree for priority queue
3  *
4  * THIS IMPLEMENTATION IS ADAPTED FROM THE DASSF
5  * C++ IMPLEMENTATION.
6  * THEIR COPYRIGHT IS ATTACHED BELOW
7  */
8 
9 /*
10  * Copyright (c) 1998-2002 Dartmouth College
11  *
12  * Permission is hereby granted, free of charge, to any individual or
13  * institution obtaining a copy of this software and associated
14  * documentation files (the "Software"), to use, copy, modify, and
15  * distribute without restriction, provided that this copyright and
16  * permission notice is maintained, intact, in all copies and supporting
17  * documentation.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22  * IN NO EVENT SHALL DARTMOUTH COLLEGE BE LIABLE FOR ANY CLAIM, DAMAGES
23  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
25  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  */
27 
28 #include <ross.h>
29 
30 #define UP(t) ((t)->up)
31 #define UPUP(t) ((t)->up->up)
32 #define LEFT(t) ((t)->next)
33 #define RIGHT(t) ((t)->prev)
34 #define KEY(t) ((t)->recv_ts)
35 
36 struct tw_pq
37 {
40  unsigned int nitems;
41  unsigned int max_size;
42 };
43 typedef tw_pq splay_tree;
44 
45 #define ROTATE_R(n,p,g) \
46  if((LEFT(p) = RIGHT(n))) UP(RIGHT(n)) = p; RIGHT(n) = p; \
47  UP(n) = g; UP(p) = n;
48 
49 #define ROTATE_L(n,p,g) \
50  if((RIGHT(p) = LEFT(n))) UP(LEFT(n)) = p; LEFT(n) = p; \
51  UP(n) = g; UP(p) = n;
52 
53 tw_pq *
55 {
56  splay_tree *st = (splay_tree *) tw_calloc(TW_LOC, "splay tree queue", sizeof(splay_tree), 1);
57 
58  st->root = 0;
59  st->least = 0;
60  st->nitems = 0;
61 
62  return st;
63 }
64 
65 static unsigned int tw_pq_compare_less_than( tw_event *n, tw_event *e )
66 {
67  if (TW_STIME_CMP(KEY(n), KEY(e)) < 0)
68  return 1;
69  else if (TW_STIME_CMP(KEY(n), KEY(e)) > 0)
70  return 0;
71  else
72  {
73  if( n->send_lp < e->send_lp )
74  return 1;
75  else if( n->send_lp > e->send_lp )
76  return 0;
77  else
78  {
79  if( n->dest_lp->gid < e->dest_lp->gid )
80  return 1;
81  else if(n->dest_lp->gid > e->dest_lp->gid )
82  return 0;
83  else
84  {
85  if( n->event_id < e->event_id )
86  return 1;
87  else if( n->event_id > e->event_id )
88  return 0;
89  else
90  tw_error(TW_LOC, "Found tie events at ts %lf when it's impossible!!\n", e->recv_ts);
91  }
92  }
93  }
94 }
95 
96 static void
97 splay(tw_event * node)
98 {
99  register tw_event *n = node, *g, *p;
100  register tw_event *x, *z;
101 
102  for (; (p = UP(n));)
103  {
104  if (n == LEFT(p))
105  {
106  if (!((g = UPUP(n))))
107  {
108  ROTATE_R(n, p, g);
109  } else if (p == LEFT(g))
110  {
111  if ((z = UP(g)))
112  {
113  if (g == LEFT(z))
114  LEFT(z) = n;
115  else
116  RIGHT(z) = n;
117  }
118  UP(n) = z;
119  if ((x = LEFT(p) = RIGHT(n)))
120  UP(x) = p;
121  RIGHT(n) = p;
122  UP(p) = n;
123  if ((x = LEFT(g) = RIGHT(p)))
124  UP(x) = g;
125  RIGHT(p) = g;
126  UP(g) = p;
127  } else
128  {
129  if ((z = UP(g)))
130  {
131  if (g == LEFT(z))
132  LEFT(z) = n;
133  else
134  RIGHT(z) = n;
135  }
136  UP(n) = z;
137  if ((x = LEFT(p) = RIGHT(n)))
138  RIGHT(n) = UP(x) = p;
139  else
140  RIGHT(n) = p;
141  if ((x = RIGHT(g) = LEFT(n)))
142  LEFT(n) = UP(x) = g;
143  else
144  LEFT(n) = g;
145  UP(g) = UP(p) = n;
146  }
147  } else
148  {
149  if (!((g = UPUP(n))))
150  {
151  ROTATE_L(n, p, g);
152  } else if (p == RIGHT(g))
153  {
154  if ((z = UP(g)))
155  {
156  if (g == RIGHT(z))
157  RIGHT(z) = n;
158  else
159  LEFT(z) = n;
160  }
161  UP(n) = z;
162  if ((x = RIGHT(p) = LEFT(n)))
163  UP(x) = p;
164  LEFT(n) = p;
165  UP(p) = n;
166  if ((x = RIGHT(g) = LEFT(p)))
167  UP(x) = g;
168  LEFT(p) = g;
169  UP(g) = p;
170  } else
171  {
172  if ((z = UP(g)))
173  {
174  if (g == RIGHT(z))
175  RIGHT(z) = n;
176  else
177  LEFT(z) = n;
178  }
179  UP(n) = z;
180  if ((x = RIGHT(p) = LEFT(n)))
181  LEFT(n) = UP(x) = p;
182  else
183  LEFT(n) = p;
184  if ((x = LEFT(g) = RIGHT(n)))
185  RIGHT(n) = UP(x) = g;
186  else
187  RIGHT(n) = g;
188  UP(g) = UP(p) = n;
189  }
190  }
191  }
192 }
193 
194 void
196 {
197  tw_event *n = st->root;
198 
199  st->nitems++;
200  if (st->nitems > st->max_size)
201  st->max_size = st->nitems;
202 
203  e->state.owner = TW_pe_pq;
204 
205  RIGHT(e) = LEFT(e) = 0;
206  if (n)
207  {
208  for (;;)
209  {
210 // if (KEY(n) <= KEY(e))
211  if( tw_pq_compare_less_than( n, e ) )
212  {
213  if (RIGHT(n))
214  n = RIGHT(n);
215  else
216  {
217  RIGHT(n) = e;
218  UP(e) = n;
219  break;
220  }
221  } else
222  {
223  if (LEFT(n))
224  n = LEFT(n);
225  else
226  {
227  if (st->least == n)
228  st->least = e;
229  LEFT(n) = e;
230  UP(e) = n;
231  break;
232  }
233  }
234  }
235  splay(e);
236  st->root = e;
237  } else
238  {
239  st->root = st->least = e;
240  UP(e) = 0;
241  }
242 }
243 
244 tw_event *
246 {
247  tw_event *r = st->least;
248  tw_event *tmp, *p;
249 
250  if (st->nitems == 0)
251  return (tw_event *) NULL;
252 
253  st->nitems--;
254 
255  if ((p = UP(st->least)))
256  {
257  if ((tmp = RIGHT(st->least)))
258  {
259  LEFT(p) = tmp;
260  UP(tmp) = p;
261  for (; LEFT(tmp); tmp = LEFT(tmp));
262  st->least = tmp;
263  } else
264  {
265  st->least = UP(st->least);
266  LEFT(st->least) = 0;
267  }
268  } else
269  {
270  if ((st->root = RIGHT(st->least)))
271  {
272  UP(st->root) = 0;
273  for (tmp = st->root; LEFT(tmp); tmp = LEFT(tmp));
274  st->least = tmp;
275  } else
276  st->least = 0;
277  }
278 
279  LEFT(r) = NULL;
280  RIGHT(r) = NULL;
281  UP(r) = NULL;
282  r->state.owner = 0;
283 
284  return r;
285 }
286 
287 void
289 {
290  tw_event *n, *p;
291  tw_event *tmp;
292 
293  r->state.owner = 0;
294 
295  if (r == st->least)
296  {
297  tw_pq_dequeue(st);
298  return;
299  }
300 
301  if (st->nitems == 0)
302  {
304  "tw_pq_delete_any: attempt to delete from empty queue \n");
305  }
306 
307  st->nitems--;
308 
309  if ((n = LEFT(r)))
310  {
311  if ((tmp = RIGHT(r)))
312  {
313  UP(n) = 0;
314  for (; RIGHT(n); n = RIGHT(n));
315  splay(n);
316  RIGHT(n) = tmp;
317  UP(tmp) = n;
318  }
319  UP(n) = UP(r);
320  } else if ((n = RIGHT(r)))
321  {
322  UP(n) = UP(r);
323  }
324 
325  if ((p = UP(r)))
326  {
327  if (r == LEFT(p))
328  LEFT(p) = n;
329  else
330  RIGHT(p) = n;
331  if (n)
332  {
333  splay(p);
334  st->root = p;
335  }
336  } else
337  st->root = n;
338 
339  LEFT(r) = NULL;
340  RIGHT(r) = NULL;
341  UP(r) = NULL;
342 }
343 
344 tw_stime
346 {
347  return ((pq->least ? pq->least->recv_ts : TW_STIME_MAX));
348 }
349 
350 unsigned int
352 {
353  return (st->nitems);
354 }
355 
356 unsigned int
358 {
359  return (pq->max_size);
360 }
#define TW_LOC
Definition: ross-extern.h:164
tw_lp * dest_lp
Destination LP ID.
Definition: ross-types.h:280
static void splay(tw_event *node)
Definition: splay.c:97
tw_stime tw_pq_minimum(splay_tree *pq)
Definition: splay.c:345
double tw_stime
Definition: ross.h:150
#define ROTATE_L(n, p, g)
Definition: splay.c:49
#define KEY(t)
Definition: splay.c:34
tw_eventid event_id
Unique id assigned by src_lp->pe if remote.
Definition: ross-types.h:264
void tw_error(const char *file, int line, const char *fmt,...) NORETURN
Definition: tw-util.c:74
tw_stime recv_ts
Actual time to be received.
Definition: ross-types.h:282
tw_pq * tw_pq_create(void)
Definition: splay.c:54
tw_pq splay_tree
Definition: splay.c:43
unsigned int tw_pq_get_size(splay_tree *st)
Definition: splay.c:351
tw_event * root
Definition: splay.c:38
Event Stucture.
Definition: ross-types.h:250
void tw_pq_delete_any(splay_tree *st, tw_event *r)
Definition: splay.c:288
tw_event * tw_pq_dequeue(splay_tree *st)
Definition: splay.c:245
tw_lpid gid
global LP id
Definition: ross-types.h:306
#define TW_STIME_CMP(x, y)
Definition: ross.h:154
unsigned int max_size
Definition: splay.c:41
#define UPUP(t)
Definition: splay.c:31
void tw_pq_enqueue(splay_tree *st, tw_event *e)
Definition: splay.c:195
tw_lpid send_lp
sending LP ID for data collection uses
Definition: ross-types.h:285
#define RIGHT(t)
Definition: splay.c:33
#define TW_STIME_MAX
Definition: ross.h:156
unsigned int tw_pq_max_size(splay_tree *pq)
Definition: splay.c:357
tw_event * least
Definition: splay.c:39
unsigned int nitems
Definition: splay.c:40
#define UP(t)
Definition: splay.c:30
struct tw_event::@0 state
In a tw_pe.pq.
Definition: ross-types.h:215
void * tw_calloc(const char *file, int line, const char *for_who, size_t e_sz, size_t n)
Definition: tw-util.c:203
#define LEFT(t)
Definition: splay.c:32
static unsigned int tw_pq_compare_less_than(tw_event *n, tw_event *e)
Definition: splay.c:65
#define ROTATE_R(n, p, g)
Definition: splay.c:45
Definition: splay.c:36
unsigned char owner
Owner of the next/prev pointers; see tw_event_owner.
Definition: ross-types.h:268