Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/core/templates/rb_map.h
9973 views
1
/**************************************************************************/
2
/* rb_map.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/error/error_macros.h"
34
#include "core/os/memory.h"
35
#include "core/templates/pair.h"
36
37
#include <initializer_list>
38
39
// based on the very nice implementation of rb-trees by:
40
// https://web.archive.org/web/20120507164830/https://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
41
42
template <typename K, typename V, typename C = Comparator<K>, typename A = DefaultAllocator>
43
class RBMap {
44
enum Color {
45
RED,
46
BLACK
47
};
48
struct _Data;
49
50
public:
51
class Element {
52
private:
53
friend class RBMap<K, V, C, A>;
54
int color = RED;
55
Element *right = nullptr;
56
Element *left = nullptr;
57
Element *parent = nullptr;
58
Element *_next = nullptr;
59
Element *_prev = nullptr;
60
KeyValue<K, V> _data;
61
62
public:
63
KeyValue<K, V> &key_value() { return _data; }
64
const KeyValue<K, V> &key_value() const { return _data; }
65
66
const Element *next() const {
67
return _next;
68
}
69
Element *next() {
70
return _next;
71
}
72
const Element *prev() const {
73
return _prev;
74
}
75
Element *prev() {
76
return _prev;
77
}
78
const K &key() const {
79
return _data.key;
80
}
81
V &value() {
82
return _data.value;
83
}
84
const V &value() const {
85
return _data.value;
86
}
87
V &get() {
88
return _data.value;
89
}
90
const V &get() const {
91
return _data.value;
92
}
93
Element(const KeyValue<K, V> &p_data) :
94
_data(p_data) {}
95
};
96
97
typedef KeyValue<K, V> ValueType;
98
99
struct Iterator {
100
friend class RBMap<K, V, C, A>;
101
102
_FORCE_INLINE_ KeyValue<K, V> &operator*() const {
103
return E->key_value();
104
}
105
_FORCE_INLINE_ KeyValue<K, V> *operator->() const { return &E->key_value(); }
106
_FORCE_INLINE_ Iterator &operator++() {
107
E = E->next();
108
return *this;
109
}
110
_FORCE_INLINE_ Iterator &operator--() {
111
E = E->prev();
112
return *this;
113
}
114
115
_FORCE_INLINE_ bool operator==(const Iterator &p_it) const { return E == p_it.E; }
116
_FORCE_INLINE_ bool operator!=(const Iterator &p_it) const { return E != p_it.E; }
117
explicit operator bool() const {
118
return E != nullptr;
119
}
120
121
Iterator &operator=(const Iterator &p_it) {
122
E = p_it.E;
123
return *this;
124
}
125
Iterator(Element *p_E) { E = p_E; }
126
Iterator() {}
127
Iterator(const Iterator &p_it) { E = p_it.E; }
128
129
private:
130
Element *E = nullptr;
131
};
132
133
struct ConstIterator {
134
_FORCE_INLINE_ const KeyValue<K, V> &operator*() const {
135
return E->key_value();
136
}
137
_FORCE_INLINE_ const KeyValue<K, V> *operator->() const { return &E->key_value(); }
138
_FORCE_INLINE_ ConstIterator &operator++() {
139
E = E->next();
140
return *this;
141
}
142
_FORCE_INLINE_ ConstIterator &operator--() {
143
E = E->prev();
144
return *this;
145
}
146
147
_FORCE_INLINE_ bool operator==(const ConstIterator &p_it) const { return E == p_it.E; }
148
_FORCE_INLINE_ bool operator!=(const ConstIterator &p_it) const { return E != p_it.E; }
149
explicit operator bool() const {
150
return E != nullptr;
151
}
152
153
ConstIterator &operator=(const ConstIterator &p_it) {
154
E = p_it.E;
155
return *this;
156
}
157
ConstIterator(const Element *p_E) { E = p_E; }
158
ConstIterator() {}
159
ConstIterator(const ConstIterator &p_it) { E = p_it.E; }
160
161
private:
162
const Element *E = nullptr;
163
};
164
165
_FORCE_INLINE_ Iterator begin() {
166
return Iterator(front());
167
}
168
_FORCE_INLINE_ Iterator end() {
169
return Iterator(nullptr);
170
}
171
172
#if 0
173
//to use when replacing find()
174
_FORCE_INLINE_ Iterator find(const K &p_key) {
175
return Iterator(find(p_key));
176
}
177
#endif
178
_FORCE_INLINE_ void remove(const Iterator &p_iter) {
179
return erase(p_iter.E);
180
}
181
182
_FORCE_INLINE_ ConstIterator begin() const {
183
return ConstIterator(front());
184
}
185
_FORCE_INLINE_ ConstIterator end() const {
186
return ConstIterator(nullptr);
187
}
188
189
#if 0
190
//to use when replacing find()
191
_FORCE_INLINE_ ConstIterator find(const K &p_key) const {
192
return ConstIterator(find(p_key));
193
}
194
#endif
195
private:
196
struct _Data {
197
Element *_root = nullptr;
198
Element *_nil = nullptr;
199
int size_cache = 0;
200
201
_FORCE_INLINE_ _Data() {
202
#ifdef GLOBALNIL_DISABLED
203
_nil = memnew_allocator(Element, A);
204
_nil->parent = _nil->left = _nil->right = _nil;
205
_nil->color = BLACK;
206
#else
207
_nil = (Element *)&_GlobalNilClass::_nil;
208
#endif
209
}
210
211
void _create_root() {
212
_root = memnew_allocator(Element(KeyValue<K, V>(K(), V())), A);
213
_root->parent = _root->left = _root->right = _nil;
214
_root->color = BLACK;
215
}
216
217
void _free_root() {
218
if (_root) {
219
memdelete_allocator<Element, A>(_root);
220
_root = nullptr;
221
}
222
}
223
224
~_Data() {
225
_free_root();
226
227
#ifdef GLOBALNIL_DISABLED
228
memdelete_allocator<Element, A>(_nil);
229
#endif
230
}
231
};
232
233
_Data _data;
234
235
inline void _set_color(Element *p_node, int p_color) {
236
ERR_FAIL_COND(p_node == _data._nil && p_color == RED);
237
p_node->color = p_color;
238
}
239
240
inline void _rotate_left(Element *p_node) {
241
Element *r = p_node->right;
242
p_node->right = r->left;
243
if (r->left != _data._nil) {
244
r->left->parent = p_node;
245
}
246
r->parent = p_node->parent;
247
if (p_node == p_node->parent->left) {
248
p_node->parent->left = r;
249
} else {
250
p_node->parent->right = r;
251
}
252
253
r->left = p_node;
254
p_node->parent = r;
255
}
256
257
inline void _rotate_right(Element *p_node) {
258
Element *l = p_node->left;
259
p_node->left = l->right;
260
if (l->right != _data._nil) {
261
l->right->parent = p_node;
262
}
263
l->parent = p_node->parent;
264
if (p_node == p_node->parent->right) {
265
p_node->parent->right = l;
266
} else {
267
p_node->parent->left = l;
268
}
269
270
l->right = p_node;
271
p_node->parent = l;
272
}
273
274
inline Element *_successor(Element *p_node) const {
275
Element *node = p_node;
276
277
if (node->right != _data._nil) {
278
node = node->right;
279
while (node->left != _data._nil) { /* returns the minimum of the right subtree of node */
280
node = node->left;
281
}
282
return node;
283
} else {
284
while (node == node->parent->right) {
285
node = node->parent;
286
}
287
288
if (node->parent == _data._root) {
289
return nullptr; // No successor, as p_node = last node
290
}
291
return node->parent;
292
}
293
}
294
295
inline Element *_predecessor(Element *p_node) const {
296
Element *node = p_node;
297
298
if (node->left != _data._nil) {
299
node = node->left;
300
while (node->right != _data._nil) { /* returns the minimum of the left subtree of node */
301
node = node->right;
302
}
303
return node;
304
} else {
305
while (node == node->parent->left) {
306
node = node->parent;
307
}
308
309
if (node == _data._root) {
310
return nullptr; // No predecessor, as p_node = first node
311
}
312
return node->parent;
313
}
314
}
315
316
Element *_find(const K &p_key) const {
317
Element *node = _data._root->left;
318
C less;
319
320
while (node != _data._nil) {
321
if (less(p_key, node->_data.key)) {
322
node = node->left;
323
} else if (less(node->_data.key, p_key)) {
324
node = node->right;
325
} else {
326
return node; // found
327
}
328
}
329
330
return nullptr;
331
}
332
333
Element *_find_closest(const K &p_key) const {
334
Element *node = _data._root->left;
335
Element *prev = nullptr;
336
C less;
337
338
while (node != _data._nil) {
339
prev = node;
340
341
if (less(p_key, node->_data.key)) {
342
node = node->left;
343
} else if (less(node->_data.key, p_key)) {
344
node = node->right;
345
} else {
346
return node; // found
347
}
348
}
349
350
if (prev == nullptr) {
351
return nullptr; // tree empty
352
}
353
354
if (less(p_key, prev->_data.key)) {
355
prev = prev->_prev;
356
}
357
358
return prev;
359
}
360
361
void _insert_rb_fix(Element *p_new_node) {
362
Element *node = p_new_node;
363
Element *nparent = node->parent;
364
Element *ngrand_parent = nullptr;
365
366
while (nparent->color == RED) {
367
ngrand_parent = nparent->parent;
368
369
if (nparent == ngrand_parent->left) {
370
if (ngrand_parent->right->color == RED) {
371
_set_color(nparent, BLACK);
372
_set_color(ngrand_parent->right, BLACK);
373
_set_color(ngrand_parent, RED);
374
node = ngrand_parent;
375
nparent = node->parent;
376
} else {
377
if (node == nparent->right) {
378
_rotate_left(nparent);
379
node = nparent;
380
nparent = node->parent;
381
}
382
_set_color(nparent, BLACK);
383
_set_color(ngrand_parent, RED);
384
_rotate_right(ngrand_parent);
385
}
386
} else {
387
if (ngrand_parent->left->color == RED) {
388
_set_color(nparent, BLACK);
389
_set_color(ngrand_parent->left, BLACK);
390
_set_color(ngrand_parent, RED);
391
node = ngrand_parent;
392
nparent = node->parent;
393
} else {
394
if (node == nparent->left) {
395
_rotate_right(nparent);
396
node = nparent;
397
nparent = node->parent;
398
}
399
_set_color(nparent, BLACK);
400
_set_color(ngrand_parent, RED);
401
_rotate_left(ngrand_parent);
402
}
403
}
404
}
405
406
_set_color(_data._root->left, BLACK);
407
}
408
409
Element *_insert(const K &p_key, const V &p_value) {
410
Element *new_parent = _data._root;
411
Element *node = _data._root->left;
412
C less;
413
414
while (node != _data._nil) {
415
new_parent = node;
416
417
if (less(p_key, node->_data.key)) {
418
node = node->left;
419
} else if (less(node->_data.key, p_key)) {
420
node = node->right;
421
} else {
422
node->_data.value = p_value;
423
return node; // Return existing node with new value
424
}
425
}
426
427
typedef KeyValue<K, V> KV;
428
Element *new_node = memnew_allocator(Element(KV(p_key, p_value)), A);
429
new_node->parent = new_parent;
430
new_node->right = _data._nil;
431
new_node->left = _data._nil;
432
433
//new_node->data=_data;
434
435
if (new_parent == _data._root || less(p_key, new_parent->_data.key)) {
436
new_parent->left = new_node;
437
} else {
438
new_parent->right = new_node;
439
}
440
441
new_node->_next = _successor(new_node);
442
new_node->_prev = _predecessor(new_node);
443
if (new_node->_next) {
444
new_node->_next->_prev = new_node;
445
}
446
if (new_node->_prev) {
447
new_node->_prev->_next = new_node;
448
}
449
450
_data.size_cache++;
451
_insert_rb_fix(new_node);
452
return new_node;
453
}
454
455
void _erase_fix_rb(Element *p_node) {
456
Element *root = _data._root->left;
457
Element *node = _data._nil;
458
Element *sibling = p_node;
459
Element *parent = sibling->parent;
460
461
while (node != root) { // If red node found, will exit at a break
462
if (sibling->color == RED) {
463
_set_color(sibling, BLACK);
464
_set_color(parent, RED);
465
if (sibling == parent->right) {
466
sibling = sibling->left;
467
_rotate_left(parent);
468
} else {
469
sibling = sibling->right;
470
_rotate_right(parent);
471
}
472
}
473
if ((sibling->left->color == BLACK) && (sibling->right->color == BLACK)) {
474
_set_color(sibling, RED);
475
if (parent->color == RED) {
476
_set_color(parent, BLACK);
477
break;
478
} else { // loop: haven't found any red nodes yet
479
node = parent;
480
parent = node->parent;
481
sibling = (node == parent->left) ? parent->right : parent->left;
482
}
483
} else {
484
if (sibling == parent->right) {
485
if (sibling->right->color == BLACK) {
486
_set_color(sibling->left, BLACK);
487
_set_color(sibling, RED);
488
_rotate_right(sibling);
489
sibling = sibling->parent;
490
}
491
_set_color(sibling, parent->color);
492
_set_color(parent, BLACK);
493
_set_color(sibling->right, BLACK);
494
_rotate_left(parent);
495
break;
496
} else {
497
if (sibling->left->color == BLACK) {
498
_set_color(sibling->right, BLACK);
499
_set_color(sibling, RED);
500
_rotate_left(sibling);
501
sibling = sibling->parent;
502
}
503
504
_set_color(sibling, parent->color);
505
_set_color(parent, BLACK);
506
_set_color(sibling->left, BLACK);
507
_rotate_right(parent);
508
break;
509
}
510
}
511
}
512
513
ERR_FAIL_COND(_data._nil->color != BLACK);
514
}
515
516
void _erase(Element *p_node) {
517
Element *rp = ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : p_node->_next;
518
Element *node = (rp->left == _data._nil) ? rp->right : rp->left;
519
520
Element *sibling = nullptr;
521
if (rp == rp->parent->left) {
522
rp->parent->left = node;
523
sibling = rp->parent->right;
524
} else {
525
rp->parent->right = node;
526
sibling = rp->parent->left;
527
}
528
529
if (node->color == RED) {
530
node->parent = rp->parent;
531
_set_color(node, BLACK);
532
} else if (rp->color == BLACK && rp->parent != _data._root) {
533
_erase_fix_rb(sibling);
534
}
535
536
if (rp != p_node) {
537
ERR_FAIL_COND(rp == _data._nil);
538
539
rp->left = p_node->left;
540
rp->right = p_node->right;
541
rp->parent = p_node->parent;
542
rp->color = p_node->color;
543
if (p_node->left != _data._nil) {
544
p_node->left->parent = rp;
545
}
546
if (p_node->right != _data._nil) {
547
p_node->right->parent = rp;
548
}
549
550
if (p_node == p_node->parent->left) {
551
p_node->parent->left = rp;
552
} else {
553
p_node->parent->right = rp;
554
}
555
}
556
557
if (p_node->_next) {
558
p_node->_next->_prev = p_node->_prev;
559
}
560
if (p_node->_prev) {
561
p_node->_prev->_next = p_node->_next;
562
}
563
564
memdelete_allocator<Element, A>(p_node);
565
_data.size_cache--;
566
ERR_FAIL_COND(_data._nil->color == RED);
567
}
568
569
void _calculate_depth(Element *p_element, int &max_d, int d) const {
570
if (p_element == _data._nil) {
571
return;
572
}
573
574
_calculate_depth(p_element->left, max_d, d + 1);
575
_calculate_depth(p_element->right, max_d, d + 1);
576
577
if (d > max_d) {
578
max_d = d;
579
}
580
}
581
582
void _cleanup_tree(Element *p_element) {
583
if (p_element == _data._nil) {
584
return;
585
}
586
587
_cleanup_tree(p_element->left);
588
_cleanup_tree(p_element->right);
589
memdelete_allocator<Element, A>(p_element);
590
}
591
592
void _copy_from(const RBMap &p_map) {
593
clear();
594
// not the fastest way, but safeset to write.
595
for (Element *I = p_map.front(); I; I = I->next()) {
596
insert(I->key(), I->value());
597
}
598
}
599
600
public:
601
const Element *find(const K &p_key) const {
602
if (!_data._root) {
603
return nullptr;
604
}
605
606
const Element *res = _find(p_key);
607
return res;
608
}
609
610
Element *find(const K &p_key) {
611
if (!_data._root) {
612
return nullptr;
613
}
614
615
Element *res = _find(p_key);
616
return res;
617
}
618
619
const Element *find_closest(const K &p_key) const {
620
if (!_data._root) {
621
return nullptr;
622
}
623
624
const Element *res = _find_closest(p_key);
625
return res;
626
}
627
628
Element *find_closest(const K &p_key) {
629
if (!_data._root) {
630
return nullptr;
631
}
632
633
Element *res = _find_closest(p_key);
634
return res;
635
}
636
637
bool has(const K &p_key) const {
638
return find(p_key) != nullptr;
639
}
640
641
Element *insert(const K &p_key, const V &p_value) {
642
if (!_data._root) {
643
_data._create_root();
644
}
645
return _insert(p_key, p_value);
646
}
647
648
void erase(Element *p_element) {
649
if (!_data._root || !p_element) {
650
return;
651
}
652
653
_erase(p_element);
654
if (_data.size_cache == 0 && _data._root) {
655
_data._free_root();
656
}
657
}
658
659
bool erase(const K &p_key) {
660
if (!_data._root) {
661
return false;
662
}
663
664
Element *e = find(p_key);
665
if (!e) {
666
return false;
667
}
668
669
_erase(e);
670
if (_data.size_cache == 0 && _data._root) {
671
_data._free_root();
672
}
673
return true;
674
}
675
676
const V &operator[](const K &p_key) const {
677
CRASH_COND(!_data._root);
678
const Element *e = find(p_key);
679
CRASH_COND(!e);
680
return e->_data.value;
681
}
682
683
V &operator[](const K &p_key) {
684
if (!_data._root) {
685
_data._create_root();
686
}
687
688
Element *e = find(p_key);
689
if (!e) {
690
e = insert(p_key, V());
691
}
692
693
return e->_data.value;
694
}
695
696
Element *front() const {
697
if (!_data._root) {
698
return nullptr;
699
}
700
701
Element *e = _data._root->left;
702
if (e == _data._nil) {
703
return nullptr;
704
}
705
706
while (e->left != _data._nil) {
707
e = e->left;
708
}
709
710
return e;
711
}
712
713
Element *back() const {
714
if (!_data._root) {
715
return nullptr;
716
}
717
718
Element *e = _data._root->left;
719
if (e == _data._nil) {
720
return nullptr;
721
}
722
723
while (e->right != _data._nil) {
724
e = e->right;
725
}
726
727
return e;
728
}
729
730
inline bool is_empty() const {
731
return _data.size_cache == 0;
732
}
733
inline int size() const {
734
return _data.size_cache;
735
}
736
737
int calculate_depth() const {
738
// used for debug mostly
739
if (!_data._root) {
740
return 0;
741
}
742
743
int max_d = 0;
744
_calculate_depth(_data._root->left, max_d, 0);
745
return max_d;
746
}
747
748
void clear() {
749
if (!_data._root) {
750
return;
751
}
752
753
_cleanup_tree(_data._root->left);
754
_data._root->left = _data._nil;
755
_data.size_cache = 0;
756
_data._free_root();
757
}
758
759
void operator=(const RBMap &p_map) {
760
_copy_from(p_map);
761
}
762
763
RBMap(const RBMap &p_map) {
764
_copy_from(p_map);
765
}
766
767
RBMap(std::initializer_list<KeyValue<K, V>> p_init) {
768
for (const KeyValue<K, V> &E : p_init) {
769
insert(E.key, E.value);
770
}
771
}
772
773
_FORCE_INLINE_ RBMap() {}
774
775
~RBMap() {
776
clear();
777
}
778
};
779
780