Node rotate inline functions are better, added more code everywhere else

This commit is contained in:
disinvite 2023-07-25 22:46:54 -04:00
parent 3ae3d2fe20
commit fcfc475eb1
4 changed files with 106 additions and 67 deletions

View File

@ -18,13 +18,50 @@ MxAtomId::MxAtomId(const char *p_str, LookupMode p_mode)
// OFFSET: LEGO1 0x100acfd0 // OFFSET: LEGO1 0x100acfd0
MxAtomId::~MxAtomId() MxAtomId::~MxAtomId()
{ {
// TODO Destroy();
}
// OFFSET: LEGO1 0x100acfe0
void MxAtomId::Destroy()
{
if (*m_internal == '\0')
return;
if (!MxOmni::GetInstance())
return;
if (!AtomIdTree())
return;
TreeValue value = TreeValue(m_internal);
TreeValue *p = &value;
// 100ad052
MxBinaryTree *tree = AtomIdTree();
TreeNode *root = tree->m_root;
// should inline Search but NOT TreeValueCompare
TreeNode *node = tree->Search(p);
TreeNode *ass = node;
if (node == root->m_parent || TreeValueCompare(p, node->m_value)) {
ass = root->m_parent;
}
node->m_value->RefCountDec();
} }
// OFFSET: LEGO1 0x100ad1c0 // OFFSET: LEGO1 0x100ad1c0
MxAtomId &MxAtomId::operator=(const MxAtomId &id) MxAtomId &MxAtomId::operator=(const MxAtomId &atomId)
{ {
// TODO // TODO
const char *temp = m_internal;
if (m_internal)
Destroy();
if (atomId.m_internal && MxOmni::GetInstance() && AtomIdTree())
try_to_open(temp, LookupMode_Exact);
return *this; return *this;
} }
@ -44,16 +81,17 @@ TreeValue *MxAtomId::try_to_open(const char *p_str, LookupMode p_mode)
break; break;
} }
// LAB_100ad2a1
MxBinaryTree *tree = AtomIdTree(); MxBinaryTree *tree = AtomIdTree();
// get the closest node that matches the given value // get the closest node that matches the given value
// should NOT inline
node = tree->Search(value); node = tree->Search(value);
// pointer reuse??? // pointer reuse???
TreeNode *ptr_reuse = node; TreeNode *ptr_reuse = node;
// is the node an exact match? // is the node an exact match?
if (tree->m_root == node || if (tree->m_root == node || TreeValueCompare(value, node->m_value)) {
strcmp(value->m_str.GetData(), node->m_value->m_str.GetData()) > 0) {
ptr_reuse = tree->m_root; ptr_reuse = tree->m_root;
} }
@ -70,3 +108,10 @@ TreeValue *MxAtomId::try_to_open(const char *p_str, LookupMode p_mode)
return value; return value;
} }
// OFFSET: LEGO1 0x100ad7e0
void MxAtomId::Clear()
{
Destroy();
m_internal = NULL;
}

View File

@ -33,6 +33,8 @@ class MxAtomId
// TODO: belongs here? // TODO: belongs here?
TreeValue *try_to_open(const char *, LookupMode); TreeValue *try_to_open(const char *, LookupMode);
void Destroy();
void Clear();
private: private:
const char *m_internal; const char *m_internal;

View File

