Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
RBTree.cs
Go to the documentation of this file.
4
5namespace System.Data;
6
7internal abstract class RBTree<K> : IEnumerable
8{
9 private enum NodeColor
10 {
11 red,
12 black
13 }
14
15 private struct Node
16 {
17 internal int _selfId;
18
19 internal int _leftId;
20
21 internal int _rightId;
22
23 internal int _parentId;
24
25 internal int _nextId;
26
27 internal int _subTreeSize;
28
29 internal K _keyOfNode;
30
32 }
33
34 private readonly struct NodePath
35 {
36 internal readonly int _nodeID;
37
38 internal readonly int _mainTreeNodeID;
39
40 internal NodePath(int nodeID, int mainTreeNodeID)
41 {
44 }
45 }
46
47 private sealed class TreePage
48 {
49 internal readonly Node[] _slots;
50
51 internal readonly int[] _slotMap;
52
53 private int _inUseCount;
54
55 private int _pageId;
56
57 private int _nextFreeSlotLine;
58
59 internal int InUseCount
60 {
61 get
62 {
63 return _inUseCount;
64 }
65 set
66 {
68 }
69 }
70
71 internal int PageId
72 {
73 get
74 {
75 return _pageId;
76 }
77 set
78 {
79 _pageId = value;
80 }
81 }
82
83 internal TreePage(int size)
84 {
85 if (size > 65536)
86 {
88 }
89 _slots = new Node[size];
90 _slotMap = new int[(size + 32 - 1) / 32];
91 }
92
93 internal int AllocSlot(RBTree<K> tree)
94 {
95 int num = 0;
96 int num2 = 0;
97 int num3 = -1;
98 if (_inUseCount < _slots.Length)
99 {
100 for (num = _nextFreeSlotLine; num < _slotMap.Length; num++)
101 {
102 if ((uint)_slotMap[num] < uint.MaxValue)
103 {
104 num3 = 0;
105 num2 = ~_slotMap[num] & (_slotMap[num] + 1);
106 _slotMap[num] |= num2;
107 _inUseCount++;
108 if (_inUseCount == _slots.Length)
109 {
110 tree.MarkPageFull(this);
111 }
112 tree._inUseNodeCount++;
113 num3 = RBTree<K>.GetIntValueFromBitMap((uint)num2);
114 _nextFreeSlotLine = num;
115 num3 = num * 32 + num3;
116 break;
117 }
118 }
119 if (num3 == -1 && _nextFreeSlotLine != 0)
120 {
123 }
124 }
125 return num3;
126 }
127 }
128
130 {
131 private readonly RBTree<K> _tree;
132
133 private readonly int _version;
134
135 private int _index;
136
137 private int _mainTreeNodeId;
138
139 private K _current;
140
141 public K Current => _current;
142
143 object IEnumerator.Current => Current;
144
146 {
147 _tree = tree;
149 _index = 0;
150 _mainTreeNodeId = tree.root;
151 _current = default(K);
152 }
153
154 internal RBTreeEnumerator(RBTree<K> tree, int position)
155 {
156 _tree = tree;
158 if (position == 0)
159 {
160 _index = 0;
161 _mainTreeNodeId = tree.root;
162 }
163 else
164 {
165 _index = tree.ComputeNodeByIndex(position - 1, out _mainTreeNodeId);
166 if (_index == 0)
167 {
168 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.IndexOutOFRangeinGetNodeByIndex);
169 }
170 }
171 _current = default(K);
172 }
173
174 public void Dispose()
175 {
176 }
177
178 public bool MoveNext()
179 {
180 if (_version != _tree._version)
181 {
183 }
184 bool result = _tree.Successor(ref _index, ref _mainTreeNodeId);
185 _current = _tree.Key(_index);
186 return result;
187 }
188
190 {
191 if (_version != _tree._version)
192 {
194 }
195 _index = 0;
196 _mainTreeNodeId = _tree.root;
197 _current = default(K);
198 }
199 }
200
202
203 private int[] _pageTableMap;
204
205 private int _inUsePageCount;
206
207 private int _nextFreePageLine;
208
209 public int root;
210
211 private int _version;
212
213 private int _inUseNodeCount;
214
216
218
219 public int Count => _inUseNodeCount - 1;
220
222
223 public K this[int index] => Key(GetNodeByIndex(index)._nodeID);
224
225 protected abstract int CompareNode(K record1, K record2);
226
227 protected abstract int CompareSateliteTreeNode(K record1, K record2);
228
234
235 [MemberNotNull("_pageTable")]
236 [MemberNotNull("_pageTableMap")]
237 private void InitTree()
238 {
239 root = 0;
240 _pageTable = new TreePage[32];
241 _pageTableMap = new int[(_pageTable.Length + 32 - 1) / 32];
242 _inUsePageCount = 0;
244 AllocPage(32);
246 _pageTable[0]._slotMap[0] = 1;
247 _pageTable[0].InUseCount = 1;
248 _inUseNodeCount = 1;
250 }
251
252 private void FreePage(TreePage page)
253 {
255 _pageTable[page.PageId] = null;
257 }
258
259 private TreePage AllocPage(int size)
260 {
262 if (num != -1)
263 {
264 _pageTable[num] = new TreePage(size);
265 _nextFreePageLine = num / 32;
266 }
267 else
268 {
269 TreePage[] array = new TreePage[_pageTable.Length * 2];
271 int[] array2 = new int[(array.Length + 32 - 1) / 32];
274 num = _pageTable.Length;
277 _pageTable[num] = new TreePage(size);
278 }
279 _pageTable[num].PageId = num;
281 return _pageTable[num];
282 }
283
285 {
286 _pageTableMap[page.PageId / 32] |= 1 << page.PageId % 32;
287 }
288
290 {
291 _pageTableMap[page.PageId / 32] &= ~(1 << page.PageId % 32);
292 }
293
294 private static int GetIntValueFromBitMap(uint bitMap)
295 {
296 int num = 0;
297 if ((bitMap & 0xFFFF0000u) != 0)
298 {
299 num += 16;
300 bitMap >>= 16;
301 }
302 if ((bitMap & 0xFF00u) != 0)
303 {
304 num += 8;
305 bitMap >>= 8;
306 }
307 if ((bitMap & 0xF0u) != 0)
308 {
309 num += 4;
310 bitMap >>= 4;
311 }
312 if ((bitMap & 0xCu) != 0)
313 {
314 num += 2;
315 bitMap >>= 2;
316 }
317 if ((bitMap & 2u) != 0)
318 {
319 num++;
320 }
321 return num;
322 }
323
324 private void FreeNode(int nodeId)
325 {
327 int num = nodeId & 0xFFFF;
328 treePage._slots[num] = default(Node);
329 treePage._slotMap[num / 32] &= ~(1 << num % 32);
330 treePage.InUseCount--;
332 if (treePage.InUseCount == 0)
333 {
335 }
336 else if (treePage.InUseCount == treePage._slots.Length - 1)
337 {
339 }
340 }
341
343 {
344 int i = _nextFreePageLine;
345 int result = -1;
346 for (; i < _pageTableMap.Length; i++)
347 {
348 if ((uint)_pageTableMap[i] >= uint.MaxValue)
349 {
350 continue;
351 }
352 uint num = (uint)_pageTableMap[i];
353 while ((num ^ 0xFFFFFFFFu) != 0)
354 {
355 uint num2 = ~num & (num + 1);
356 if ((_pageTableMap[i] & num2) != 0L)
357 {
358 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.PagePositionInSlotInUse);
359 }
360 result = i * 32 + GetIntValueFromBitMap(num2);
361 if (allocatedPage)
362 {
363 if (_pageTable[result] != null)
364 {
365 return result;
366 }
367 }
368 else if (_pageTable[result] == null)
369 {
370 return result;
371 }
372 result = -1;
373 num |= num2;
374 }
375 }
376 if (_nextFreePageLine != 0)
377 {
380 }
381 return result;
382 }
383
384 private int GetNewNode(K key)
385 {
386 TreePage treePage = null;
388 treePage = ((indexOfPageWithFreeSlot != -1) ? _pageTable[indexOfPageWithFreeSlot] : ((_inUsePageCount < 4) ? AllocPage(32) : ((_inUsePageCount < 32) ? AllocPage(256) : ((_inUsePageCount < 128) ? AllocPage(1024) : ((_inUsePageCount < 4096) ? AllocPage(4096) : ((_inUsePageCount >= 32768) ? AllocPage(65536) : AllocPage(8192)))))));
389 int num = treePage.AllocSlot(this);
390 if (num == -1)
391 {
393 }
394 treePage._slots[num]._selfId = (treePage.PageId << 16) | num;
395 treePage._slots[num]._subTreeSize = 1;
396 treePage._slots[num]._keyOfNode = key;
397 return treePage._slots[num]._selfId;
398 }
399
400 private int Successor(int x_id)
401 {
402 if (Right(x_id) != 0)
403 {
404 return Minimum(Right(x_id));
405 }
406 int num = Parent(x_id);
407 while (num != 0 && x_id == Right(num))
408 {
409 x_id = num;
410 num = Parent(num);
411 }
412 return num;
413 }
414
415 private bool Successor(ref int nodeId, ref int mainTreeNodeId)
416 {
417 if (nodeId == 0)
418 {
420 mainTreeNodeId = 0;
421 }
422 else
423 {
425 if (nodeId == 0 && mainTreeNodeId != 0)
426 {
428 mainTreeNodeId = 0;
429 }
430 }
431 if (nodeId != 0)
432 {
433 if (Next(nodeId) != 0)
434 {
435 if (mainTreeNodeId != 0)
436 {
437 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.NestedSatelliteTreeEnumerator);
438 }
441 }
442 return true;
443 }
444 return false;
445 }
446
447 private int Minimum(int x_id)
448 {
449 while (Left(x_id) != 0)
450 {
451 x_id = Left(x_id);
452 }
453 return x_id;
454 }
455
456 private int LeftRotate(int root_id, int x_id, int mainTreeNode)
457 {
458 int num = Right(x_id);
459 SetRight(x_id, Left(num));
460 if (Left(num) != 0)
461 {
462 SetParent(Left(num), x_id);
463 }
464 SetParent(num, Parent(x_id));
465 if (Parent(x_id) == 0)
466 {
467 if (root_id == 0)
468 {
469 root = num;
470 }
471 else
472 {
473 SetNext(mainTreeNode, num);
474 SetKey(mainTreeNode, Key(num));
475 root_id = num;
476 }
477 }
478 else if (x_id == Left(Parent(x_id)))
479 {
480 SetLeft(Parent(x_id), num);
481 }
482 else
483 {
484 SetRight(Parent(x_id), num);
485 }
486 SetLeft(num, x_id);
487 SetParent(x_id, num);
488 if (x_id != 0)
489 {
491 }
492 if (num != 0)
493 {
494 SetSubTreeSize(num, SubTreeSize(Left(num)) + SubTreeSize(Right(num)) + ((Next(num) == 0) ? 1 : SubTreeSize(Next(num))));
495 }
496 return root_id;
497 }
498
499 private int RightRotate(int root_id, int x_id, int mainTreeNode)
500 {
501 int num = Left(x_id);
502 SetLeft(x_id, Right(num));
503 if (Right(num) != 0)
504 {
505 SetParent(Right(num), x_id);
506 }
507 SetParent(num, Parent(x_id));
508 if (Parent(x_id) == 0)
509 {
510 if (root_id == 0)
511 {
512 root = num;
513 }
514 else
515 {
516 SetNext(mainTreeNode, num);
517 SetKey(mainTreeNode, Key(num));
518 root_id = num;
519 }
520 }
521 else if (x_id == Left(Parent(x_id)))
522 {
523 SetLeft(Parent(x_id), num);
524 }
525 else
526 {
527 SetRight(Parent(x_id), num);
528 }
529 SetRight(num, x_id);
530 SetParent(x_id, num);
531 if (x_id != 0)
532 {
534 }
535 if (num != 0)
536 {
537 SetSubTreeSize(num, SubTreeSize(Left(num)) + SubTreeSize(Right(num)) + ((Next(num) == 0) ? 1 : SubTreeSize(Next(num))));
538 }
539 return root_id;
540 }
541
542 private int RBInsert(int root_id, int x_id, int mainTreeNodeID, int position, bool append)
543 {
544 _version++;
545 int num = 0;
546 int num2 = ((root_id == 0) ? root : root_id);
547 if (_accessMethod == TreeAccessMethod.KEY_SEARCH_AND_INDEX && !append)
548 {
549 while (num2 != 0)
550 {
552 num = num2;
554 if (num3 < 0)
555 {
556 num2 = Left(num2);
557 continue;
558 }
559 if (num3 > 0)
560 {
561 num2 = Right(num2);
562 continue;
563 }
564 if (root_id != 0)
565 {
566 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.InvalidStateinInsert);
567 }
568 if (Next(num2) != 0)
569 {
570 root_id = RBInsert(Next(num2), x_id, num2, -1, append: false);
571 SetKey(num2, Key(Next(num2)));
572 }
573 else
574 {
575 int num4 = 0;
578 SetNext(num4, num2);
583 if (Left(Parent(num2)) == num2)
584 {
586 }
587 else if (Right(Parent(num2)) == num2)
588 {
590 }
591 if (Left(num2) != 0)
592 {
594 }
595 if (Right(num2) != 0)
596 {
598 }
599 if (root == num2)
600 {
601 root = num4;
602 }
603 SetColor(num2, NodeColor.black);
604 SetParent(num2, 0);
605 SetLeft(num2, 0);
606 SetRight(num2, 0);
607 int size = SubTreeSize(num2);
609 root_id = RBInsert(num2, x_id, num4, -1, append: false);
610 SetSubTreeSize(num4, size);
611 }
612 return root_id;
613 }
614 }
615 else
616 {
617 if (!(_accessMethod == TreeAccessMethod.INDEX_ONLY || append))
618 {
619 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.UnsupportedAccessMethod1);
620 }
621 if (position == -1)
622 {
623 position = SubTreeSize(root);
624 }
625 while (num2 != 0)
626 {
628 num = num2;
629 int num5 = position - SubTreeSize(Left(num));
630 if (num5 <= 0)
631 {
632 num2 = Left(num2);
633 continue;
634 }
635 num2 = Right(num2);
636 if (num2 != 0)
637 {
638 position = num5 - 1;
639 }
640 }
641 }
642 SetParent(x_id, num);
643 if (num == 0)
644 {
645 if (root_id == 0)
646 {
647 root = x_id;
648 }
649 else
650 {
653 root_id = x_id;
654 }
655 }
656 else
657 {
658 int num6 = 0;
659 if (_accessMethod == TreeAccessMethod.KEY_SEARCH_AND_INDEX)
660 {
661 num6 = ((root_id == 0) ? CompareNode(Key(x_id), Key(num)) : CompareSateliteTreeNode(Key(x_id), Key(num)));
662 }
663 else
664 {
665 if (_accessMethod != TreeAccessMethod.INDEX_ONLY)
666 {
667 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.UnsupportedAccessMethod2);
668 }
669 num6 = ((position > 0) ? 1 : (-1));
670 }
671 if (num6 < 0)
672 {
673 SetLeft(num, x_id);
674 }
675 else
676 {
677 SetRight(num, x_id);
678 }
679 }
680 SetLeft(x_id, 0);
681 SetRight(x_id, 0);
682 SetColor(x_id, NodeColor.red);
683 num2 = x_id;
684 while (color(Parent(x_id)) == NodeColor.red)
685 {
686 if (Parent(x_id) == Left(Parent(Parent(x_id))))
687 {
688 num = Right(Parent(Parent(x_id)));
689 if (color(num) == NodeColor.red)
690 {
691 SetColor(Parent(x_id), NodeColor.black);
692 SetColor(num, NodeColor.black);
695 continue;
696 }
697 if (x_id == Right(Parent(x_id)))
698 {
699 x_id = Parent(x_id);
701 }
702 SetColor(Parent(x_id), NodeColor.black);
705 continue;
706 }
707 num = Left(Parent(Parent(x_id)));
708 if (color(num) == NodeColor.red)
709 {
710 SetColor(Parent(x_id), NodeColor.black);
711 SetColor(num, NodeColor.black);
714 continue;
715 }
716 if (x_id == Left(Parent(x_id)))
717 {
718 x_id = Parent(x_id);
720 }
721 SetColor(Parent(x_id), NodeColor.black);
724 }
725 if (root_id == 0)
726 {
727 SetColor(root, NodeColor.black);
728 }
729 else
730 {
731 SetColor(root_id, NodeColor.black);
732 }
733 return root_id;
734 }
735
736 public void UpdateNodeKey(K currentKey, K newKey)
737 {
738 NodePath nodeByKey = GetNodeByKey(currentKey);
739 if (Parent(nodeByKey._nodeID) == 0 && nodeByKey._nodeID != root)
740 {
741 SetKey(nodeByKey._mainTreeNodeID, newKey);
742 }
743 SetKey(nodeByKey._nodeID, newKey);
744 }
745
746 public K DeleteByIndex(int i)
747 {
749 K result = Key(nodeByIndex._nodeID);
750 RBDeleteX(0, nodeByIndex._nodeID, nodeByIndex._mainTreeNodeID);
751 return result;
752 }
753
754 public int RBDelete(int z_id)
755 {
756 return RBDeleteX(0, z_id, 0);
757 }
758
759 private int RBDeleteX(int root_id, int z_id, int mainTreeNodeID)
760 {
761 int num = 0;
762 if (Next(z_id) != 0)
763 {
764 return RBDeleteX(Next(z_id), Next(z_id), z_id);
765 }
766 bool flag = false;
767 int num2 = ((_accessMethod == TreeAccessMethod.KEY_SEARCH_AND_INDEX) ? mainTreeNodeID : z_id);
768 if (Next(num2) != 0)
769 {
770 root_id = Next(num2);
771 }
772 if (SubTreeSize(Next(num2)) == 2)
773 {
774 flag = true;
775 }
776 else if (SubTreeSize(Next(num2)) == 1)
777 {
778 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.InvalidNextSizeInDelete);
779 }
780 int num3 = ((Left(z_id) != 0 && Right(z_id) != 0) ? Successor(z_id) : z_id);
781 num = ((Left(num3) == 0) ? Right(num3) : Left(num3));
782 int num4 = Parent(num3);
783 if (num != 0)
784 {
785 SetParent(num, num4);
786 }
787 if (num4 == 0)
788 {
789 if (root_id == 0)
790 {
791 root = num;
792 }
793 else
794 {
795 root_id = num;
796 }
797 }
798 else if (num3 == Left(num4))
799 {
800 SetLeft(num4, num);
801 }
802 else
803 {
804 SetRight(num4, num);
805 }
806 if (num3 != z_id)
807 {
808 SetKey(z_id, Key(num3));
810 }
811 if (Next(num2) != 0)
812 {
813 if (root_id == 0 && z_id != num2)
814 {
815 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.InvalidStateinDelete);
816 }
817 if (root_id != 0)
818 {
821 }
822 }
823 for (int num5 = num4; num5 != 0; num5 = Parent(num5))
824 {
826 }
827 if (root_id != 0)
828 {
829 for (int num6 = num2; num6 != 0; num6 = Parent(num6))
830 {
832 }
833 }
834 if (color(num3) == NodeColor.black)
835 {
837 }
838 if (flag)
839 {
840 if (num2 == 0 || SubTreeSize(Next(num2)) != 1)
841 {
842 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.InvalidNodeSizeinDelete);
843 }
845 int num7 = Next(num2);
850 if (Parent(num2) != 0)
851 {
853 if (Left(Parent(num2)) == num2)
854 {
856 }
857 else
858 {
860 }
861 }
862 if (Left(num2) != 0)
863 {
865 }
866 if (Right(num2) != 0)
867 {
869 }
870 if (root == num2)
871 {
872 root = num7;
873 }
874 FreeNode(num2);
875 num2 = 0;
876 }
877 else if (Next(num2) != 0)
878 {
879 if (root_id == 0 && z_id != num2)
880 {
881 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.InvalidStateinEndDelete);
882 }
883 if (root_id != 0)
884 {
887 }
888 }
889 if (num3 != z_id)
890 {
895 if (Parent(z_id) != 0)
896 {
898 if (Left(Parent(z_id)) == z_id)
899 {
901 }
902 else
903 {
905 }
906 }
907 else
908 {
909 SetParent(num3, 0);
910 }
911 if (Left(z_id) != 0)
912 {
914 }
915 if (Right(z_id) != 0)
916 {
918 }
919 if (root == z_id)
920 {
921 root = num3;
922 }
923 else if (root_id == z_id)
924 {
925 root_id = num3;
926 }
927 if (num2 != 0 && Next(num2) == z_id)
928 {
929 SetNext(num2, num3);
930 }
931 }
932 FreeNode(z_id);
933 _version++;
934 return z_id;
935 }
936
937 private int RBDeleteFixup(int root_id, int x_id, int px_id, int mainTreeNodeID)
938 {
939 if (x_id == 0 && px_id == 0)
940 {
941 return 0;
942 }
943 while (((root_id == 0) ? root : root_id) != x_id && color(x_id) == NodeColor.black)
944 {
945 int num;
946 if ((x_id != 0 && x_id == Left(Parent(x_id))) || (x_id == 0 && Left(px_id) == 0))
947 {
948 num = ((x_id == 0) ? Right(px_id) : Right(Parent(x_id)));
949 if (num == 0)
950 {
952 }
953 if (color(num) == NodeColor.red)
954 {
955 SetColor(num, NodeColor.black);
958 num = ((x_id == 0) ? Right(px_id) : Right(Parent(x_id)));
959 }
960 if (color(Left(num)) == NodeColor.black && color(Right(num)) == NodeColor.black)
961 {
962 SetColor(num, NodeColor.red);
963 x_id = px_id;
964 px_id = Parent(px_id);
965 continue;
966 }
967 if (color(Right(num)) == NodeColor.black)
968 {
969 SetColor(Left(num), NodeColor.black);
970 SetColor(num, NodeColor.red);
972 num = ((x_id == 0) ? Right(px_id) : Right(Parent(x_id)));
973 }
974 SetColor(num, color(px_id));
975 SetColor(px_id, NodeColor.black);
976 SetColor(Right(num), NodeColor.black);
978 x_id = ((root_id == 0) ? root : root_id);
979 px_id = Parent(x_id);
980 continue;
981 }
982 num = Left(px_id);
983 if (color(num) == NodeColor.red)
984 {
985 SetColor(num, NodeColor.black);
986 if (x_id != 0)
987 {
990 num = ((x_id == 0) ? Left(px_id) : Left(Parent(x_id)));
991 }
992 else
993 {
996 num = ((x_id == 0) ? Left(px_id) : Left(Parent(x_id)));
997 if (num == 0)
998 {
999 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.CannotRotateInvalidsuccessorNodeinDelete);
1000 }
1001 }
1002 }
1003 if (color(Right(num)) == NodeColor.black && color(Left(num)) == NodeColor.black)
1004 {
1005 SetColor(num, NodeColor.red);
1006 x_id = px_id;
1007 px_id = Parent(px_id);
1008 continue;
1009 }
1010 if (color(Left(num)) == NodeColor.black)
1011 {
1012 SetColor(Right(num), NodeColor.black);
1013 SetColor(num, NodeColor.red);
1015 num = ((x_id == 0) ? Left(px_id) : Left(Parent(x_id)));
1016 }
1017 SetColor(num, color(px_id));
1018 SetColor(px_id, NodeColor.black);
1019 SetColor(Left(num), NodeColor.black);
1021 x_id = ((root_id == 0) ? root : root_id);
1022 px_id = Parent(x_id);
1023 }
1024 SetColor(x_id, NodeColor.black);
1025 return root_id;
1026 }
1027
1028 private int SearchSubTree(int root_id, K key)
1029 {
1030 if (root_id != 0 && _accessMethod != TreeAccessMethod.KEY_SEARCH_AND_INDEX)
1031 {
1032 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.UnsupportedAccessMethodInNonNillRootSubtree);
1033 }
1034 int num = ((root_id == 0) ? root : root_id);
1035 while (num != 0)
1036 {
1037 int num2 = ((root_id == 0) ? CompareNode(key, Key(num)) : CompareSateliteTreeNode(key, Key(num)));
1038 if (num2 == 0)
1039 {
1040 break;
1041 }
1042 num = ((num2 >= 0) ? Right(num) : Left(num));
1043 }
1044 return num;
1045 }
1046
1047 public int Search(K key)
1048 {
1049 int num = root;
1050 while (num != 0)
1051 {
1052 int num2 = CompareNode(key, Key(num));
1053 if (num2 == 0)
1054 {
1055 break;
1056 }
1057 num = ((num2 >= 0) ? Right(num) : Left(num));
1058 }
1059 return num;
1060 }
1061
1063 {
1064 int num = SearchSubTree(0, key);
1065 if (Next(num) != 0)
1066 {
1067 return new NodePath(SearchSubTree(Next(num), key), num);
1068 }
1069 if (!Key(num).Equals(key))
1070 {
1071 num = 0;
1072 }
1073 return new NodePath(num, 0);
1074 }
1075
1076 public int GetIndexByKey(K key)
1077 {
1078 int result = -1;
1080 if (nodeByKey._nodeID != 0)
1081 {
1082 result = GetIndexByNodePath(nodeByKey);
1083 }
1084 return result;
1085 }
1086
1087 public int GetIndexByNode(int node)
1088 {
1089 if (_inUseSatelliteTreeCount == 0)
1090 {
1091 return ComputeIndexByNode(node);
1092 }
1093 if (Next(node) != 0)
1094 {
1096 }
1097 int num = SearchSubTree(0, Key(node));
1098 if (num == node)
1099 {
1101 }
1103 }
1104
1106 {
1107 if (_inUseSatelliteTreeCount == 0)
1108 {
1109 return ComputeIndexByNode(path._nodeID);
1110 }
1111 if (path._mainTreeNodeID == 0)
1112 {
1113 return ComputeIndexWithSatelliteByNode(path._nodeID);
1114 }
1115 return ComputeIndexWithSatelliteByNode(path._mainTreeNodeID) + ComputeIndexByNode(path._nodeID);
1116 }
1117
1119 {
1120 int num = SubTreeSize(Left(nodeId));
1121 while (nodeId != 0)
1122 {
1123 int num2 = Parent(nodeId);
1124 if (nodeId == Right(num2))
1125 {
1126 num += SubTreeSize(Left(num2)) + 1;
1127 }
1128 nodeId = num2;
1129 }
1130 return num;
1131 }
1132
1134 {
1135 int num = SubTreeSize(Left(nodeId));
1136 while (nodeId != 0)
1137 {
1138 int num2 = Parent(nodeId);
1139 if (nodeId == Right(num2))
1140 {
1141 num += SubTreeSize(Left(num2)) + ((Next(num2) == 0) ? 1 : SubTreeSize(Next(num2)));
1142 }
1143 nodeId = num2;
1144 }
1145 return num;
1146 }
1147
1149 {
1150 int num;
1151 int satelliteRootId;
1152 if (_inUseSatelliteTreeCount == 0)
1153 {
1154 num = ComputeNodeByIndex(root, userIndex + 1);
1155 satelliteRootId = 0;
1156 }
1157 else
1158 {
1160 }
1161 if (num == 0)
1162 {
1163 if (TreeAccessMethod.INDEX_ONLY == _accessMethod)
1164 {
1166 }
1167 throw ExceptionBuilder.InternalRBTreeError(RBTreeError.IndexOutOFRangeinGetNodeByIndex);
1168 }
1169 return new NodePath(num, satelliteRootId);
1170 }
1171
1173 {
1174 index++;
1175 satelliteRootId = 0;
1176 int num = root;
1177 int num2 = -1;
1178 while (num != 0 && ((num2 = SubTreeSize(Left(num)) + 1) != index || Next(num) != 0))
1179 {
1180 if (index < num2)
1181 {
1182 num = Left(num);
1183 continue;
1184 }
1185 if (Next(num) != 0 && index >= num2 && index <= num2 + SubTreeSize(Next(num)) - 1)
1186 {
1187 satelliteRootId = num;
1188 index = index - num2 + 1;
1189 return ComputeNodeByIndex(Next(num), index);
1190 }
1191 index = ((Next(num) != 0) ? (index - (num2 + SubTreeSize(Next(num)) - 1)) : (index - num2));
1192 num = Right(num);
1193 }
1194 return num;
1195 }
1196
1197 private int ComputeNodeByIndex(int x_id, int index)
1198 {
1199 while (x_id != 0)
1200 {
1201 int num = Left(x_id);
1202 int num2 = SubTreeSize(num) + 1;
1203 if (index < num2)
1204 {
1205 x_id = num;
1206 continue;
1207 }
1208 if (num2 >= index)
1209 {
1210 break;
1211 }
1212 x_id = Right(x_id);
1213 index -= num2;
1214 }
1215 return x_id;
1216 }
1217
1218 public int Insert(K item)
1219 {
1220 int newNode = GetNewNode(item);
1221 RBInsert(0, newNode, 0, -1, append: false);
1222 return newNode;
1223 }
1224
1225 public int Add(K item)
1226 {
1227 int newNode = GetNewNode(item);
1228 RBInsert(0, newNode, 0, -1, append: false);
1229 return newNode;
1230 }
1231
1233 {
1234 return new RBTreeEnumerator(this);
1235 }
1236
1237 public int IndexOf(int nodeId, K item)
1238 {
1239 int result = -1;
1240 if (nodeId != 0)
1241 {
1242 if ((object)Key(nodeId) == (object)item)
1243 {
1244 return GetIndexByNode(nodeId);
1245 }
1246 if ((result = IndexOf(Left(nodeId), item)) != -1)
1247 {
1248 return result;
1249 }
1250 result = IndexOf(Right(nodeId), item);
1251 _ = -1;
1252 return result;
1253 }
1254 return result;
1255 }
1256
1257 public int Insert(int position, K item)
1258 {
1259 return InsertAt(position, item, append: false);
1260 }
1261
1262 public int InsertAt(int position, K item, bool append)
1263 {
1264 int newNode = GetNewNode(item);
1265 RBInsert(0, newNode, 0, position, append);
1266 return newNode;
1267 }
1268
1269 public void RemoveAt(int position)
1270 {
1271 DeleteByIndex(position);
1272 }
1273
1274 public void Clear()
1275 {
1276 InitTree();
1277 _version++;
1278 }
1279
1280 public void CopyTo(Array array, int index)
1281 {
1282 if (array == null)
1283 {
1284 throw ExceptionBuilder.ArgumentNull("array");
1285 }
1286 if (index < 0)
1287 {
1288 throw ExceptionBuilder.ArgumentOutOfRange("index");
1289 }
1290 int count = Count;
1291 if (array.Length - index < Count)
1292 {
1294 }
1295 int num = Minimum(root);
1296 for (int i = 0; i < count; i++)
1297 {
1298 array.SetValue(Key(num), index + i);
1299 num = Successor(num);
1300 }
1301 }
1302
1303 public void CopyTo(K[] array, int index)
1304 {
1305 if (array == null)
1306 {
1307 throw ExceptionBuilder.ArgumentNull("array");
1308 }
1309 if (index < 0)
1310 {
1311 throw ExceptionBuilder.ArgumentOutOfRange("index");
1312 }
1313 int count = Count;
1314 if (array.Length - index < Count)
1315 {
1317 }
1318 int num = Minimum(root);
1319 for (int i = 0; i < count; i++)
1320 {
1321 array[index + i] = Key(num);
1322 num = Successor(num);
1323 }
1324 }
1325
1326 private void SetRight(int nodeId, int rightNodeId)
1327 {
1329 }
1330
1331 private void SetLeft(int nodeId, int leftNodeId)
1332 {
1333 _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._leftId = leftNodeId;
1334 }
1335
1336 private void SetParent(int nodeId, int parentNodeId)
1337 {
1339 }
1340
1341 private void SetColor(int nodeId, NodeColor color)
1342 {
1343 _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._nodeColor = color;
1344 }
1345
1346 private void SetKey(int nodeId, K key)
1347 {
1348 _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._keyOfNode = key;
1349 }
1350
1351 private void SetNext(int nodeId, int nextNodeId)
1352 {
1353 _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._nextId = nextNodeId;
1354 }
1355
1356 private void SetSubTreeSize(int nodeId, int size)
1357 {
1358 _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._subTreeSize = size;
1359 }
1360
1361 private void IncreaseSize(int nodeId)
1362 {
1363 _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._subTreeSize++;
1364 }
1365
1366 private void RecomputeSize(int nodeId)
1367 {
1370 }
1371
1372 private void DecreaseSize(int nodeId)
1373 {
1374 _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._subTreeSize--;
1375 }
1376
1377 public int Right(int nodeId)
1378 {
1379 return _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._rightId;
1380 }
1381
1382 public int Left(int nodeId)
1383 {
1384 return _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._leftId;
1385 }
1386
1387 public int Parent(int nodeId)
1388 {
1389 return _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._parentId;
1390 }
1391
1393 {
1394 return _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._nodeColor;
1395 }
1396
1397 public int Next(int nodeId)
1398 {
1399 return _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._nextId;
1400 }
1401
1402 public int SubTreeSize(int nodeId)
1403 {
1404 return _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._subTreeSize;
1405 }
1406
1407 public K Key(int nodeId)
1408 {
1409 return _pageTable[nodeId >> 16]._slots[nodeId & 0xFFFF]._keyOfNode;
1410 }
1411}
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
static Exception EnumeratorModified()
static Exception ArgumentOutOfRange(string paramName)
static Exception InvalidOffsetLength()
static Exception InternalRBTreeError(RBTreeError internalError)
static Exception ArgumentNull(string paramName)
readonly Node[] _slots
Definition RBTree.cs:49
readonly int[] _slotMap
Definition RBTree.cs:51
int AllocSlot(RBTree< K > tree)
Definition RBTree.cs:93
K Key(int nodeId)
Definition RBTree.cs:1407
K DeleteByIndex(int i)
Definition RBTree.cs:746
int ComputeNodeByIndex(int index, out int satelliteRootId)
Definition RBTree.cs:1172
NodeColor color(int nodeId)
Definition RBTree.cs:1392
int Insert(int position, K item)
Definition RBTree.cs:1257
int GetIndexOfPageWithFreeSlot(bool allocatedPage)
Definition RBTree.cs:342
int ComputeIndexWithSatelliteByNode(int nodeId)
Definition RBTree.cs:1133
void SetNext(int nodeId, int nextNodeId)
Definition RBTree.cs:1351
int Right(int nodeId)
Definition RBTree.cs:1377
void SetRight(int nodeId, int rightNodeId)
Definition RBTree.cs:1326
void MarkPageFree(TreePage page)
Definition RBTree.cs:289
int IndexOf(int nodeId, K item)
Definition RBTree.cs:1237
int Parent(int nodeId)
Definition RBTree.cs:1387
void UpdateNodeKey(K currentKey, K newKey)
Definition RBTree.cs:736
TreePage AllocPage(int size)
Definition RBTree.cs:259
int GetIndexByKey(K key)
Definition RBTree.cs:1076
int Add(K item)
Definition RBTree.cs:1225
int Successor(int x_id)
Definition RBTree.cs:400
int GetIndexByNodePath(NodePath path)
Definition RBTree.cs:1105
int RBDelete(int z_id)
Definition RBTree.cs:754
void CopyTo(Array array, int index)
Definition RBTree.cs:1280
void SetColor(int nodeId, NodeColor color)
Definition RBTree.cs:1341
int SubTreeSize(int nodeId)
Definition RBTree.cs:1402
int GetNewNode(K key)
Definition RBTree.cs:384
int ComputeNodeByIndex(int x_id, int index)
Definition RBTree.cs:1197
int[] _pageTableMap
Definition RBTree.cs:203
readonly TreeAccessMethod _accessMethod
Definition RBTree.cs:217
int LeftRotate(int root_id, int x_id, int mainTreeNode)
Definition RBTree.cs:456
void RemoveAt(int position)
Definition RBTree.cs:1269
int SearchSubTree(int root_id, K key)
Definition RBTree.cs:1028
void SetLeft(int nodeId, int leftNodeId)
Definition RBTree.cs:1331
int _inUseSatelliteTreeCount
Definition RBTree.cs:215
void IncreaseSize(int nodeId)
Definition RBTree.cs:1361
int Search(K key)
Definition RBTree.cs:1047
int InsertAt(int position, K item, bool append)
Definition RBTree.cs:1262
int RBInsert(int root_id, int x_id, int mainTreeNodeID, int position, bool append)
Definition RBTree.cs:542
int GetIndexByNode(int node)
Definition RBTree.cs:1087
void FreePage(TreePage page)
Definition RBTree.cs:252
static int GetIntValueFromBitMap(uint bitMap)
Definition RBTree.cs:294
int RBDeleteFixup(int root_id, int x_id, int px_id, int mainTreeNodeID)
Definition RBTree.cs:937
int Next(int nodeId)
Definition RBTree.cs:1397
int RightRotate(int root_id, int x_id, int mainTreeNode)
Definition RBTree.cs:499
int CompareSateliteTreeNode(K record1, K record2)
void DecreaseSize(int nodeId)
Definition RBTree.cs:1372
RBTree(TreeAccessMethod accessMethod)
Definition RBTree.cs:229
IEnumerator GetEnumerator()
Definition RBTree.cs:1232
void SetParent(int nodeId, int parentNodeId)
Definition RBTree.cs:1336
int ComputeIndexByNode(int nodeId)
Definition RBTree.cs:1118
int RBDeleteX(int root_id, int z_id, int mainTreeNodeID)
Definition RBTree.cs:759
NodePath GetNodeByKey(K key)
Definition RBTree.cs:1062
NodePath GetNodeByIndex(int userIndex)
Definition RBTree.cs:1148
void SetSubTreeSize(int nodeId, int size)
Definition RBTree.cs:1356
void CopyTo(K[] array, int index)
Definition RBTree.cs:1303
void SetKey(int nodeId, K key)
Definition RBTree.cs:1346
void FreeNode(int nodeId)
Definition RBTree.cs:324
int Left(int nodeId)
Definition RBTree.cs:1382
int Insert(K item)
Definition RBTree.cs:1218
int CompareNode(K record1, K record2)
bool Successor(ref int nodeId, ref int mainTreeNodeId)
Definition RBTree.cs:415
TreePage[] _pageTable
Definition RBTree.cs:201
int Minimum(int x_id)
Definition RBTree.cs:447
void MarkPageFull(TreePage page)
Definition RBTree.cs:284
void RecomputeSize(int nodeId)
Definition RBTree.cs:1366
NodePath(int nodeID, int mainTreeNodeID)
Definition RBTree.cs:40
readonly int _mainTreeNodeID
Definition RBTree.cs:38
NodeColor _nodeColor
Definition RBTree.cs:31
object IEnumerator. Current
Definition RBTree.cs:143
readonly RBTree< K > _tree
Definition RBTree.cs:131
RBTreeEnumerator(RBTree< K > tree)
Definition RBTree.cs:145
RBTreeEnumerator(RBTree< K > tree, int position)
Definition RBTree.cs:154