7 extern int __ecereVMethodID_class_OnCompare;
8 extern int __ecereVMethodID_class_OnCopy;
11 enum AddSide : int { compare = 0, left = -1, right = 1};
13 public class AVLNode<class T> : IteratorPointer
17 thisclass parent, left, right;
22 property thisclass prev
30 if(parent && this == parent.right)
39 property thisclass next
43 thisclass right = this.right;
48 thisclass parent = this.parent;
49 if(parent && this == parent.left)
58 property thisclass minimum
60 get { while(left) this = left; return this; }
63 property thisclass maximum
65 get { while(right) this = right; return this; }
70 get { return 1 + (left ? left.count : 0) + (right ? right.count : 0); }
72 property int depthProp
76 int leftDepth = left ? (left.depthProp+1) : 0;
77 int rightDepth = right ? (right.depthProp+1) : 0;
78 return Max(leftDepth, rightDepth);
85 if (left) left.Free();
86 if (right) right.Free();
90 bool Add(Class Tclass, thisclass node, AddSide addSide)
93 int (* onCompare)(void *, void *, void *);
95 bool reference = false;
99 Tclass = class(uint64);
101 onCompare = (void *)Tclass._vTbl[__ecereVMethodID_class_OnCompare];
102 if((t == systemClass && !Tclass.byValueSystemClass) || t == bitClass || t == enumClass || t == unitClass || t == structClass)
105 offset = __ENDIAN_PAD((t == structClass) ? sizeof(void *) : Tclass.typeSize);
107 a = reference ? ((byte *)&node.key + offset) : ((byte *)(uintptr)node.key);
116 byte * b = reference ? ((byte *)&key + offset) : (byte *)(uintptr)key;
117 result = onCompare(Tclass, a, b);
146 for(n = this; n; n = n.parent)
148 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
149 if(newDepth == n.depth)
157 public thisclass Find(Class Tclass, const T key)
160 bool reference = false;
162 ClassType t = Tclass.type;
163 int (* onCompare)(void *, void *, void *) = (void *)Tclass._vTbl[__ecereVMethodID_class_OnCompare];
165 reference = (t == systemClass && !Tclass.byValueSystemClass) || t == bitClass || t == enumClass || t == unitClass;
166 offset = __ENDIAN_PAD(Tclass.typeSize);
167 a = reference ? ((byte *)&(uint64)key) + offset : (byte *)(uintptr)key;
171 offset = __ENDIAN_PAD(sizeof(void *));
176 // *** NEED COMPARISON OPERATOR SUPPORT HERE INVOKING OnCompare, AS WELL AS TYPE INFORMATION PASSED ***
177 byte * b = reference ? ((byte *)&this.key) + offset : (byte *)(uintptr)this.key;
178 int result = onCompare(Tclass, a, b);
189 thisclass FindEx(Class Tclass, const T key, AVLNode */*thisclass **/ addTo, AddSide * addSide)
192 bool reference = false;
194 ClassType t = Tclass.type;
195 int (* onCompare)(void *, void *, void *) = (void *)Tclass._vTbl[__ecereVMethodID_class_OnCompare];
197 reference = (t == systemClass && !Tclass.byValueSystemClass) || t == bitClass || t == enumClass || t == unitClass;
198 offset = __ENDIAN_PAD(Tclass.typeSize);
199 a = reference ? ((byte *)&(uint64)key) + offset : (byte *)(uintptr)key;
203 offset = __ENDIAN_PAD(sizeof(void *));
206 if(Tclass == class(uint))
208 uint ia = *(uint *)a;
211 uint ib = *(uint *)(reference ? ((byte *)&this.key) + offset : (byte *)(uintptr)this.key);
212 int result = ia > ib ? 1 : ia < ib ? -1 : 0;
215 thisclass node = result < 0 ? left : right;
218 if(addTo) *addTo = this;
219 if(addSide) *addSide = (AddSide)result;
231 byte * b = reference ? ((byte *)&this.key) + offset : (byte *)(uintptr)this.key;
232 int result = onCompare(Tclass, a, b);
235 thisclass node = result < 0 ? left : right;
238 if(addTo) *addTo = this;
239 if(addSide) *addSide = (AddSide)result;
250 thisclass FindAll(const T key)
252 AVLNode<T> result = null;
253 // *** FIND ALL COMPARES KEY FOR EQUALITY, NOT USING OnCompare ***
254 if(this.key == key) result = this;
255 if(!result && left) result = left.FindAll(key);
256 if(!result && right) result = right.FindAll(key);
260 void RemoveSwap(thisclass swap)
264 swap.left.parent = swap.parent;
265 if(swap == swap.parent.left)
266 swap.parent.left = swap.left;
267 else if(swap == swap.parent.right)
268 swap.parent.right = swap.left;
273 swap.right.parent = swap.parent;
274 if(swap == swap.parent.left)
275 swap.parent.left = swap.right;
276 else if(swap == swap.parent.right)
277 swap.parent.right = swap.right;
281 if(swap == swap.parent.left) swap.parent.left = null;
282 else if(swap == swap.parent.right) swap.parent.right = null;
286 for(n = swap.parent; n; n = n.parent)
288 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
289 if(newDepth == n.depth)
304 swap.parent = parent;
309 if(this == parent.left) parent.left = swap;
310 else if(this == parent.right) parent.right = swap;
314 thisclass RemoveSwapLeft()
316 thisclass swap = left ? left.maximum : right;
317 thisclass swapParent = null;
318 if(swap) { swapParent = swap.parent; RemoveSwap(swap); }
321 if(this == parent.left) parent.left = null;
322 else if(this == parent.right) parent.right = null;
326 for(n = swap ? swap : parent; n; n = n.parent)
328 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
329 if(newDepth == n.depth && n != swap)
334 if(swapParent && swapParent != this)
335 return swapParent.Rebalance();
337 return swap.Rebalance();
339 return parent.Rebalance();
344 thisclass RemoveSwapRight()
347 thisclass swap = right ? right.minimum : left;
348 thisclass swapParent = null;
349 if(swap) { swapParent = swap.parent; RemoveSwap(swap); }
352 if(this == parent.left) parent.left = null;
353 else if(this == parent.right) parent.right = null;
357 for(n = swap ? swap : parent; n; n = n.parent)
359 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
361 if(newDepth == n.depth && n != swap)
366 if(swapParent && swapParent != this)
367 result = swapParent.Rebalance();
369 result = swap.Rebalance();
371 result = parent.Rebalance();
377 property int balanceFactor
381 int leftDepth = left ? (left.depth+1) : 0;
382 int rightDepth = right ? (right.depth+1) : 0;
383 return rightDepth - leftDepth;
387 thisclass Rebalance()
391 int factor = balanceFactor;
394 if(left.balanceFactor == 1)
401 if(right.balanceFactor == -1)
413 void SingleRotateRight()
417 if(this == parent.left)
419 else if(this == parent.right)
422 left.parent = parent;
425 if(left) left.parent = this;
428 depth = Max(left ? (left.depth+1) : 0, right ? (right.depth+1) : 0);
429 parent.depth = Max(parent.left ? (parent.left.depth+1) : 0, parent.right ? (parent.right.depth+1) : 0);
432 for(n = parent.parent; n; n = n.parent)
434 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
435 if(newDepth == n.depth)
442 void SingleRotateLeft()
446 if(this == parent.right)
447 parent.right = right;
448 else if(this == parent.left)
451 right.parent = parent;
454 if(right) right.parent = this;
457 depth = Max(left ? (left.depth+1) : 0, right ? (right.depth+1) : 0);
458 parent.depth = Max(parent.left ? (parent.left.depth+1) : 0, parent.right ? (parent.right.depth+1) : 0);
461 for(n = parent.parent; n; n = n.parent)
463 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
464 if(newDepth == n.depth)
471 void DoubleRotateRight()
473 left.SingleRotateLeft();
477 void DoubleRotateLeft()
479 right.SingleRotateRight();
484 public class CustomAVLTree<class BT:AVLNode, class KT = uint64> : Container<BT, I = KT>
492 IteratorPointer GetFirst() { return (IteratorPointer) (root ? root.minimum : null); }
493 IteratorPointer GetLast() { return (IteratorPointer) (root ? root.maximum : null); }
494 IteratorPointer GetPrev(IteratorPointer node) { return ((BT)node).prev; }
495 IteratorPointer GetNext(IteratorPointer node) { return ((BT)node).next; }
496 BT GetData(IteratorPointer node) { return (BT)node; }
497 bool SetData(IteratorPointer node, BT data)
499 // Not supported for CustomAVLTree
503 IteratorPointer Add(BT node)
509 Class Tclass = class(BT).templateArgs[0].dataTypeClass;
512 Tclass = class(BT).templateArgs[0].dataTypeClass =
513 eSystem_FindClass(__thisModule.application, class(BT).templateArgs[0].dataTypeString);
515 if(root.Add(Tclass, node, 0))
516 root = node.Rebalance();
521 return (IteratorPointer)node;
524 private IteratorPointer AddEx(BT node, BT addNode, AddSide addSide)
530 Class Tclass = class(BT).templateArgs[0].dataTypeClass;
533 Tclass = class(BT).templateArgs[0].dataTypeClass =
534 eSystem_FindClass(__thisModule.application, class(BT).templateArgs[0].dataTypeString);
536 if(addNode.Add(Tclass, node, addSide))
537 root = node.Rebalance();
542 return (IteratorPointer)node;
545 void Remove(IteratorPointer node)
547 BT parent = ((BT)node).parent;
549 if(parent || root == (BT)node)
551 root = ((BT)node).RemoveSwapRight();
553 ((BT)node).parent = null;
557 void Delete(IteratorPointer _item)
560 // THIS SHOULDN'T BE CALLING THE VIRTUAL FUNCTION
561 CustomAVLTree::Remove(_item);
579 BT right = item.right;
585 BT parent = item.parent;
594 IteratorPointer Find(BT value)
596 return (IteratorPointer)value;
599 BT GetAtPosition(const KT pos, bool create, bool * justAdded)
601 // TODO: FindEx / AddEx & create nodes if create is true?
602 return root ? root.Find(class(KT), pos) : null;