mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 12:40:33 +00:00
[RTL]
Implemenet SwapSplayLinks, return 'NewElement' correctly when inserting. Thanks to Alex Ionescu for helping out with this patch. svn path=/trunk/; revision=53015
This commit is contained in:
parent
f1f448e2ba
commit
a90824eeae
2 changed files with 125 additions and 3 deletions
|
@ -213,7 +213,7 @@ RtlInsertElementGenericTableFull(IN PRTL_GENERIC_TABLE Table,
|
||||||
Table->TableRoot = RtlSplay(NewNode);
|
Table->TableRoot = RtlSplay(NewNode);
|
||||||
|
|
||||||
/* Return status */
|
/* Return status */
|
||||||
if (NewElement) *NewElement = (SearchResult == TableFoundNode);
|
if (NewElement) *NewElement = (SearchResult != TableFoundNode);
|
||||||
|
|
||||||
/* Return pointer to user data */
|
/* Return pointer to user data */
|
||||||
return &((PTABLE_ENTRY_HEADER)NewNode)->UserData;
|
return &((PTABLE_ENTRY_HEADER)NewNode)->UserData;
|
||||||
|
@ -300,7 +300,7 @@ RtlDeleteElementGenericTable(IN PRTL_GENERIC_TABLE Table,
|
||||||
|
|
||||||
/* Get the splay links and table search result immediately */
|
/* Get the splay links and table search result immediately */
|
||||||
Result = RtlpFindGenericTableNodeOrParent(Table, Buffer, &NodeOrParent);
|
Result = RtlpFindGenericTableNodeOrParent(Table, Buffer, &NodeOrParent);
|
||||||
if ((Result == TableEmptyTree) || (Result != TableFoundNode))
|
if (Result != TableFoundNode)
|
||||||
{
|
{
|
||||||
/* Nothing to delete */
|
/* Nothing to delete */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -13,13 +13,134 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
//#define VERIFY_SWAP_SPLAY_LINKS
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
FixupChildLinks(PRTL_SPLAY_LINKS Links, BOOLEAN Root, BOOLEAN LeftChild)
|
||||||
|
{
|
||||||
|
if (RtlLeftChild(Links)) {
|
||||||
|
RtlInsertAsLeftChild(Links, RtlLeftChild(Links));
|
||||||
|
}
|
||||||
|
if (RtlRightChild(Links)) {
|
||||||
|
RtlInsertAsRightChild(Links, RtlRightChild(Links));
|
||||||
|
}
|
||||||
|
if (!Root) {
|
||||||
|
if (LeftChild) {
|
||||||
|
RtlInsertAsLeftChild(RtlParent(Links), Links);
|
||||||
|
} else {
|
||||||
|
RtlInsertAsRightChild(RtlParent(Links), Links);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Given the tree:
|
||||||
|
D
|
||||||
|
B F
|
||||||
|
A C E G
|
||||||
|
|
||||||
|
Swap(Q,S):
|
||||||
|
|
||||||
|
Q S Q.P Q.L Q.R S.P S.L S.R
|
||||||
|
A C S.P S.L S.R Q.P Q.L Q.R
|
||||||
|
B A S S.L S.R Q.P Q Q.R
|
||||||
|
B C S S.L S.R Q.P Q.L Q
|
||||||
|
D A S.P S.L S.R S Q.L Q.R
|
||||||
|
D B S S.L S.R S Q Q.R
|
||||||
|
D F S S.L S.R S Q.L Q
|
||||||
|
|
||||||
|
When Q is the immediate parent of S,
|
||||||
|
Set Q's parent to S, and the proper child ptr of S to Q
|
||||||
|
When Q is the root,
|
||||||
|
Set S's parent to S
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
VOID
|
VOID
|
||||||
SwapSplayLinks(PRTL_SPLAY_LINKS LinkA,
|
SwapSplayLinks(PRTL_SPLAY_LINKS LinkA,
|
||||||
PRTL_SPLAY_LINKS LinkB)
|
PRTL_SPLAY_LINKS LinkB)
|
||||||
{
|
{
|
||||||
DPRINT1("UNIMPLEMENTED!\n");
|
if (RtlParent(LinkA) == LinkB || RtlIsRoot(LinkB)) {
|
||||||
|
PRTL_SPLAY_LINKS Tmp = LinkA;
|
||||||
|
LinkA = LinkB;
|
||||||
|
LinkB = Tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
RTL_SPLAY_LINKS Ta = *LinkA, Tb = *LinkB;
|
||||||
|
BOOLEAN RootA = RtlIsRoot(LinkA),
|
||||||
|
LeftA = RtlIsLeftChild(LinkA),
|
||||||
|
LeftB = RtlIsLeftChild(LinkB);
|
||||||
|
*LinkB = Ta; *LinkA = Tb;
|
||||||
|
|
||||||
|
// A was parent of B is a special case: A->Parent is now B
|
||||||
|
if (RtlParent(&Tb) == LinkA) {
|
||||||
|
if (!RootA) {
|
||||||
|
if (LeftA) {
|
||||||
|
RtlInsertAsLeftChild(RtlParent(&Ta), LinkB);
|
||||||
|
} else {
|
||||||
|
RtlInsertAsRightChild(RtlParent(&Ta), LinkB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (LeftB) {
|
||||||
|
RtlInsertAsLeftChild(LinkB, LinkA);
|
||||||
|
} else {
|
||||||
|
RtlInsertAsRightChild(LinkB, LinkA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FixupChildLinks(LinkA, FALSE, LeftB);
|
||||||
|
FixupChildLinks(LinkB, RootA, LeftA);
|
||||||
|
|
||||||
|
// A was root is a special case: B->Parent is now B
|
||||||
|
if (RootA)
|
||||||
|
RtlParent(LinkB) = LinkB;
|
||||||
|
|
||||||
|
#ifdef VERIFY_SWAP_SPLAY_LINKS
|
||||||
|
// Verify the distinct cases of node swap
|
||||||
|
if (RootA) {
|
||||||
|
if (RtlParent(&Tb) == LinkA) {
|
||||||
|
// LinkA = D, LinkB = B
|
||||||
|
// D B S S.L S.R S Q Q.R
|
||||||
|
ASSERT(RtlParent(LinkA) == LinkB);
|
||||||
|
ASSERT(RtlLeftChild(LinkA) == RtlLeftChild(&Tb));
|
||||||
|
ASSERT(RtlRightChild(LinkA) == RtlRightChild(&Tb));
|
||||||
|
ASSERT(RtlParent(LinkB) == LinkB);
|
||||||
|
ASSERT(RtlLeftChild(LinkB) == (LeftB ? LinkA : RtlLeftChild(&Ta)));
|
||||||
|
ASSERT(RtlRightChild(LinkB) == (LeftB ? RtlRightChild(&Ta) : LinkA));
|
||||||
|
} else {
|
||||||
|
// LinkA = D, LinkB = A
|
||||||
|
// D A S.P S.L S.R S Q.L Q.R
|
||||||
|
ASSERT(RtlParent(LinkA) == RtlParent(&Tb));
|
||||||
|
ASSERT(RtlLeftChild(LinkA) == RtlLeftChild(&Tb));
|
||||||
|
ASSERT(RtlRightChild(LinkA) == RtlRightChild(&Tb));
|
||||||
|
ASSERT(RtlParent(LinkB) == LinkB);
|
||||||
|
ASSERT(RtlLeftChild(LinkB) == RtlLeftChild(&Ta));
|
||||||
|
ASSERT(RtlRightChild(LinkB) == RtlRightChild(&Ta));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (RtlParent(&Tb) == LinkA) {
|
||||||
|
// LinkA = B, LinkB = A
|
||||||
|
// B A S S.L S.R Q.P Q Q.R
|
||||||
|
ASSERT(RtlParent(LinkA) == LinkB);
|
||||||
|
ASSERT(RtlLeftChild(LinkA) == RtlLeftChild(&Tb));
|
||||||
|
ASSERT(RtlRightChild(LinkA) == RtlRightChild(&Tb));
|
||||||
|
ASSERT(RtlParent(LinkB) == RtlParent(&Ta));
|
||||||
|
ASSERT(RtlLeftChild(LinkB) == (LeftB ? LinkA : RtlLeftChild(&Ta)));
|
||||||
|
ASSERT(RtlRightChild(LinkB) == (LeftB ? RtlRightChild(&Ta) : LinkA));
|
||||||
|
} else {
|
||||||
|
// LinkA = A, LinkB = C
|
||||||
|
// A C S.P S.L S.R Q.P Q.L Q.R
|
||||||
|
ASSERT(!memcmp(LinkA, &Tb, sizeof(Tb)));
|
||||||
|
ASSERT(!memcmp(LinkB, &Ta, sizeof(Ta)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -513,6 +634,7 @@ RtlSplay(PRTL_SPLAY_LINKS Links)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the root entry */
|
/* Return the root entry */
|
||||||
|
ASSERT(RtlIsRoot(N));
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue