common: tree: Various updates.

pull/8/head
bunnei 3 years ago
parent 69c2faeb6a
commit 0fdf1d2a60

@ -43,294 +43,265 @@
* The maximum height of a red-black tree is 2lg (n+1). * The maximum height of a red-black tree is 2lg (n+1).
*/ */
#include "common/assert.h" namespace Common::freebsd {
namespace Common { enum class RBColor {
RB_BLACK = 0,
RB_RED = 1,
};
#pragma pack(push, 4)
template <typename T> template <typename T>
class RBHead { class RBEntry {
public: public:
[[nodiscard]] T* Root() { constexpr RBEntry() = default;
return rbh_root;
}
[[nodiscard]] const T* Root() const { [[nodiscard]] constexpr T* Left() {
return rbh_root; return m_rbe_left;
} }
[[nodiscard]] constexpr const T* Left() const {
void SetRoot(T* root) { return m_rbe_left;
rbh_root = root;
} }
[[nodiscard]] bool IsEmpty() const { constexpr void SetLeft(T* e) {
return Root() == nullptr; m_rbe_left = e;
} }
private: [[nodiscard]] constexpr T* Right() {
T* rbh_root = nullptr; return m_rbe_right;
};
enum class EntryColor {
Black,
Red,
};
template <typename T>
class RBEntry {
public:
[[nodiscard]] T* Left() {
return rbe_left;
} }
[[nodiscard]] constexpr const T* Right() const {
[[nodiscard]] const T* Left() const { return m_rbe_right;
return rbe_left;
} }
void SetLeft(T* left) { constexpr void SetRight(T* e) {
rbe_left = left; m_rbe_right = e;
} }
[[nodiscard]] T* Right() { [[nodiscard]] constexpr T* Parent() {
return rbe_right; return m_rbe_parent;
} }
[[nodiscard]] constexpr const T* Parent() const {
[[nodiscard]] const T* Right() const { return m_rbe_parent;
return rbe_right;
} }
void SetRight(T* right) { constexpr void SetParent(T* e) {
rbe_right = right; m_rbe_parent = e;
} }
[[nodiscard]] T* Parent() { [[nodiscard]] constexpr bool IsBlack() const {
return rbe_parent; return m_rbe_color == RBColor::RB_BLACK;
} }
[[nodiscard]] constexpr bool IsRed() const {
[[nodiscard]] const T* Parent() const { return m_rbe_color == RBColor::RB_RED;
return rbe_parent;
} }
[[nodiscard]] constexpr RBColor Color() const {
void SetParent(T* parent) { return m_rbe_color;
rbe_parent = parent;
} }
[[nodiscard]] bool IsBlack() const { constexpr void SetColor(RBColor c) {
return rbe_color == EntryColor::Black; m_rbe_color = c;
} }
[[nodiscard]] bool IsRed() const { private:
return rbe_color == EntryColor::Red; T* m_rbe_left{};
} T* m_rbe_right{};
T* m_rbe_parent{};
RBColor m_rbe_color{RBColor::RB_BLACK};
};
#pragma pack(pop)
[[nodiscard]] EntryColor Color() const { template <typename T>
return rbe_color; struct CheckRBEntry {
} static constexpr bool value = false;
};
template <typename T>
struct CheckRBEntry<RBEntry<T>> {
static constexpr bool value = true;
};
void SetColor(EntryColor color) { template <typename T>
rbe_color = color; concept IsRBEntry = CheckRBEntry<T>::value;
}
template <typename T>
concept HasRBEntry = requires(T& t, const T& ct) {
{ t.GetRBEntry() } -> std::same_as<RBEntry<T>&>;
{ ct.GetRBEntry() } -> std::same_as<const RBEntry<T>&>;
};
template <typename T>
requires HasRBEntry<T>
class RBHead {
private: private:
T* rbe_left = nullptr; T* m_rbh_root = nullptr;
T* rbe_right = nullptr;
T* rbe_parent = nullptr; public:
EntryColor rbe_color{}; [[nodiscard]] constexpr T* Root() {
return m_rbh_root;
}
[[nodiscard]] constexpr const T* Root() const {
return m_rbh_root;
}
constexpr void SetRoot(T* root) {
m_rbh_root = root;
}
[[nodiscard]] constexpr bool IsEmpty() const {
return this->Root() == nullptr;
}
}; };
template <typename Node> template <typename T>
[[nodiscard]] RBEntry<Node>& RB_ENTRY(Node* node) { requires HasRBEntry<T>
return node->GetEntry(); [[nodiscard]] constexpr RBEntry<T>& RB_ENTRY(T* t) {
return t->GetRBEntry();
} }
template <typename T>
template <typename Node> requires HasRBEntry<T>
[[nodiscard]] const RBEntry<Node>& RB_ENTRY(const Node* node) { [[nodiscard]] constexpr const RBEntry<T>& RB_ENTRY(const T* t) {
return node->GetEntry(); return t->GetRBEntry();
} }
template <typename Node> template <typename T>
[[nodiscard]] Node* RB_PARENT(Node* node) { requires HasRBEntry<T>
return RB_ENTRY(node).Parent(); [[nodiscard]] constexpr T* RB_LEFT(T* t) {
return RB_ENTRY(t).Left();
} }
template <typename T>
template <typename Node> requires HasRBEntry<T>
[[nodiscard]] const Node* RB_PARENT(const Node* node) { [[nodiscard]] constexpr const T* RB_LEFT(const T* t) {
return RB_ENTRY(node).Parent(); return RB_ENTRY(t).Left();
} }
template <typename Node> template <typename T>
void RB_SET_PARENT(Node* node, Node* parent) { requires HasRBEntry<T>
return RB_ENTRY(node).SetParent(parent); [[nodiscard]] constexpr T* RB_RIGHT(T* t) {
return RB_ENTRY(t).Right();
} }
template <typename T>
template <typename Node> requires HasRBEntry<T>
[[nodiscard]] Node* RB_LEFT(Node* node) { [[nodiscard]] constexpr const T* RB_RIGHT(const T* t) {
return RB_ENTRY(node).Left(); return RB_ENTRY(t).Right();
} }
template <typename Node> template <typename T>
[[nodiscard]] const Node* RB_LEFT(const Node* node) { requires HasRBEntry<T>
return RB_ENTRY(node).Left(); [[nodiscard]] constexpr T* RB_PARENT(T* t) {
return RB_ENTRY(t).Parent();
} }
template <typename T>
template <typename Node> requires HasRBEntry<T>
void RB_SET_LEFT(Node* node, Node* left) { [[nodiscard]] constexpr const T* RB_PARENT(const T* t) {
return RB_ENTRY(node).SetLeft(left); return RB_ENTRY(t).Parent();
} }
template <typename Node> template <typename T>
[[nodiscard]] Node* RB_RIGHT(Node* node) { requires HasRBEntry<T>
return RB_ENTRY(node).Right(); constexpr void RB_SET_LEFT(T* t, T* e) {
RB_ENTRY(t).SetLeft(e);
} }
template <typename T>
template <typename Node> requires HasRBEntry<T>
[[nodiscard]] const Node* RB_RIGHT(const Node* node) { constexpr void RB_SET_RIGHT(T* t, T* e) {
return RB_ENTRY(node).Right(); RB_ENTRY(t).SetRight(e);
} }
template <typename T>
template <typename Node> requires HasRBEntry<T>
void RB_SET_RIGHT(Node* node, Node* right) { constexpr void RB_SET_PARENT(T* t, T* e) {
return RB_ENTRY(node).SetRight(right); RB_ENTRY(t).SetParent(e);
} }
template <typename Node> template <typename T>
[[nodiscard]] bool RB_IS_BLACK(const Node* node) { requires HasRBEntry<T>
return RB_ENTRY(node).IsBlack(); [[nodiscard]] constexpr bool RB_IS_BLACK(const T* t) {
return RB_ENTRY(t).IsBlack();
} }
template <typename T>
template <typename Node> requires HasRBEntry<T>
[[nodiscard]] bool RB_IS_RED(const Node* node) { [[nodiscard]] constexpr bool RB_IS_RED(const T* t) {
return RB_ENTRY(node).IsRed(); return RB_ENTRY(t).IsRed();
} }
template <typename Node> template <typename T>
[[nodiscard]] EntryColor RB_COLOR(const Node* node) { requires HasRBEntry<T>
return RB_ENTRY(node).Color(); [[nodiscard]] constexpr RBColor RB_COLOR(const T* t) {
return RB_ENTRY(t).Color();
} }
template <typename Node> template <typename T>
void RB_SET_COLOR(Node* node, EntryColor color) { requires HasRBEntry<T>
return RB_ENTRY(node).SetColor(color); constexpr void RB_SET_COLOR(T* t, RBColor c) {
RB_ENTRY(t).SetColor(c);
} }
template <typename Node> template <typename T>
void RB_SET(Node* node, Node* parent) { requires HasRBEntry<T>
auto& entry = RB_ENTRY(node); constexpr void RB_SET(T* elm, T* parent) {
entry.SetParent(parent); auto& rb_entry = RB_ENTRY(elm);
entry.SetLeft(nullptr); rb_entry.SetParent(parent);
entry.SetRight(nullptr); rb_entry.SetLeft(nullptr);
entry.SetColor(EntryColor::Red); rb_entry.SetRight(nullptr);
rb_entry.SetColor(RBColor::RB_RED);
} }
template <typename Node> template <typename T>
void RB_SET_BLACKRED(Node* black, Node* red) { requires HasRBEntry<T>
RB_SET_COLOR(black, EntryColor::Black); constexpr void RB_SET_BLACKRED(T* black, T* red) {
RB_SET_COLOR(red, EntryColor::Red); RB_SET_COLOR(black, RBColor::RB_BLACK);
RB_SET_COLOR(red, RBColor::RB_RED);
} }
template <typename Node> template <typename T>
void RB_ROTATE_LEFT(RBHead<Node>* head, Node* elm, Node*& tmp) { requires HasRBEntry<T>
constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) {
tmp = RB_RIGHT(elm); tmp = RB_RIGHT(elm);
RB_SET_RIGHT(elm, RB_LEFT(tmp)); if (RB_SET_RIGHT(elm, RB_LEFT(tmp)); RB_RIGHT(elm) != nullptr) {
if (RB_RIGHT(elm) != nullptr) {
RB_SET_PARENT(RB_LEFT(tmp), elm); RB_SET_PARENT(RB_LEFT(tmp), elm);
} }
RB_SET_PARENT(tmp, RB_PARENT(elm)); if (RB_SET_PARENT(tmp, RB_PARENT(elm)); RB_PARENT(tmp) != nullptr) {
if (RB_PARENT(tmp) != nullptr) {
if (elm == RB_LEFT(RB_PARENT(elm))) { if (elm == RB_LEFT(RB_PARENT(elm))) {
RB_SET_LEFT(RB_PARENT(elm), tmp); RB_SET_LEFT(RB_PARENT(elm), tmp);
} else { } else {
RB_SET_RIGHT(RB_PARENT(elm), tmp); RB_SET_RIGHT(RB_PARENT(elm), tmp);
} }
} else { } else {
head->SetRoot(tmp); head.SetRoot(tmp);
} }
RB_SET_LEFT(tmp, elm); RB_SET_LEFT(tmp, elm);
RB_SET_PARENT(elm, tmp); RB_SET_PARENT(elm, tmp);
} }
template <typename Node> template <typename T>
void RB_ROTATE_RIGHT(RBHead<Node>* head, Node* elm, Node*& tmp) { requires HasRBEntry<T>
constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) {
tmp = RB_LEFT(elm); tmp = RB_LEFT(elm);
RB_SET_LEFT(elm, RB_RIGHT(tmp)); if (RB_SET_LEFT(elm, RB_RIGHT(tmp)); RB_LEFT(elm) != nullptr) {
if (RB_LEFT(elm) != nullptr) {
RB_SET_PARENT(RB_RIGHT(tmp), elm); RB_SET_PARENT(RB_RIGHT(tmp), elm);
} }
RB_SET_PARENT(tmp, RB_PARENT(elm)); if (RB_SET_PARENT(tmp, RB_PARENT(elm)); RB_PARENT(tmp) != nullptr) {
if (RB_PARENT(tmp) != nullptr) {
if (elm == RB_LEFT(RB_PARENT(elm))) { if (elm == RB_LEFT(RB_PARENT(elm))) {
RB_SET_LEFT(RB_PARENT(elm), tmp); RB_SET_LEFT(RB_PARENT(elm), tmp);
} else { } else {
RB_SET_RIGHT(RB_PARENT(elm), tmp); RB_SET_RIGHT(RB_PARENT(elm), tmp);
} }
} else { } else {
head->SetRoot(tmp); head.SetRoot(tmp);
} }
RB_SET_RIGHT(tmp, elm); RB_SET_RIGHT(tmp, elm);
RB_SET_PARENT(elm, tmp); RB_SET_PARENT(elm, tmp);
} }
template <typename Node> template <typename T>
void RB_INSERT_COLOR(RBHead<Node>* head, Node* elm) { requires HasRBEntry<T>
Node* parent = nullptr; constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) {
Node* tmp = nullptr; T* tmp;
while ((elm == nullptr || RB_IS_BLACK(elm)) && elm != head.Root()) {
while ((parent = RB_PARENT(elm)) != nullptr && RB_IS_RED(parent)) {
Node* gparent = RB_PARENT(parent);
if (parent == RB_LEFT(gparent)) {
tmp = RB_RIGHT(gparent);
if (tmp && RB_IS_RED(tmp)) {
RB_SET_COLOR(tmp, EntryColor::Black);
RB_SET_BLACKRED(parent, gparent);
elm = gparent;
continue;
}
if (RB_RIGHT(parent) == elm) {
RB_ROTATE_LEFT(head, parent, tmp);
tmp = parent;
parent = elm;
elm = tmp;
}
RB_SET_BLACKRED(parent, gparent);
RB_ROTATE_RIGHT(head, gparent, tmp);
} else {
tmp = RB_LEFT(gparent);
if (tmp && RB_IS_RED(tmp)) {
RB_SET_COLOR(tmp, EntryColor::Black);
RB_SET_BLACKRED(parent, gparent);
elm = gparent;
continue;
}
if (RB_LEFT(parent) == elm) {
RB_ROTATE_RIGHT(head, parent, tmp);
tmp = parent;
parent = elm;
elm = tmp;
}
RB_SET_BLACKRED(parent, gparent);
RB_ROTATE_LEFT(head, gparent, tmp);
}
}
RB_SET_COLOR(head->Root(), EntryColor::Black);
}
template <typename Node>
void RB_REMOVE_COLOR(RBHead<Node>* head, Node* parent, Node* elm) {
Node* tmp;
while ((elm == nullptr || RB_IS_BLACK(elm)) && elm != head->Root() && parent != nullptr) {
if (RB_LEFT(parent) == elm) { if (RB_LEFT(parent) == elm) {
tmp = RB_RIGHT(parent); tmp = RB_RIGHT(parent);
if (!tmp) {
ASSERT_MSG(false, "tmp is invalid!");
break;
}
if (RB_IS_RED(tmp)) { if (RB_IS_RED(tmp)) {
RB_SET_BLACKRED(tmp, parent); RB_SET_BLACKRED(tmp, parent);
RB_ROTATE_LEFT(head, parent, tmp); RB_ROTATE_LEFT(head, parent, tmp);
@ -339,29 +310,29 @@ void RB_REMOVE_COLOR(RBHead<Node>* head, Node* parent, Node* elm) {
if ((RB_LEFT(tmp) == nullptr || RB_IS_BLACK(RB_LEFT(tmp))) && if ((RB_LEFT(tmp) == nullptr || RB_IS_BLACK(RB_LEFT(tmp))) &&
(RB_RIGHT(tmp) == nullptr || RB_IS_BLACK(RB_RIGHT(tmp)))) { (RB_RIGHT(tmp) == nullptr || RB_IS_BLACK(RB_RIGHT(tmp)))) {
RB_SET_COLOR(tmp, EntryColor::Red); RB_SET_COLOR(tmp, RBColor::RB_RED);
elm = parent; elm = parent;
parent = RB_PARENT(elm); parent = RB_PARENT(elm);
} else { } else {
if (RB_RIGHT(tmp) == nullptr || RB_IS_BLACK(RB_RIGHT(tmp))) { if (RB_RIGHT(tmp) == nullptr || RB_IS_BLACK(RB_RIGHT(tmp))) {
Node* oleft; T* oleft;
if ((oleft = RB_LEFT(tmp)) != nullptr) { if ((oleft = RB_LEFT(tmp)) != nullptr) {
RB_SET_COLOR(oleft, EntryColor::Black); RB_SET_COLOR(oleft, RBColor::RB_BLACK);
} }
RB_SET_COLOR(tmp, EntryColor::Red); RB_SET_COLOR(tmp, RBColor::RB_RED);
RB_ROTATE_RIGHT(head, tmp, oleft); RB_ROTATE_RIGHT(head, tmp, oleft);
tmp = RB_RIGHT(parent); tmp = RB_RIGHT(parent);
} }
RB_SET_COLOR(tmp, RB_COLOR(parent)); RB_SET_COLOR(tmp, RB_COLOR(parent));
RB_SET_COLOR(parent, EntryColor::Black); RB_SET_COLOR(parent, RBColor::RB_BLACK);
if (RB_RIGHT(tmp)) { if (RB_RIGHT(tmp)) {
RB_SET_COLOR(RB_RIGHT(tmp), EntryColor::Black); RB_SET_COLOR(RB_RIGHT(tmp), RBColor::RB_BLACK);
} }
RB_ROTATE_LEFT(head, parent, tmp); RB_ROTATE_LEFT(head, parent, tmp);
elm = head->Root(); elm = head.Root();
break; break;
} }
} else { } else {
@ -372,68 +343,56 @@ void RB_REMOVE_COLOR(RBHead<Node>* head, Node* parent, Node* elm) {
tmp = RB_LEFT(parent); tmp = RB_LEFT(parent);
} }
if (!tmp) {
ASSERT_MSG(false, "tmp is invalid!");
break;
}
if ((RB_LEFT(tmp) == nullptr || RB_IS_BLACK(RB_LEFT(tmp))) && if ((RB_LEFT(tmp) == nullptr || RB_IS_BLACK(RB_LEFT(tmp))) &&
(RB_RIGHT(tmp) == nullptr || RB_IS_BLACK(RB_RIGHT(tmp)))) { (RB_RIGHT(tmp) == nullptr || RB_IS_BLACK(RB_RIGHT(tmp)))) {
RB_SET_COLOR(tmp, EntryColor::Red); RB_SET_COLOR(tmp, RBColor::RB_RED);
elm = parent; elm = parent;
parent = RB_PARENT(elm); parent = RB_PARENT(elm);
} else { } else {
if (RB_LEFT(tmp) == nullptr || RB_IS_BLACK(RB_LEFT(tmp))) { if (RB_LEFT(tmp) == nullptr || RB_IS_BLACK(RB_LEFT(tmp))) {
Node* oright; T* oright;
if ((oright = RB_RIGHT(tmp)) != nullptr) { if ((oright = RB_RIGHT(tmp)) != nullptr) {
RB_SET_COLOR(oright, EntryColor::Black); RB_SET_COLOR(oright, RBColor::RB_BLACK);
} }
RB_SET_COLOR(tmp, EntryColor::Red); RB_SET_COLOR(tmp, RBColor::RB_RED);
RB_ROTATE_LEFT(head, tmp, oright); RB_ROTATE_LEFT(head, tmp, oright);
tmp = RB_LEFT(parent); tmp = RB_LEFT(parent);
} }
RB_SET_COLOR(tmp, RB_COLOR(parent)); RB_SET_COLOR(tmp, RB_COLOR(parent));
RB_SET_COLOR(parent, EntryColor::Black); RB_SET_COLOR(parent, RBColor::RB_BLACK);
if (RB_LEFT(tmp)) { if (RB_LEFT(tmp)) {
RB_SET_COLOR(RB_LEFT(tmp), EntryColor::Black); RB_SET_COLOR(RB_LEFT(tmp), RBColor::RB_BLACK);
} }
RB_ROTATE_RIGHT(head, parent, tmp); RB_ROTATE_RIGHT(head, parent, tmp);
elm = head->Root(); elm = head.Root();
break; break;
} }
} }
} }
if (elm) { if (elm) {
RB_SET_COLOR(elm, EntryColor::Black); RB_SET_COLOR(elm, RBColor::RB_BLACK);
} }
} }
template <typename Node> template <typename T>
Node* RB_REMOVE(RBHead<Node>* head, Node* elm) { requires HasRBEntry<T>
Node* child = nullptr; constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) {
Node* parent = nullptr; T* child = nullptr;
Node* old = elm; T* parent = nullptr;
EntryColor color{}; T* old = elm;
RBColor color = RBColor::RB_BLACK;
const auto finalize = [&] {
if (color == EntryColor::Black) {
RB_REMOVE_COLOR(head, parent, child);
}
return old;
};
if (RB_LEFT(elm) == nullptr) { if (RB_LEFT(elm) == nullptr) {
child = RB_RIGHT(elm); child = RB_RIGHT(elm);
} else if (RB_RIGHT(elm) == nullptr) { } else if (RB_RIGHT(elm) == nullptr) {
child = RB_LEFT(elm); child = RB_LEFT(elm);
} else { } else {
Node* left; T* left;
elm = RB_RIGHT(elm); elm = RB_RIGHT(elm);
while ((left = RB_LEFT(elm)) != nullptr) { while ((left = RB_LEFT(elm)) != nullptr) {
elm = left; elm = left;
@ -446,6 +405,7 @@ Node* RB_REMOVE(RBHead<Node>* head, Node* elm) {
if (child) { if (child) {
RB_SET_PARENT(child, parent); RB_SET_PARENT(child, parent);
} }
if (parent) { if (parent) {
if (RB_LEFT(parent) == elm) { if (RB_LEFT(parent) == elm) {
RB_SET_LEFT(parent, child); RB_SET_LEFT(parent, child);
@ -453,14 +413,14 @@ Node* RB_REMOVE(RBHead<Node>* head, Node* elm) {
RB_SET_RIGHT(parent, child); RB_SET_RIGHT(parent, child);
} }
} else { } else {
head->SetRoot(child); head.SetRoot(child);
} }
if (RB_PARENT(elm) == old) { if (RB_PARENT(elm) == old) {
parent = elm; parent = elm;
} }
elm->SetEntry(old->GetEntry()); elm->SetRBEntry(old->GetRBEntry());
if (RB_PARENT(old)) { if (RB_PARENT(old)) {
if (RB_LEFT(RB_PARENT(old)) == old) { if (RB_LEFT(RB_PARENT(old)) == old) {
@ -469,17 +429,24 @@ Node* RB_REMOVE(RBHead<Node>* head, Node* elm) {
RB_SET_RIGHT(RB_PARENT(old), elm); RB_SET_RIGHT(RB_PARENT(old), elm);
} }
} else { } else {
head->SetRoot(elm); head.SetRoot(elm);
} }
RB_SET_PARENT(RB_LEFT(old), elm); RB_SET_PARENT(RB_LEFT(old), elm);
if (RB_RIGHT(old)) { if (RB_RIGHT(old)) {
RB_SET_PARENT(RB_RIGHT(old), elm); RB_SET_PARENT(RB_RIGHT(old), elm);
} }
if (parent) { if (parent) {
left = parent; left = parent;
} }
return finalize(); if (color == RBColor::RB_BLACK) {
RB_REMOVE_COLOR(head, parent, child);
}
return old;
} }
parent = RB_PARENT(elm); parent = RB_PARENT(elm);
@ -495,17 +462,69 @@ Node* RB_REMOVE(RBHead<Node>* head, Node* elm) {
RB_SET_RIGHT(parent, child); RB_SET_RIGHT(parent, child);
} }
} else { } else {
head->SetRoot(child); head.SetRoot(child);
}
if (color == RBColor::RB_BLACK) {
RB_REMOVE_COLOR(head, parent, child);
}
return old;
}
template <typename T>
requires HasRBEntry<T>
constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) {
T *parent = nullptr, *tmp = nullptr;
while ((parent = RB_PARENT(elm)) != nullptr && RB_IS_RED(parent)) {
T* gparent = RB_PARENT(parent);
if (parent == RB_LEFT(gparent)) {
tmp = RB_RIGHT(gparent);
if (tmp && RB_IS_RED(tmp)) {
RB_SET_COLOR(tmp, RBColor::RB_BLACK);
RB_SET_BLACKRED(parent, gparent);
elm = gparent;
continue;
}
if (RB_RIGHT(parent) == elm) {
RB_ROTATE_LEFT(head, parent, tmp);
tmp = parent;
parent = elm;
elm = tmp;
}
RB_SET_BLACKRED(parent, gparent);
RB_ROTATE_RIGHT(head, gparent, tmp);
} else {
tmp = RB_LEFT(gparent);
if (tmp && RB_IS_RED(tmp)) {
RB_SET_COLOR(tmp, RBColor::RB_BLACK);
RB_SET_BLACKRED(parent, gparent);
elm = gparent;
continue;
}
if (RB_LEFT(parent) == elm) {
RB_ROTATE_RIGHT(head, parent, tmp);
tmp = parent;
parent = elm;
elm = tmp;
}
RB_SET_BLACKRED(parent, gparent);
RB_ROTATE_LEFT(head, gparent, tmp);
}
} }
return finalize(); RB_SET_COLOR(head.Root(), RBColor::RB_BLACK);
} }
// Inserts a node into the RB tree template <typename T, typename Compare>
template <typename Node, typename CompareFunction> requires HasRBEntry<T>
Node* RB_INSERT(RBHead<Node>* head, Node* elm, CompareFunction cmp) { constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) {
Node* parent = nullptr; T* parent = nullptr;
Node* tmp = head->Root(); T* tmp = head.Root();
int comp = 0; int comp = 0;
while (tmp) { while (tmp) {
@ -529,17 +548,17 @@ Node* RB_INSERT(RBHead<Node>* head, Node* elm, CompareFunction cmp) {
RB_SET_RIGHT(parent, elm); RB_SET_RIGHT(parent, elm);
} }
} else { } else {
head->SetRoot(elm); head.SetRoot(elm);
} }
RB_INSERT_COLOR(head, elm); RB_INSERT_COLOR(head, elm);
return nullptr; return nullptr;
} }
// Finds the node with the same key as elm template <typename T, typename Compare>
template <typename Node, typename CompareFunction> requires HasRBEntry<T>
Node* RB_FIND(RBHead<Node>* head, Node* elm, CompareFunction cmp) { constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) {
Node* tmp = head->Root(); T* tmp = head.Root();
while (tmp) { while (tmp) {
const int comp = cmp(elm, tmp); const int comp = cmp(elm, tmp);
@ -555,11 +574,11 @@ Node* RB_FIND(RBHead<Node>* head, Node* elm, CompareFunction cmp) {
return nullptr; return nullptr;
} }
// Finds the first node greater than or equal to the search key template <typename T, typename Compare>
template <typename Node, typename CompareFunction> requires HasRBEntry<T>
Node* RB_NFIND(RBHead<Node>* head, Node* elm, CompareFunction cmp) { constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) {
Node* tmp = head->Root(); T* tmp = head.Root();
Node* res = nullptr; T* res = nullptr;
while (tmp) { while (tmp) {
const int comp = cmp(elm, tmp); const int comp = cmp(elm, tmp);
@ -576,13 +595,13 @@ Node* RB_NFIND(RBHead<Node>* head, Node* elm, CompareFunction cmp) {
return res; return res;
} }
// Finds the node with the same key as lelm template <typename T, typename U, typename Compare>
template <typename Node, typename CompareFunction> requires HasRBEntry<T>
Node* RB_FIND_LIGHT(RBHead<Node>* head, const void* lelm, CompareFunction lcmp) { constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
Node* tmp = head->Root(); T* tmp = head.Root();
while (tmp) { while (tmp) {
const int comp = lcmp(lelm, tmp); const int comp = cmp(key, tmp);
if (comp < 0) { if (comp < 0) {
tmp = RB_LEFT(tmp); tmp = RB_LEFT(tmp);
} else if (comp > 0) { } else if (comp > 0) {
@ -595,14 +614,14 @@ Node* RB_FIND_LIGHT(RBHead<Node>* head, const void* lelm, CompareFunction lcmp)
return nullptr; return nullptr;
} }
// Finds the first node greater than or equal to the search key template <typename T, typename U, typename Compare>
template <typename Node, typename CompareFunction> requires HasRBEntry<T>
Node* RB_NFIND_LIGHT(RBHead<Node>* head, const void* lelm, CompareFunction lcmp) { constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
Node* tmp = head->Root(); T* tmp = head.Root();
Node* res = nullptr; T* res = nullptr;
while (tmp) { while (tmp) {
const int comp = lcmp(lelm, tmp); const int comp = cmp(key, tmp);
if (comp < 0) { if (comp < 0) {
res = tmp; res = tmp;
tmp = RB_LEFT(tmp); tmp = RB_LEFT(tmp);
@ -616,8 +635,43 @@ Node* RB_NFIND_LIGHT(RBHead<Node>* head, const void* lelm, CompareFunction lcmp)
return res; return res;
} }
template <typename Node> template <typename T, typename Compare>
Node* RB_NEXT(Node* elm) { requires HasRBEntry<T>
constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) {
T* tmp = head.Root();
while (true) {
const int comp = cmp(elm, tmp);
if (comp < 0) {
tmp = RB_LEFT(tmp);
} else if (comp > 0) {
tmp = RB_RIGHT(tmp);
} else {
return tmp;
}
}
}
template <typename T, typename U, typename Compare>
requires HasRBEntry<T>
constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) {
T* tmp = head.Root();
while (true) {
const int comp = cmp(key, tmp);
if (comp < 0) {
tmp = RB_LEFT(tmp);
} else if (comp > 0) {
tmp = RB_RIGHT(tmp);
} else {
return tmp;
}
}
}
template <typename T>
requires HasRBEntry<T>
constexpr T* RB_NEXT(T* elm) {
if (RB_RIGHT(elm)) { if (RB_RIGHT(elm)) {
elm = RB_RIGHT(elm); elm = RB_RIGHT(elm);
while (RB_LEFT(elm)) { while (RB_LEFT(elm)) {
@ -636,8 +690,9 @@ Node* RB_NEXT(Node* elm) {
return elm; return elm;
} }
template <typename Node> template <typename T>
Node* RB_PREV(Node* elm) { requires HasRBEntry<T>
constexpr T* RB_PREV(T* elm) {
if (RB_LEFT(elm)) { if (RB_LEFT(elm)) {
elm = RB_LEFT(elm); elm = RB_LEFT(elm);
while (RB_RIGHT(elm)) { while (RB_RIGHT(elm)) {
@ -656,30 +711,32 @@ Node* RB_PREV(Node* elm) {
return elm; return elm;
} }
template <typename Node> template <typename T>
Node* RB_MINMAX(RBHead<Node>* head, bool is_min) { requires HasRBEntry<T>
Node* tmp = head->Root(); constexpr T* RB_MIN(RBHead<T>& head) {
Node* parent = nullptr; T* tmp = head.Root();
T* parent = nullptr;
while (tmp) { while (tmp) {
parent = tmp; parent = tmp;
if (is_min) { tmp = RB_LEFT(tmp);
tmp = RB_LEFT(tmp);
} else {
tmp = RB_RIGHT(tmp);
}
} }
return parent; return parent;
} }
template <typename Node> template <typename T>
Node* RB_MIN(RBHead<Node>* head) { requires HasRBEntry<T>
return RB_MINMAX(head, true); constexpr T* RB_MAX(RBHead<T>& head) {
} T* tmp = head.Root();
T* parent = nullptr;
template <typename Node> while (tmp) {
Node* RB_MAX(RBHead<Node>* head) { parent = tmp;
return RB_MINMAX(head, false); tmp = RB_RIGHT(tmp);
}
return parent;
} }
} // namespace Common
} // namespace Common::freebsd

Loading…
Cancel
Save