mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-21 07:11:16 +00:00
Still working on "tree add" function
* I think the left/right rotates are correct now. Eventually I will rename the members from m_child0/m_child1 to right/left but that ought to be its own commit. * MxAtomId operator= match * Added some more comments as I try to work all this stuff out.
This commit is contained in:
parent
fcfc475eb1
commit
d80b387490
@ -54,13 +54,15 @@ void MxAtomId::Destroy()
|
|||||||
// OFFSET: LEGO1 0x100ad1c0
|
// OFFSET: LEGO1 0x100ad1c0
|
||||||
MxAtomId &MxAtomId::operator=(const MxAtomId &atomId)
|
MxAtomId &MxAtomId::operator=(const MxAtomId &atomId)
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
const char *temp = m_internal;
|
|
||||||
if (m_internal)
|
if (m_internal)
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
if (atomId.m_internal && MxOmni::GetInstance() && AtomIdTree())
|
if (atomId.m_internal && MxOmni::GetInstance() && AtomIdTree()) {
|
||||||
try_to_open(temp, LookupMode_Exact);
|
TreeValue *value = try_to_open(atomId.m_internal, LookupMode_Exact);
|
||||||
|
value->RefCountInc();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_internal = atomId.m_internal;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -87,24 +89,34 @@ TreeValue *MxAtomId::try_to_open(const char *p_str, LookupMode p_mode)
|
|||||||
// should NOT inline
|
// should NOT inline
|
||||||
node = tree->Search(value);
|
node = tree->Search(value);
|
||||||
|
|
||||||
// pointer reuse???
|
TreeNode *t;
|
||||||
TreeNode *ptr_reuse = node;
|
|
||||||
|
|
||||||
// is the node an exact match?
|
// is the node an exact match?
|
||||||
if (tree->m_root == node || TreeValueCompare(value, node->m_value)) {
|
if (tree->m_root == node || TreeValueCompare(value, node->m_value)) {
|
||||||
ptr_reuse = tree->m_root;
|
t = tree->m_root;
|
||||||
}
|
|
||||||
|
|
||||||
ptr_reuse = ptr_reuse->m_child0;
|
|
||||||
if (ptr_reuse == AtomIdTree()->m_root) {
|
|
||||||
delete value;
|
|
||||||
value = ptr_reuse->m_value;
|
|
||||||
} else {
|
} else {
|
||||||
|
t = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LAB_100ad42b
|
if (t->m_child0 != AtomIdTree()->m_root) {
|
||||||
|
delete value;
|
||||||
|
value = node->m_value;
|
||||||
|
} else {
|
||||||
|
// repeat?
|
||||||
|
node = tree->Search(value);
|
||||||
|
TreeNode *pOutput;
|
||||||
|
|
||||||
|
// TODO: this is all wrong, but I wanted to see if
|
||||||
|
// just slapping an approximation of the code down would reveal
|
||||||
|
// the answer.
|
||||||
|
if (AtomIdTree()->m_p2) {
|
||||||
|
tree->Insert(&pOutput, pOutput, node, value);
|
||||||
|
} else {
|
||||||
|
tree->Insert(&pOutput, pOutput, AtomIdTree()->m_root, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LAB_100ad42b
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ TreeValue::~TreeValue()
|
|||||||
// nothing.
|
// nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MxBinaryTree::LeftRotate(TreeNode *x)
|
inline void MxBinaryTree::RightRotate(TreeNode *x)
|
||||||
{
|
{
|
||||||
TreeNode *y = x->m_child1;
|
TreeNode *y = x->m_child1;
|
||||||
x->m_child1 = y->m_child0;
|
x->m_child1 = y->m_child0;
|
||||||
@ -36,7 +36,7 @@ inline void MxBinaryTree::LeftRotate(TreeNode *x)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MxBinaryTree::RightRotate(TreeNode *x)
|
inline void MxBinaryTree::LeftRotate(TreeNode *x)
|
||||||
{
|
{
|
||||||
TreeNode *y = x->m_child0;
|
TreeNode *y = x->m_child0;
|
||||||
x->m_child0 = y->m_child1;
|
x->m_child0 = y->m_child1;
|
||||||
@ -63,38 +63,47 @@ inline void MxBinaryTree::RightRotate(TreeNode *x)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline TreeNode *minimum(TreeNode *p_node)
|
||||||
|
{
|
||||||
|
// horrible. but it has to be this way to
|
||||||
|
// force a non-branching JMP to repeat the loop.
|
||||||
|
while (1) {
|
||||||
|
if (p_node->m_child1 == MxBinaryTree::g_Node_Nil)
|
||||||
|
break;
|
||||||
|
p_node = p_node->m_child1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p_node;
|
||||||
|
}
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100ad480
|
// OFFSET: LEGO1 0x100ad480
|
||||||
void mini_walk(TreeNode* &p_node)
|
void mini_walk(TreeNode* &p_node)
|
||||||
{
|
{
|
||||||
|
// I think this is checking whether this is the tree "root" node
|
||||||
|
// i.e. MxBinaryTree->m_root
|
||||||
|
// The actual root is m_root->parent. There is an intentional loop here.
|
||||||
|
// If it is the "root" node, return the minimum value of the tree.
|
||||||
|
// We have a reference to it at m_root->m_child1.
|
||||||
|
|
||||||
if (p_node->m_color == NODE_COLOR_RED
|
if (p_node->m_color == NODE_COLOR_RED
|
||||||
&& p_node->m_parent->m_parent == p_node) {
|
&& p_node->m_parent->m_parent == p_node) {
|
||||||
p_node = p_node->m_child1;
|
p_node = p_node->m_child1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeNode *t = p_node->m_child0;
|
// successor?
|
||||||
if (t != MxBinaryTree::g_Node_Nil) {
|
if (p_node->m_child0 != MxBinaryTree::g_Node_Nil) {
|
||||||
|
p_node = minimum(p_node->m_child0);
|
||||||
// wonky
|
|
||||||
while (1) {
|
|
||||||
if (t->m_child1 == MxBinaryTree::g_Node_Nil)
|
|
||||||
break;
|
|
||||||
t = t->m_child1;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_node = t;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeNode *u = p_node->m_parent;
|
// p_node->m_child0 *is* NIL, so go up a level and try it
|
||||||
TreeNode *v = p_node;
|
TreeNode *y = p_node->m_parent;
|
||||||
while (u != v) {
|
while (p_node == y->m_child0) {
|
||||||
p_node = u;
|
p_node = y;
|
||||||
v = u;
|
y = y->m_parent;
|
||||||
u = u->m_parent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p_node = u;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100ad4d0
|
// OFFSET: LEGO1 0x100ad4d0
|
||||||
@ -119,14 +128,17 @@ void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_par
|
|||||||
p_parent->m_child1 = node;
|
p_parent->m_child1 = node;
|
||||||
|
|
||||||
if (m_root->m_child1 == p_parent)
|
if (m_root->m_child1 == p_parent)
|
||||||
|
// Set the tree minimum.
|
||||||
m_root->m_child1 = node;
|
m_root->m_child1 = node;
|
||||||
} else {
|
} else {
|
||||||
p_parent->m_child0 = node;
|
p_parent->m_child0 = node;
|
||||||
|
|
||||||
if (m_root != p_parent) {
|
if (m_root != p_parent) {
|
||||||
if (m_root->m_child0 == p_parent)
|
if (m_root->m_child0 == p_parent)
|
||||||
|
// Set the tree maximum.
|
||||||
m_root->m_child0 = node;
|
m_root->m_child0 = node;
|
||||||
} else {
|
} else {
|
||||||
|
// Set the tree minimum and top node.
|
||||||
m_root->m_parent = node;
|
m_root->m_parent = node;
|
||||||
m_root->m_child1 = node;
|
m_root->m_child1 = node;
|
||||||
}
|
}
|
||||||
@ -150,20 +162,6 @@ void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_par
|
|||||||
|
|
||||||
// 100ad5d3
|
// 100ad5d3
|
||||||
if (parent->m_child1 == cur) {
|
if (parent->m_child1 == cur) {
|
||||||
cur = parent;
|
|
||||||
LeftRotate(cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
// LAB_100ad60f
|
|
||||||
cur->m_parent->m_color = NODE_COLOR_BLACK;
|
|
||||||
cur->m_parent->m_parent->m_color = NODE_COLOR_RED;
|
|
||||||
RightRotate(cur->m_parent->m_parent);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// LAB_100ad67f
|
|
||||||
if (uncle->m_color != NODE_COLOR_RED) {
|
|
||||||
if (parent->m_child0 == cur) {
|
|
||||||
cur = parent;
|
cur = parent;
|
||||||
RightRotate(cur);
|
RightRotate(cur);
|
||||||
}
|
}
|
||||||
@ -174,6 +172,20 @@ void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_par
|
|||||||
LeftRotate(cur->m_parent->m_parent);
|
LeftRotate(cur->m_parent->m_parent);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// LAB_100ad67f
|
||||||
|
if (uncle->m_color != NODE_COLOR_RED) {
|
||||||
|
if (parent->m_child0 == cur) {
|
||||||
|
cur = parent;
|
||||||
|
LeftRotate(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LAB_100ad60f
|
||||||
|
cur->m_parent->m_color = NODE_COLOR_BLACK;
|
||||||
|
cur->m_parent->m_parent->m_color = NODE_COLOR_RED;
|
||||||
|
RightRotate(cur->m_parent->m_parent);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LAB_100ad72c
|
// LAB_100ad72c
|
||||||
|
|||||||
@ -47,6 +47,11 @@ inline TreeNode *newTreeNode(TreeNode *p_parent, int p_color)
|
|||||||
// OFFSET: LEGO1 0x100ad120
|
// OFFSET: LEGO1 0x100ad120
|
||||||
inline int TreeValueCompare(TreeValue *&p_val0, TreeValue *&p_val1)
|
inline int TreeValueCompare(TreeValue *&p_val0, TreeValue *&p_val1)
|
||||||
{
|
{
|
||||||
|
// For strcmp, a result greater than 0 means that b > a.
|
||||||
|
// So: for this function, return TRUE if:
|
||||||
|
// * string values are non-equal
|
||||||
|
// * string values are in order: p_val0 < p_val1
|
||||||
|
|
||||||
return strcmp(p_val0->m_str.GetData(), p_val1->m_str.GetData()) > 0;
|
return strcmp(p_val0->m_str.GetData(), p_val1->m_str.GetData()) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user