From f9a7faa6e54336eb4109d6c6c1b8004389b7aac4 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 16 Oct 2006 04:08:09 +0000 Subject: [PATCH] - Implement RtlGetElementGenericTable using ordered node/element. - The splay tree generic table package is now complete. (The AVL package was done by Art earlier). svn path=/trunk/; revision=24546 --- reactos/lib/rtl/generictable.c | 87 ++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/reactos/lib/rtl/generictable.c b/reactos/lib/rtl/generictable.c index c6d3e8fe280..7e5752a2efe 100644 --- a/reactos/lib/rtl/generictable.c +++ b/reactos/lib/rtl/generictable.c @@ -412,15 +412,96 @@ RtlEnumerateGenericTableLikeADirectory(IN PRTL_AVL_TABLE Table, } /* - * @unimplemented + * @implemented */ PVOID NTAPI RtlGetElementGenericTable(IN PRTL_GENERIC_TABLE Table, IN ULONG I) { - UNIMPLEMENTED; - return 0; + ULONG OrderedElement, ElementCount; + PLIST_ENTRY OrderedNode; + ULONG DeltaUp, DeltaDown; + ULONG NextI = I + 1; + + /* Setup current accounting data */ + OrderedNode = Table->OrderedPointer; + OrderedElement = Table->WhichOrderedElement; + ElementCount = Table->NumberGenericTableElements; + + /* Sanity checks */ + if ((I == MAXULONG) || (NextI > ElementCount)) return NULL; + + /* Check if we already found the entry */ + if (NextI == OrderedElement) + { + /* Return it */ + return &((PTABLE_ENTRY_HEADER)CONTAINING_RECORD(OrderedNode, + TABLE_ENTRY_HEADER, + ListEntry))->UserData; + } + + /* Now check if we're farther behind */ + if (OrderedElement > NextI) + { + /* Find out if the distance is more then the half-way point */ + if (NextI > (OrderedElement / 2)) + { + /* Do the search backwards, since this takes less iterations */ + DeltaDown = OrderedElement - NextI; + do + { + /* Get next node */ + OrderedNode = OrderedNode->Blink; + } while (--DeltaDown); + } + else + { + /* Follow the list directly instead */ + OrderedNode = &Table->InsertOrderList; + do + { + /* Get next node */ + OrderedNode = OrderedNode->Flink; + } while (--NextI); + } + } + else + { + /* We are farther ahead, calculate distances */ + DeltaUp = NextI - OrderedElement; + DeltaDown = (ElementCount - NextI) + 1; + + /* Check if the up distance is smaller then the down distance */ + if (DeltaUp <= DeltaDown) + { + /* Do the search forwards, since this takes less iterations */ + do + { + /* Get next node */ + OrderedNode = OrderedNode->Blink; + } while (--DeltaUp); + } + else + { + /* Do the search downwards, since this takes less iterations */ + OrderedNode = &Table->InsertOrderList; + do + { + /* Get next node */ + OrderedNode = OrderedNode->Blink; + } while (--DeltaDown); + } + } + + /* Got the element, save it */ + Table->OrderedPointer = OrderedNode; + Table->WhichOrderedElement = NextI; + + /* Return the element */ + return &((PTABLE_ENTRY_HEADER)CONTAINING_RECORD(OrderedNode, + TABLE_ENTRY_HEADER, + ListEntry))->UserData; } /* AVL FUNCTIONS *************************************************************/