gwnavruntime/kernel/SF_SplayTree.h Source File

SF_SplayTree.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 /**************************************************************************
8 
9 Filename : KY_SplayTree.h
10 Content : Template implementation for a simple splay tree.
11 Created : 2009
12 Authors : MaximShemanarev
13 
14 **************************************************************************/
15 
16 #ifndef INC_KY_Kernel_SplayTree_H
17 #define INC_KY_Kernel_SplayTree_H
18 
20 
21 namespace Kaim {
22 
23 // Intrusive splay tree adopted from heap manager written by Pradeep Chulliyan
24 // chulliyan@hotmail.com (public domain license).
25 //
26 // Good performance for a splay tree depends on the fact that it is
27 // self-balancing, and indeed self optimizing, in that frequently
28 // accessed nodes will move nearer to the root where they can be
29 // accessed more quickly. This is an advantage for nearly all practical
30 // applications, and is particularly useful for implementing caches and
31 // garbage collection algorithms; however it is important to note that
32 // for uniform access, a splay tree's performance will be considerably
33 // (although not asymptotically) worse than a somewhat balanced simple
34 // binary search tree.
35 //
36 // The tree requires the following accessor (as an example):
37 //
38 // struct TreeNodeAccessor
39 // {
40 // static bool Less(const TreeNode& a, const TreeNode& b) { return a.Key < b.Key; }
41 // static bool Equal(const TreeNode& a, const TreeNode& b) { return a.Key == b.Key; }
42 //
43 // static TreeNode* GetChild ( TreeNode* n, UPInt i) { return n->Child[i]; }
44 // static const TreeNode* GetChild (const TreeNode* n, UPInt i) { return n->Child[i]; }
45 // static TreeNode** GetChildPtr( TreeNode* n, UPInt i) { return &n->Child[i]; }
46 //
47 // static void SetChild (TreeNode* n, UPInt i, TreeNode* c) { n->Child[i] = c; }
48 //
49 // static void ClearLinks(TreeNode* n) { n->Child[0] = n->Child[1] = 0; }
50 // };
51 //
52 // Operations on the tree:
53 //
54 // static T* Splay(T** root, const T& key);
55 // void Insert(T* n, T* t);
56 // T* Insert(T* n);
57 // void Remove(T* t, bool splayed);
58 // const T* FindEqual(const T& key) const;
59 // const T* FindGrEq (const T& key) const;
60 // const T* FindLeEq (const T& key) const;
61 //
62 //------------------------------------------------------------------------
63 template<class T, class Accessor> class SplayTree
64 {
65 
66 public:
67  SplayTree() : Root(0) {}
68 
69  void Clear() { Root = 0; }
70 
71  // Adjust the tree (splay the heap) to get the best matching node
72  // at the top of the heap.
73  //--------------------------------------------------------------------
74  static T* Splay(T** root, const T& key)
75  {
76  T* t = *root;
77  if (t == 0)
78  return 0;
79 
80  T n;
81  Accessor::ClearLinks(&n);
82  T* l = &n;
83  T* r = l;
84  T* y = 0;
85 
86  for (;;)
87  {
88  if (Accessor::Less(key, *t))
89  {
90  if (Accessor::GetChild(t, 0) == 0)
91  break;
92 
93  // Rotate right
94  //------------------
95  if (Accessor::Less(key, *Accessor::GetChild(t, 0)))
96  {
97  y = Accessor::GetChild(t, 0);
98  Accessor::SetChild(t, 0, Accessor::GetChild(y, 1));
99  Accessor::SetChild(y, 1, t);
100  t = y;
101 
102  if (Accessor::GetChild(t, 0) == 0)
103  break;
104  }
105 
106  // Link right
107  //------------------
108  Accessor::SetChild(r, 0, t);
109  r = t;
110  t = Accessor::GetChild(t, 0);
111  }
112  else if (Accessor::Less(*t, key))
113  {
114  if (Accessor::GetChild(t, 1) == 0)
115  break;
116 
117  // Rotate left
118  //------------------
119  if (Accessor::Less(*Accessor::GetChild(t, 1), key))
120  {
121  y = Accessor::GetChild(t, 1);
122  Accessor::SetChild(t, 1, Accessor::GetChild(y, 0));
123  Accessor::SetChild(y, 0, t);
124  t = y;
125 
126  if (Accessor::GetChild(t, 1) == 0)
127  break;
128  }
129 
130  // Link left
131  //------------------
132  Accessor::SetChild(l, 1, t);
133  l = t;
134  t = Accessor::GetChild(t, 1);
135  }
136  else
137  break;
138  }
139 
140  // Re-create the node
141  //------------------
142  Accessor::SetChild(l, 1, 0);
143  Accessor::SetChild(r, 0, 0);
144  Accessor::SetChild(l, 1, Accessor::GetChild(t, 0));
145  Accessor::SetChild(r, 0, Accessor::GetChild(t, 1));
146  Accessor::SetChild(t, 0, Accessor::GetChild(&n, 1));
147  Accessor::SetChild(t, 1, Accessor::GetChild(&n, 0));
148 
149  return *root = t;
150  }
151 
152 
153  // Link node 'n' to node 't' and move 'n' to the root.
154  //--------------------------------------------------------------------
155  void Insert(T* n, T* t)
156  {
157  if (t == 0)
158  {
159  Accessor::ClearLinks(n);
160  }
161  else if (Accessor::Less(*n, *t))
162  {
163  Accessor::SetChild(n, 0, Accessor::GetChild(t, 0));
164  Accessor::SetChild(n, 1, t);
165  Accessor::SetChild(t, 0, 0);
166  }
167  else
168  {
169  Accessor::SetChild(n, 1, Accessor::GetChild(t, 1));
170  Accessor::SetChild(n, 0, t);
171  Accessor::SetChild(t, 1, 0);
172  }
173  Root = n;
174  }
175 
176 
177  // Insert node into the tree starting from the Root node.
178  // Returns NULL on success, or the pointer to the node if the node
179  // with the same key already exists in the tree.
180  //--------------------------------------------------------------------
181  T* Insert(T* n)
182  {
183  //Insert(n, Splay(&Root, *n));
184  T* t = Splay(&Root, *n);
185  if (t && Accessor::Equal(*t, *n))
186  {
187  return t;
188  }
189  Insert(n, t);
190  return 0;
191  }
192 
193 
194  // Remove a node from the tree. If 'splayed' is true, then the tree
195  // is assumed to be splayed with the correct key.
196  //--------------------------------------------------------------------
197  void Remove(T* t, bool splayed = false)
198  {
199  T* x = Root;
200 
201  if (splayed)
202  x = t;
203  else
204  x = Splay(&x, *t);
205 
206  if (Accessor::Equal(*x, *t))
207  {
208  if (Accessor::GetChild(t, 0) == 0)
209  {
210  x = Accessor::GetChild(t, 1);
211  }
212  else
213  {
214  x = Splay(Accessor::GetChildPtr(t, 0), *t);
215  Accessor::SetChild(x, 1, Accessor::GetChild(t, 1));
216  }
217  }
218  Root = x;
219  Accessor::ClearLinks(t);
220  }
221 
222 
223  //--------------------------------------------------------------------
224  const T* FindEqual(const T& key) const
225  {
226  const T* node = Root;
227  while(node && !Accessor::Equal(*node, key))
228  {
229  node = Accessor::GetChild(node, Accessor::Less(*node, key));
230  }
231  return node;
232  }
233 
234 
235  //--------------------------------------------------------------------
236  const T* FindGrEq(const T& key) const
237  {
238  const T* node = Root;
239  const T* best = 0;
240  while (node)
241  {
242  if (Accessor::Less(*node, key))
243  {
244  node = Accessor::GetChild(node, 1);
245  }
246  else
247  {
248  best = node;
249  node = Accessor::GetChild(node, 0);
250  }
251  }
252  return best;
253  }
254 
255 
256  //--------------------------------------------------------------------
257  const T* FindLeEq(const T& key) const
258  {
259  const T* node = Root;
260  const T* best = 0;
261  while (node)
262  {
263  if (Accessor::Less(key, *node))
264  {
265  node = Accessor::GetChild(node, 0);
266  }
267  else
268  {
269  best = node;
270  node = Accessor::GetChild(node, 1);
271  }
272  }
273  return best;
274  }
275 
276 
277  T* Root;
278 };
279 
280 
281 
282 //------------------------------------------------------------------------
283 template<class T, class Accessor> class SplayTreeMulti
284 {
285 public:
286 
287  //--------------------------------------------------------------------
288  void Insert(T* n)
289  {
290  T* t = Tree.Splay(&Tree.Root, *n);
291 
292  if (t == 0 || !Accessor::Equal(*t, *n))
293  {
294  // Insert into the tree
295  //--------------------
296  n->pPrev = n->pNext = 0;
297  Tree.Insert(n, t);
298  }
299  else
300  {
301  // Link to the existing tree node
302  //--------------------
303  n->pNext = t->pNext;
304  n->pPrev = t;
305  t->pNext = n;
306  if (n->pNext)
307  n->pNext->pPrev = n;
308  }
309  }
310 
311  //--------------------------------------------------------------------
312  void Remove(T* n, bool splayed = false)
313  {
314  // If the node 'n' is not the first node in the linked list,
315  // simply de-link 'n' from the linked list.
316  //-------------------
317  if (n->pPrev)
318  {
319  n->pPrev->pNext = n->pNext;
320  if (n->pNext)
321  n->pNext->pPrev = n->pPrev;
322  }
323  else
324  {
325  // The node 'n' is the first node of the linked list.
326  // Remove it from the tree and add the next node from the linked
327  // list to the tree.
328  //--------------------
329  if (n->pNext)
330  {
331  T* t = (T*)n->pNext;
332  T* x = Tree.Root;
333 
334  if (splayed)
335  x = n;
336  else
337  x = Tree.Splay(&x, *n);
338 
339  if (x && Accessor::Equal(*x, *n))
340  {
341  Accessor::SetChild(t, 0, Accessor::GetChild(x, 0));
342  Accessor::SetChild(t, 1, Accessor::GetChild(x, 1));
343  t->pPrev = 0;
344  Tree.Root = (T*)n->pNext;
345  }
346  }
347  else
348  {
349  Tree.Remove(n, false);
350  }
351  }
352  }
353 
354  //--------------------------------------------------------------------
355  T* PullBestGrEq(const T& key)
356  {
357  T* node = Tree.Splay(&Tree.Root, key);
358  bool splayed = true;
359 
360  if (node && Accessor::Less(*node, key))
361  {
362  splayed = false;
363  if ((node = Accessor::GetChild(node, 1)) != 0)
364  {
365  while (Accessor::GetChild(node, 0))
366  node = (T*)Accessor::GetChild(node, 0);
367  }
368  }
369 
370  if (node)
371  {
372  // Take the next node to reduce splaying
373  // the tree in RemoveMulti().
374  //------------------------
375  if (node->pNext)
376  node = (T*)node->pNext;
377 
378  Remove(node, splayed);
379  }
380  return node;
381 
382  }
383 
384  //--------------------------------------------------------------------
385  T* PullBestLeEq(UPInt key)
386  {
387  // TO DO
388  return 0;
389  }
390 
391  SplayTree<T, Accessor> Tree;
392 };
393 
394 
395 } // Scaleform
396 
397 #endif
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17