@ -3,6 +3,12 @@
// 0x101013f0 // 0x101013f0
TreeNode *MxBinaryTree::g_Node_Nil = NULL; TreeNode *MxBinaryTree::g_Node_Nil = NULL;
// OFFSET: LEGO1 0x100ad170
TreeValue::~TreeValue()
{
// nothing.
}
inline void MxBinaryTree::LeftRotate(TreeNode *x) inline void MxBinaryTree::LeftRotate(TreeNode *x)
{ {
TreeNode *y = x->m_child1; TreeNode *y = x->m_child1;
@ -14,23 +20,22 @@ inline void MxBinaryTree::LeftRotate(TreeNode *x)
y->m_parent = x->m_parent; y->m_parent = x->m_parent;
if (m_root->m_parent != x) { if (m_root->m_parent != x) {
if (x == x->m_parent->m_child0) { if (x != x->m_parent->m_child0) {
x->m_parent->m_child0 = y;
y->m_child0 = x; //?
x->m_parent = y; //?
} else {
x->m_parent->m_child1 = y; x->m_parent->m_child1 = y;
y->m_child1 = x; //? y->m_child0 = x;
x->m_parent = y; //? x->m_parent = y;
} else {
x->m_parent->m_child0 = y;
y->m_child0 = x;
x->m_parent = y;
} }
} else { } else {
// ? m_root->m_parent->m_child0 = y;
y->m_child0 = x; y->m_child0 = x;
x->m_parent = y; x->m_parent = y;
} }
} }
inline void MxBinaryTree::RightRotate(TreeNode *x) inline void MxBinaryTree::RightRotate(TreeNode *x)
{ {
TreeNode *y = x->m_child0; TreeNode *y = x->m_child0;
@ -42,17 +47,17 @@ inline void MxBinaryTree::RightRotate(TreeNode *x)
y->m_parent = x->m_parent; y->m_parent = x->m_parent;
if (m_root->m_parent != x) { if (m_root->m_parent != x) {
if (x == x->m_parent->m_child1) { if (x != x->m_parent->m_child1) {
x->m_parent->m_child1 = y;
y->m_child1 = x; //?
x->m_parent = y; //?
} else {
x->m_parent->m_child0 = y; x->m_parent->m_child0 = y;
y->m_child0 = x; //? y->m_child1 = x;
x->m_parent = y; //? x->m_parent = y;
} else {
x->m_parent->m_child1 = y;
y->m_child1 = x;
x->m_parent = y;
} }
} else { } else {
//? m_root->m_parent->m_child1 = y;
y->m_child1 = x; y->m_child1 = x;
x->m_parent = y; x->m_parent = y;
} }
@ -93,26 +98,24 @@ void mini_walk(TreeNode* &p_node)
} }
// OFFSET: LEGO1 0x100ad4d0 // OFFSET: LEGO1 0x100ad4d0
void MxBinaryTree::FUN_100ad4d0(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_parent, TreeValue *&p_value) void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_parent, TreeValue *&p_value)
{ {
TreeNode *node = newTreeNode(p_parent, NODE_COLOR_RED); TreeNode *node = newTreeNode(p_parent, NODE_COLOR_RED);
node->m_child0 = g_Node_Nil; node->m_child0 = g_Node_Nil;
node->m_child1 = g_Node_Nil; node->m_child1 = g_Node_Nil;
// TODO: ??? // TODO: ???
if (node->m_value) { if (&node->m_value)
node->m_value = p_value; node->m_value = p_value;
}
this->m_p3++; // node count? this->m_nodeCount++;
// if tree is NOT empty // if tree is NOT empty
// if param_2 is tree_nil (always true I think?) // if param_2 is tree_nil (always true I think?)
// //
if (this->m_root != p_parent if (m_root != p_parent
&& p_leaf == MxBinaryTree::g_Node_Nil && p_leaf == MxBinaryTree::g_Node_Nil
&& strcmp(p_value->m_str.GetData(), && TreeValueCompare(p_value, p_parent->m_value)) {
p_parent->m_value->m_str.GetData()) <= 0) {
p_parent->m_child1 = node; p_parent->m_child1 = node;
if (m_root->m_child1 == p_parent) if (m_root->m_child1 == p_parent)
@ -120,8 +123,9 @@ void MxBinaryTree::FUN_100ad4d0(TreeNode **p_output, TreeNode *p_leaf, TreeNode
} else { } else {
p_parent->m_child0 = node; p_parent->m_child0 = node;
if (m_root != p_parent && m_root->m_child0 == p_parent) { if (m_root != p_parent) {
m_root->m_child0 = p_parent; if (m_root->m_child0 == p_parent)
m_root->m_child0 = node;
} else { } else {
m_root->m_parent = node; m_root->m_parent = node;
m_root->m_child1 = node; m_root->m_child1 = node;
@ -129,7 +133,7 @@ void MxBinaryTree::FUN_100ad4d0(TreeNode **p_output, TreeNode *p_leaf, TreeNode
} }
// LAB_100ad593 // LAB_100ad593
// rebalance?? // rebalance the tree
TreeNode *cur = node; TreeNode *cur = node;
while (m_root->m_parent != cur) { while (m_root->m_parent != cur) {
TreeNode *parent = cur->m_parent; TreeNode *parent = cur->m_parent;
@ -137,12 +141,10 @@ void MxBinaryTree::FUN_100ad4d0(TreeNode **p_output, TreeNode *p_leaf, TreeNode
if (parent->m_color != NODE_COLOR_RED) if (parent->m_color != NODE_COLOR_RED)
break; break;
TreeNode *grandparent = parent->m_parent; TreeNode *uncle = parent->m_parent->m_child0;
TreeNode *uncle = grandparent->m_child0;
if (uncle == parent) { if (uncle == parent) {
// wrong uncle // wrong uncle
uncle = grandparent->m_child1; uncle = parent->m_parent->m_child1;
if (uncle->m_color != NODE_COLOR_RED) { if (uncle->m_color != NODE_COLOR_RED) {
@ -150,23 +152,6 @@ void MxBinaryTree::FUN_100ad4d0(TreeNode **p_output, TreeNode *p_leaf, TreeNode
if (parent->m_child1 == cur) { if (parent->m_child1 == cur) {
cur = parent; cur = parent;
LeftRotate(cur); LeftRotate(cur);
// rotate.
/*
parent->m_child1 = parent->m_child1->m_child0;
// 100ad5e2
if (parent->m_child1 != g_Node_Nil)
parent->m_child1->m_parent = cur;
parent->m_child1->m_parent = grandparent;
if (m_root->m_parent == cur || grandparent->m_child0 == cur)
grandparent->m_child1 = parent;
else
grandparent->m_child0 = parent;
parent->m_child0 = cur;
grandparent->m_child0 = parent;
*/
} }
// LAB_100ad60f // LAB_100ad60f
@ -210,10 +195,7 @@ TreeNode *MxBinaryTree::Search(TreeValue*& p_value)
TreeNode *t_node = node_match->m_parent; TreeNode *t_node = node_match->m_parent;
while (t_node != g_Node_Nil) { while (t_node != g_Node_Nil) {
int result = strcmp(t_node->m_value->m_str.GetData(), p_value->m_str.GetData()); if (!TreeValueCompare(t_node->m_value, p_value)) {
if (result <= 0) {
// if strings equal or less than search string
// closest match? // closest match?
// it either does match or is where we will insert the new node. // it either does match or is where we will insert the new node.
node_match = t_node; node_match = t_node;

View File

@ -15,6 +15,7 @@ class TreeValue {
m_str = p_str; m_str = p_str;
m_t0 = 0; m_t0 = 0;
} }
~TreeValue();
void RefCountInc(); void RefCountInc();
void RefCountDec(); void RefCountDec();
@ -27,12 +28,6 @@ class TreeValue {
// SIZE 0x14 // SIZE 0x14
class TreeNode { class TreeNode {
public: public:
TreeNode(TreeNode *p_parent, int p_color)
{
m_parent = p_parent;
m_color = p_color;
}
TreeNode *m_child0; // +0 // string sorts after TreeNode *m_child0; // +0 // string sorts after
TreeNode *m_parent; // +4 // parent node TreeNode *m_parent; // +4 // parent node
TreeNode *m_child1; // +8 // string sorts before TreeNode *m_child1; // +8 // string sorts before
@ -40,6 +35,21 @@ class TreeNode {
int m_color; // +10 // BLACK or RED. int m_color; // +10 // BLACK or RED.
}; };
// TODO: helper to avoid using a non-default constructor
inline TreeNode *newTreeNode(TreeNode *p_parent, int p_color)
{
TreeNode *t = new TreeNode();
t->m_parent = p_parent;
t->m_color = p_color;
return t;
}
// OFFSET: LEGO1 0x100ad120
inline int TreeValueCompare(TreeValue *&p_val0, TreeValue *&p_val1)
{
return strcmp(p_val0->m_str.GetData(), p_val1->m_str.GetData()) > 0;
}
// SIZE 0x10 // SIZE 0x10
class MxBinaryTree class MxBinaryTree
{ {
@ -59,13 +69,13 @@ class MxBinaryTree
void LeftRotate(TreeNode *); void LeftRotate(TreeNode *);
void RightRotate(TreeNode *); void RightRotate(TreeNode *);
void FUN_100ad4d0(TreeNode **, TreeNode *, TreeNode *, TreeValue *&); void Insert(TreeNode **, TreeNode *, TreeNode *, TreeValue *&);
TreeNode *Search(TreeValue *&); TreeNode *Search(TreeValue *&);
int m_p0; // +0 int m_p0; // +0
TreeNode *m_root; // +4 TreeNode *m_root; // +4
int m_p2; // +8 int m_p2; // +8
int m_p3; // +c int m_nodeCount; // +c
}; };
#endif //MXBINARYTREE_H #endif //MXBINARYTREE_H