|
|
#ifndef _BPLUSTREE_CPP
#define _BPLUSTREE_CPP
/*
* Class: * * WmiAllocator * * Description: * * Provides abstraction above heap allocation functions * * Version: * * Initial * * Last Changed: * * See Source Depot for change history * */
#if 0
#include <precomp.h>
#include <windows.h>
#include <stdio.h>
#include <BPTree.h>
#endif
#if 0
#define INSERT_DEBUG
#define DELETE_DEBUG
#define FIND_DEBUG
#define COMMON_DEBUG
#endif
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiBPlusTree :: WmiBPlusTree (
WmiAllocator &a_Allocator , WmiBlockInterface &a_BlockAllocator , GUID &a_Identifier , ULONG a_BlockSize , ULONG a_KeyType , ULONG a_KeyTypeLength , ComparatorFunction a_ComparatorFunction , void *a_ComparatorOperand
) : m_Allocator ( a_Allocator ) , m_BlockAllocator ( a_BlockAllocator ) , m_Size ( 0 ) , m_Root ( 0 ) , m_Identifier ( a_Identifier ) , m_BlockSize ( a_BlockSize ) , m_KeyType ( a_KeyType ) , m_KeyTypeLength ( a_KeyTypeLength ) , m_ComparatorFunction ( a_ComparatorFunction ) , m_ComparatorOperand ( a_ComparatorOperand ) { }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiBPlusTree :: ~WmiBPlusTree () { WmiStatusCode t_StatusCode = UnInitialize () ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: Initialize () { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: UnInitialize () { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
if ( m_Root ) { t_StatusCode = RecursiveUnInitialize ( m_Root ) ; m_Root = NULL ; }
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: RecursiveUnInitialize ( WmiAbsoluteBlockOffSet &a_BlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ; return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
void WmiBPlusTree :: Recurse () { OutputDebugString ( L"\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ) ; if ( m_Root ) { BYTE *t_Block = NULL ; WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , m_Root , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
Recurse ( t_Node , m_Root ) ;
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } } OutputDebugString ( L"\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ) ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
void WmiBPlusTree :: Recurse (
WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
wchar_t t_StringBuffer [ 1024 ] ; swprintf ( t_StringBuffer , L"\n(%I64x)" , a_BlockOffSet ) ; OutputDebugString ( t_StringBuffer ) ;
WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
ULONG t_InternalKeySize = GetKeyTypeLength () ; ULONG t_KeyOffSet ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_KeyOffSet = WmiBlockLeafKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ; } else { t_KeyOffSet = WmiBlockKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ; }
ULONG t_NodeStart = a_Node->GetNodeStart () ; ULONG t_NodeSize = a_Node->GetNodeSize () ;
if ( t_Leaf ) { if ( a_BlockOffSet == m_Root ) { } else { if ( a_Node->GetNodeSize () < ( MaxLeafKeys () >> 1 ) ) { OutputDebugString ( L"\nInvalid Leaf Balance" ) ; } }
for ( ULONG t_Index = t_NodeStart ; t_Index < t_NodeSize ; t_Index ++ ) { BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ; WmiBPKey t_Key ( t_Buffer , GetKeyTypeLength () ) ;
#if 0
wchar_t t_StringBuffer [ 1024 ] ; swprintf ( t_StringBuffer , L"\nKey = %I64x" , * ( UINT64 * ) t_Key.GetConstData () ) ; OutputDebugString ( t_StringBuffer ) ; #endif
t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ; } } else { if ( a_BlockOffSet == m_Root ) { } else { if ( a_Node->GetNodeSize () < ( MaxKeys () >> 1 ) ) { OutputDebugString ( L"\nInvalid Balance" ) ; } }
for ( ULONG t_Index = t_NodeStart ; t_Index <= t_NodeSize ; t_Index ++ ) { BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ;
WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
CopyMemory (
( BYTE * ) & t_ChildOffSet , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
wchar_t t_StringBuffer [ 1024 ] ; swprintf ( t_StringBuffer , L"\t(%I64x)" , t_ChildOffSet ) ; OutputDebugString ( t_StringBuffer ) ;
t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ; }
t_BlockOffSet = sizeof ( WmiBPKeyNode ) ; for ( t_Index = t_NodeStart ; t_Index <= t_NodeSize ; t_Index ++ ) { BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ;
WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
CopyMemory (
( BYTE * ) & t_ChildOffSet , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
BYTE *t_Block = NULL ; t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ChildOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
Recurse (
t_Node , t_ChildOffSet ) ;
m_BlockAllocator.ReleaseBlock ( t_Block ) ; }
if ( t_Index < t_NodeSize ) { #if 0
WmiBPKey t_Key ( t_Buffer , GetKeyTypeLength () ) ; wchar_t t_StringBuffer [ 1024 ] ; swprintf ( t_StringBuffer , L"\nKey = %I64x" , * ( UINT64 * ) t_Key.GetConstData () ) ; OutputDebugString ( t_StringBuffer ) ; #endif
}
t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ; } } }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
void WmiBPlusTree :: PrintNode (
wchar_t *a_Prefix , WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet ) { WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
ULONG t_InternalKeySize = GetKeyTypeLength () ; ULONG t_KeyOffSet ; ULONG t_KeyPtrOffSet ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_KeyOffSet = WmiBlockLeafKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ; } else { t_KeyOffSet = WmiBlockKeyOffSet ; t_KeyPtrOffSet = WmiBlockKeyPointerOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ; }
ULONG t_NodeStart = a_Node->GetNodeStart () ; ULONG t_NodeSize = a_Node->GetNodeSize () ;
OutputDebugString ( L"\n======================================" ) ; OutputDebugString ( a_Prefix ) ;
if ( t_Leaf ) { OutputDebugString ( L"\nLeaf" ) ;
if ( a_BlockOffSet == m_Root ) { OutputDebugString ( L"\nRoot" ) ; } else { if ( a_Node->GetNodeSize () < ( MaxLeafKeys () >> 1 ) ) { OutputDebugString ( L"\nInvalid Balance" ) ; } } } else { OutputDebugString ( L"\nInternal" ) ; if ( a_BlockOffSet == m_Root ) { OutputDebugString ( L"\nRoot" ) ; } else { if ( a_Node->GetNodeSize () < ( MaxKeys () >> 1 ) ) { OutputDebugString ( L"\nInvalid Balance" ) ; } } }
wchar_t t_StringBuffer [ 1024 ] ; swprintf ( t_StringBuffer , L"\n%I64x" , a_BlockOffSet ) ; OutputDebugString ( t_StringBuffer ) ; OutputDebugString ( L"\n--------------------------------------" ) ;
for ( ULONG t_Index = t_NodeStart ; t_Index < t_NodeSize ; t_Index ++ ) { BYTE *t_KeyBuffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ;
if ( t_Leaf ) { WmiBPElement t_Element = 0 ;
CopyMemory (
( BYTE * ) & t_Element , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockLeafKeyElementOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
swprintf (
t_StringBuffer , L"\n(%I64x,%I64x)" , * ( UINT64 * ) t_KeyBuffer , t_Element ) ; } else { BYTE *t_LeftPointerBuffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyPtrOffSet ; BYTE *t_RightPointerBuffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyPtrOffSet + t_InternalKeySize ;
WmiBPElement t_Element = 0 ;
CopyMemory (
( BYTE * ) & t_Element , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyElementOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
swprintf (
t_StringBuffer , L"\n(%I64x),(%I64x,%I64x),(%I64x)" , * ( UINT64 * ) t_LeftPointerBuffer , * ( UINT64 * ) t_KeyBuffer , t_Element , * ( UINT64 * ) t_RightPointerBuffer ) ; }
OutputDebugString ( t_StringBuffer ) ; t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ; }
OutputDebugString ( L"\n======================================" ) ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: PositionInBlock (
WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet , ULONG &a_NodeIndex , WmiRelativeBlockOffSet &a_NodeOffSet , WmiAbsoluteBlockOffSet &a_ChildOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
#ifdef COMMON_DEBUG
PrintNode ( L"\nFindNextInBlock" , a_Node , a_BlockOffSet ) ; #endif
ULONG t_InternalKeySize = GetKeyTypeLength () ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ; } else { t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ; }
ULONG t_NodeStart = a_Node->GetNodeStart () ; ULONG t_NodeSize = a_Node->GetNodeSize () ;
WmiRelativeBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ; t_BlockOffSet = t_BlockOffSet + t_NodeStart * t_InternalKeySize + a_NodeIndex * t_InternalKeySize ;
if ( t_Leaf ) { if ( a_NodeIndex < t_NodeSize ) { a_NodeOffSet = t_BlockOffSet ;
a_ChildOffSet = 0 ; } else { t_StatusCode = e_StatusCode_NotFound ; } } else { if ( a_NodeIndex <= t_NodeSize ) { CopyMemory (
( BYTE * ) & a_ChildOffSet , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
if ( a_NodeIndex < t_NodeSize ) { a_NodeOffSet = t_BlockOffSet ; } else { a_NodeOffSet = 0 ; } } else { t_StatusCode = e_StatusCode_NotFound ; } }
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: GetKeyElement (
WmiBPKeyNode *a_Node , const WmiAbsoluteBlockOffSet &a_BlockOffSet , const ULONG &a_NodeIndex , Iterator &a_Iterator ) { ULONG t_InternalKeySize = GetKeyTypeLength () ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ; } else { t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ; } ULONG t_NodeStart = a_Node->GetNodeStart () ; ULONG t_NodeSize = a_Node->GetNodeSize () ;
WmiRelativeBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ; t_BlockOffSet = t_BlockOffSet + t_NodeStart * t_InternalKeySize + a_NodeIndex * t_InternalKeySize ;
if ( t_Leaf ) { CopyMemory (
( BYTE * ) & a_Iterator.GetElement () , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockLeafKeyElementOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
CopyMemory (
( BYTE * ) a_Iterator.GetKey ().GetData () , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockLeafKeyOffSet , GetKeyTypeLength () ) ; } else { CopyMemory (
( BYTE * ) & a_Iterator.GetElement () , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyElementOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
CopyMemory (
( BYTE * ) a_Iterator.GetKey ().GetData () , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyOffSet , GetKeyTypeLength () ) ; }
return e_StatusCode_Success ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: LeftMost (
Iterator &a_Iterator ) { WmiStack <IteratorPosition,8> &t_Stack = a_Iterator.GetStack () ; ULONG t_NodeIndex = a_Iterator.GetNodeIndex () ; WmiAbsoluteBlockOffSet t_BlockOffSet = a_Iterator.GetNodeOffSet () ;
WmiRelativeBlockOffSet t_NodeOffSet = 0 ; WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
do { BYTE *t_Block = NULL ; t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_BlockOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
t_StatusCode = PositionInBlock (
t_Node , t_BlockOffSet , t_NodeIndex , t_NodeOffSet , t_ChildOffSet ) ;
if ( t_StatusCode == e_StatusCode_Success ) { if ( t_ChildOffSet ) { t_StatusCode = t_Stack.Push ( IteratorPosition ( t_BlockOffSet , t_NodeIndex ) ) ; } else { a_Iterator.SetNodeIndex ( t_NodeIndex ) ; a_Iterator.SetNodeOffSet ( t_BlockOffSet ) ;
t_StatusCode = GetKeyElement ( t_Node , t_BlockOffSet , t_NodeIndex , a_Iterator ) ; } }
m_BlockAllocator.ReleaseBlock ( t_Block ) ;
t_NodeIndex = 0 ; t_BlockOffSet = t_ChildOffSet ; }
} while ( ( t_StatusCode == e_StatusCode_Success ) && t_ChildOffSet ) ;
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: RightMost (
Iterator &a_Iterator ) { WmiStack <IteratorPosition,8> &t_Stack = a_Iterator.GetStack () ; ULONG t_NodeIndex = a_Iterator.GetNodeIndex () ; WmiAbsoluteBlockOffSet t_BlockOffSet = a_Iterator.GetNodeOffSet () ;
WmiRelativeBlockOffSet t_NodeOffSet = 0 ; WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
do { BYTE *t_Block = NULL ; t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_BlockOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
BOOL t_Leaf = ( ( t_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_NodeIndex = t_Node->GetNodeSize () - t_Node->GetNodeStart () - 1 ; } else { t_NodeIndex = t_Node->GetNodeSize () - t_Node->GetNodeStart () ; }
t_StatusCode = PositionInBlock (
t_Node , t_BlockOffSet , t_NodeIndex , t_NodeOffSet , t_ChildOffSet ) ;
if ( t_StatusCode == e_StatusCode_Success ) { if ( t_ChildOffSet ) { t_StatusCode = t_Stack.Push ( IteratorPosition ( t_BlockOffSet , t_NodeIndex ) ) ; } else { a_Iterator.SetNodeIndex ( t_NodeIndex ) ; a_Iterator.SetNodeOffSet ( t_BlockOffSet ) ;
t_StatusCode = GetKeyElement ( t_Node , t_BlockOffSet , t_NodeIndex , a_Iterator ) ; } }
t_NodeIndex = 0 ; t_BlockOffSet = t_ChildOffSet ;
m_BlockAllocator.ReleaseBlock ( t_Block ) ; }
} while ( ( t_StatusCode == e_StatusCode_Success ) && t_ChildOffSet ) ;
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: Increment (
Iterator &a_Iterator ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
WmiStack <IteratorPosition,8> &t_Stack = a_Iterator.GetStack () ; ULONG t_NodeIndex = a_Iterator.GetNodeIndex () ; WmiAbsoluteBlockOffSet t_BlockOffSet = a_Iterator.GetNodeOffSet () ;
if ( t_BlockOffSet ) { BYTE *t_Block = NULL ; WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_BlockOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
t_NodeIndex ++ ;
WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ; WmiRelativeBlockOffSet t_NodeOffSet = 0 ;
WmiStatusCode t_TempStatusCode = PositionInBlock (
t_Node , t_BlockOffSet , t_NodeIndex , t_NodeOffSet , t_ChildOffSet ) ;
if ( t_TempStatusCode == e_StatusCode_Success ) { if ( t_ChildOffSet ) { t_StatusCode = t_Stack.Push ( IteratorPosition ( t_BlockOffSet , t_NodeIndex ) ) ; if ( t_StatusCode == e_StatusCode_Success ) { BYTE *t_Block = NULL ; t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ChildOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_ChildNode = ( WmiBPKeyNode * ) t_Block ;
a_Iterator.SetNodeOffSet ( t_ChildOffSet ) ; a_Iterator.SetNodeIndex ( t_ChildNode->GetNodeStart () ) ;
t_StatusCode = LeftMost ( a_Iterator ) ;
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } } } else { a_Iterator.SetNodeIndex ( t_NodeIndex ) ;
t_StatusCode = GetKeyElement ( t_Node , t_BlockOffSet , t_NodeIndex , a_Iterator ) ; } } else { IteratorPosition t_Position ;
while ( ( t_TempStatusCode = t_Stack.Top ( t_Position ) ) == e_StatusCode_Success ) { t_Stack.Pop () ;
BYTE *t_Block = NULL ; t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_Position.GetNodeOffSet () , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_ParentNode = ( WmiBPKeyNode * ) t_Block ;
if ( t_Position.GetNodeIndex () < ( t_ParentNode->GetNodeSize () - t_ParentNode->GetNodeStart () ) ) { a_Iterator.SetNodeIndex ( t_Position.GetNodeIndex () ) ; a_Iterator.SetNodeOffSet ( t_Position.GetNodeOffSet () ) ;
t_StatusCode = GetKeyElement ( t_ParentNode , t_Position.GetNodeOffSet () , t_Position.GetNodeIndex () , a_Iterator ) ;
m_BlockAllocator.ReleaseBlock ( t_Block ) ;
break ; }
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } }
if ( t_TempStatusCode != e_StatusCode_Success ) { a_Iterator.SetNodeIndex ( 0 ) ; a_Iterator.SetNodeOffSet ( 0 ) ; } }
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } } else { t_StatusCode = e_StatusCode_Failed ; }
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: Decrement (
Iterator &a_Iterator ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
WmiStack <IteratorPosition,8> &t_Stack = a_Iterator.GetStack () ; ULONG t_NodeIndex = a_Iterator.GetNodeIndex () ; WmiAbsoluteBlockOffSet t_BlockOffSet = a_Iterator.GetNodeOffSet () ;
if ( t_BlockOffSet ) { BYTE *t_Block = NULL ; WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_BlockOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
t_NodeIndex -- ;
WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ; WmiRelativeBlockOffSet t_NodeOffSet = 0 ;
WmiStatusCode t_TempStatusCode = PositionInBlock (
t_Node , t_BlockOffSet , t_NodeIndex , t_NodeOffSet , t_ChildOffSet ) ;
if ( t_TempStatusCode == e_StatusCode_Success ) { if ( t_ChildOffSet ) { t_StatusCode = t_Stack.Push ( IteratorPosition ( t_BlockOffSet , t_NodeIndex ) ) ; if ( t_StatusCode == e_StatusCode_Success ) { BYTE *t_Block = NULL ; t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ChildOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_ChildNode = ( WmiBPKeyNode * ) t_Block ;
a_Iterator.SetNodeOffSet ( t_ChildOffSet ) ; a_Iterator.SetNodeIndex ( t_ChildNode->GetNodeStart () + t_ChildNode->GetNodeSize () - 1 ) ;
t_StatusCode = RightMost ( a_Iterator ) ;
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } } } else { a_Iterator.SetNodeIndex ( t_NodeIndex ) ;
t_StatusCode = GetKeyElement ( t_Node , t_BlockOffSet , t_NodeIndex , a_Iterator ) ; } } else { IteratorPosition t_Position ;
while ( ( t_TempStatusCode = t_Stack.Top ( t_Position ) ) == e_StatusCode_Success ) { t_Stack.Pop () ;
BYTE *t_Block = NULL ; t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_Position.GetNodeOffSet () , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_ParentNode = ( WmiBPKeyNode * ) t_Block ;
if ( t_Position.GetNodeIndex () > t_ParentNode->GetNodeStart () ) { a_Iterator.SetNodeIndex ( t_Position.GetNodeIndex () ) ; a_Iterator.SetNodeOffSet ( t_Position.GetNodeOffSet () ) ;
t_StatusCode = GetKeyElement ( t_ParentNode , t_Position.GetNodeOffSet () , t_Position.GetNodeIndex () - 1 , a_Iterator ) ;
m_BlockAllocator.ReleaseBlock ( t_Block ) ;
break ; }
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } }
if ( t_TempStatusCode != e_StatusCode_Success ) { a_Iterator.SetNodeIndex ( 0 ) ; a_Iterator.SetNodeOffSet ( 0 ) ; } }
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } } else { t_StatusCode = e_StatusCode_Failed ; }
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiBPlusTree :: Iterator &WmiBPlusTree :: Begin (
Iterator &a_Iterator ) { if ( m_Root ) { BYTE *t_Block = NULL ; WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , m_Root , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
a_Iterator.SetNodeOffSet ( m_Root ) ; a_Iterator.SetNodeIndex ( t_Node->GetNodeStart () ) ;
t_StatusCode = LeftMost ( a_Iterator ) ; if ( t_StatusCode != e_StatusCode_Success ) { a_Iterator.SetNodeOffSet ( 0 ) ; a_Iterator.SetNodeIndex ( 0 ) ; } } else { a_Iterator.SetNodeOffSet ( 0 ) ; a_Iterator.SetNodeIndex ( 0 ) ; } } else { a_Iterator.SetNodeOffSet ( 0 ) ; a_Iterator.SetNodeIndex ( 0 ) ; }
return a_Iterator ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiBPlusTree :: Iterator &WmiBPlusTree :: End (
Iterator &a_Iterator ) { if ( m_Root ) { BYTE *t_Block = NULL ; WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , m_Root , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
a_Iterator.SetNodeOffSet ( m_Root ) ; a_Iterator.SetNodeIndex ( t_Node->GetNodeStart () + t_Node->GetNodeSize () - 1 ) ;
t_StatusCode = RightMost ( a_Iterator ) ; if ( t_StatusCode != e_StatusCode_Success ) { a_Iterator.SetNodeOffSet ( 0 ) ; a_Iterator.SetNodeIndex ( 0 ) ; }
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } else { a_Iterator.SetNodeOffSet ( 0 ) ; a_Iterator.SetNodeIndex ( 0 ) ; } } else { a_Iterator.SetNodeOffSet ( 0 ) ; a_Iterator.SetNodeIndex ( 0 ) ; }
return a_Iterator ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiBPlusTree :: Iterator &WmiBPlusTree :: Root (
Iterator &a_Iterator ) { if ( m_Root ) { BYTE *t_Block = NULL ; WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , m_Root , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
a_Iterator.SetNodeOffSet ( m_Root ) ; a_Iterator.SetNodeIndex ( t_Node->GetNodeStart () ) ;
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } else { a_Iterator.SetNodeOffSet ( 0 ) ; a_Iterator.SetNodeIndex ( 0 ) ; } } else { a_Iterator.SetNodeOffSet ( 0 ) ; a_Iterator.SetNodeIndex ( 0 ) ; }
return a_Iterator ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: FindInBlock (
WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet , const WmiBPKey &a_Key , WmiAbsoluteBlockOffSet &a_ChildOffSet , WmiBPElement &a_Element , WmiRelativeBlockOffSet &a_NodeOffSet , ULONG &a_NodeIndex ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
#ifdef COMMON_DEBUG
PrintNode ( L"\nFindInBlock" , a_Node , a_BlockOffSet ) ; #endif
ULONG t_InternalKeySize = GetKeyTypeLength () ; ULONG t_KeyOffSet ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_KeyOffSet = WmiBlockLeafKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ; } else { t_KeyOffSet = WmiBlockKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ; }
ULONG t_LowerIndex = a_Node->GetNodeStart () ; ULONG t_UpperIndex = a_Node->GetNodeSize () ;
while ( t_LowerIndex < t_UpperIndex ) { ULONG t_Index = ( t_LowerIndex + t_UpperIndex ) >> 1 ;
WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) + ( t_Index * t_InternalKeySize ) ;
BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ; WmiBPKey t_Key ( t_Buffer , GetKeyTypeLength () ) ;
LONG t_Compare = GetComparatorFunction () ( GetComparatorOperand () , a_Key , t_Key ) ; if ( t_Compare == 0 ) { if ( t_Leaf ) { CopyMemory (
( BYTE * ) & a_Element , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockLeafKeyElementOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
a_NodeOffSet = t_BlockOffSet ; } else { CopyMemory (
( BYTE * ) & a_Element , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyElementOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
a_NodeOffSet = t_BlockOffSet ; }
a_NodeIndex = t_Index ;
return t_StatusCode ; } else { if ( t_Compare < 0 ) { t_UpperIndex = t_Index ; } else { t_LowerIndex = t_Index + 1 ; } } }
if ( t_Leaf ) { t_StatusCode = e_StatusCode_NotFound ; } else { WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) + ( t_UpperIndex * t_InternalKeySize ) ;
CopyMemory (
( BYTE * ) & a_ChildOffSet , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
a_NodeIndex = t_UpperIndex ; }
return t_StatusCode ; }
#if 0
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: FindInBlock (
WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet , const WmiBPKey &a_Key , WmiAbsoluteBlockOffSet &a_ChildOffSet , WmiBPElement &a_Element , WmiRelativeBlockOffSet &a_NodeOffSet , ULONG &a_NodeIndex ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
#ifdef COMMON_DEBUG
PrintNode ( L"\nFindInBlock" , a_Node , a_BlockOffSet ) ; #endif
WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
ULONG t_InternalKeySize = GetKeyTypeLength () ; ULONG t_KeyOffSet ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_KeyOffSet = WmiBlockLeafKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ; } else { t_KeyOffSet = WmiBlockKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ; }
ULONG t_NodeStart = a_Node->GetNodeStart () ; ULONG t_NodeSize = a_Node->GetNodeSize () ;
for ( ULONG t_Index = t_NodeStart ; t_Index < t_NodeSize ; t_Index ++ ) { BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet ; WmiBPKey t_Key ( t_Buffer , GetKeyTypeLength () ) ;
LONG t_Compare = GetComparatorFunction () ( GetComparatorOperand () , a_Key , t_Key ) ; if ( t_Compare == 0 ) { if ( t_Leaf ) { CopyMemory (
( BYTE * ) & a_Element , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockLeafKeyElementOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
a_NodeOffSet = t_BlockOffSet ; } else { CopyMemory (
( BYTE * ) & a_Element , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyElementOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
a_NodeOffSet = t_BlockOffSet ; }
a_NodeIndex = t_Index ;
return t_StatusCode ; } else if ( t_Compare < 0 ) { if ( t_Leaf ) { t_StatusCode = e_StatusCode_NotFound ; } else { CopyMemory (
( BYTE * ) & a_ChildOffSet , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
a_NodeIndex = t_Index ; }
return t_StatusCode ; }
t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ; }
if ( t_Leaf ) { t_StatusCode = e_StatusCode_NotFound ; } else { CopyMemory (
( BYTE * ) & a_ChildOffSet , ( ( BYTE * ) ( a_Node ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
a_NodeIndex = t_Index ; }
return t_StatusCode ; }
#endif
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: Find (
const WmiBPKey &a_Key , Iterator &a_Iterator ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
if ( m_Root ) { t_StatusCode = RecursiveFind ( m_Root , a_Key , a_Iterator ) ; } else { return e_StatusCode_NotFound ; }
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: RecursiveFind (
WmiAbsoluteBlockOffSet &a_BlockOffSet , const WmiBPKey &a_Key , Iterator &a_Iterator ) { WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ; WmiBPElement t_Element = 0 ;
BYTE *t_Block = NULL ; WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , a_BlockOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
WmiRelativeBlockOffSet t_NodeOffSet = 0 ; ULONG t_NodeIndex = 0 ;
t_StatusCode = FindInBlock (
t_Node , a_BlockOffSet , a_Key , t_ChildOffSet , t_Element , t_NodeOffSet , t_NodeIndex ) ;
if ( t_StatusCode == e_StatusCode_Success ) { if ( t_ChildOffSet ) { WmiStack <IteratorPosition,8> &t_Stack = a_Iterator.GetStack () ;
t_StatusCode = t_Stack.Push ( IteratorPosition ( a_BlockOffSet , t_NodeIndex ) ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = RecursiveFind ( t_ChildOffSet , a_Key , a_Iterator ) ; } } else { a_Iterator.SetNodeOffSet ( a_BlockOffSet ) ; a_Iterator.SetNodeIndex ( t_NodeIndex ) ;
a_Iterator.GetElement () = t_Element ; CopyMemory (
a_Iterator.GetKey ().GetData () , a_Key.GetConstData () , GetKeyTypeLength () ) ; } }
m_BlockAllocator.ReleaseBlock ( t_Block ) ; }
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: SetLeafNode (
WmiBPKeyNode *a_Node , const WmiRelativeBlockOffSet &a_NodeDeltaOffSet , const WmiBPKey &a_Key , const WmiBPElement &a_Element ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockLeafKeyOffSet ;
CopyMemory (
t_Buffer , ( BYTE * ) a_Key.GetConstData () , a_Key.GetConstDataSize () , ) ;
t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockLeafKeyElementOffSet ;
CopyMemory (
t_Buffer , ( BYTE * ) & ( a_Element ) , sizeof ( a_Element ) ) ;
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: SetNode (
WmiBPKeyNode *a_Node , const WmiRelativeBlockOffSet &a_NodeDeltaOffSet , const WmiBPKey &a_Key , const WmiBPElement &a_Element , WmiAbsoluteBlockOffSet &a_LeftCutBlockOffSet , WmiAbsoluteBlockOffSet &a_RightCutBlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockKeyOffSet ;
CopyMemory (
t_Buffer , ( BYTE * ) a_Key.GetConstData () , a_Key.GetConstDataSize () , ) ;
t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockKeyElementOffSet ;
CopyMemory (
t_Buffer , ( BYTE * ) & ( a_Element ) , sizeof ( a_Element ) ) ;
t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockKeyPointerOffSet ;
CopyMemory (
t_Buffer , ( BYTE * ) & ( a_LeftCutBlockOffSet ) , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
t_Buffer = ( ( BYTE * ) a_Node ) + a_NodeDeltaOffSet + WmiBlockKeyOffSet + a_Key.GetConstDataSize () + WmiBlockKeyPointerOffSet ;
CopyMemory (
t_Buffer , ( BYTE * ) & ( a_RightCutBlockOffSet ) , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: PerformInsertion (
WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet , const WmiBPKey &a_Key , WmiBPElement &a_Element , WmiBPKey &a_ReBalanceKey , WmiBPElement &a_ReBalanceElement , WmiAbsoluteBlockOffSet &a_LeftCutBlockOffSet , WmiAbsoluteBlockOffSet &a_RightCutBlockOffSet , WmiRelativeBlockOffSet &a_PositionBlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
#ifdef INSERT_DEBUG
OutputDebugString ( L"\n/**************************************" ) ; wchar_t t_StringBuffer [ 1024 ] ; swprintf ( t_StringBuffer , L"\nInsertion Key = %I64x" , * ( UINT64 * ) a_Key.GetConstData () ) ; OutputDebugString ( t_StringBuffer ) ; #endif
WmiRelativeBlockOffSet t_StartBlockOffSet = sizeof ( WmiBPKeyNode ) ;
BOOL t_ReBalance ; ULONG t_PartitionPoint ; WmiRelativeBlockOffSet t_KeyOffSet ; WmiRelativeBlockOffSet t_KeyElementOffSet ; WmiRelativeBlockOffSet t_KeyPosition ; WmiRelativeBlockOffSet t_KeyPositionIncrement ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_KeyPositionIncrement = WmiBlockLeafKeyOffSet + GetKeyTypeLength () ;
t_ReBalance = ( a_Node->GetNodeSize () >= MaxLeafKeys () ) ? TRUE : FALSE ; if ( t_ReBalance ) { t_PartitionPoint = MaxLeafKeys () >> 1 ;
t_KeyPosition = t_StartBlockOffSet + ( t_PartitionPoint * t_KeyPositionIncrement ) ; t_KeyOffSet = t_KeyPosition + WmiBlockLeafKeyOffSet ; t_KeyElementOffSet = t_KeyPosition + WmiBlockLeafKeyElementOffSet ; } } else { t_KeyPositionIncrement = WmiBlockKeyOffSet + GetKeyTypeLength () ;
t_ReBalance = ( a_Node->GetNodeSize () >= MaxKeys () ) ? TRUE : FALSE ; if ( t_ReBalance ) { t_PartitionPoint = MaxKeys () >> 1 ;
t_KeyPosition = t_StartBlockOffSet + ( t_PartitionPoint * t_KeyPositionIncrement ) ; t_KeyOffSet = t_KeyPosition + WmiBlockKeyOffSet ; t_KeyElementOffSet = t_KeyPosition + WmiBlockKeyElementOffSet; } }
if ( t_ReBalance ) { BYTE *t_PartitionData = NULL ; t_StatusCode = m_Allocator.New ( ( void ** ) & t_PartitionData , GetKeyTypeLength () ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiAbsoluteBlockOffSet t_BlockOffSet = 0 ; BYTE *t_Block = NULL ; WmiStatusCode t_StatusCode = m_BlockAllocator.AllocateBlock (
1 , t_BlockOffSet , t_Block ) ;
if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
#ifdef INSERT_DEBUG
PrintNode ( L"\nPre Re Balanced a_Node" , a_Node , a_BlockOffSet ) ; PrintNode ( L"\nPre Re Balanced t_Node" , t_Node , t_BlockOffSet ) ; #endif
if ( a_PositionBlockOffSet < t_KeyPosition ) { /*
* Copy key to trickle up. */
BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyOffSet - t_KeyPositionIncrement ;
CopyMemory (
( BYTE * ) t_PartitionData , t_Buffer , GetKeyTypeLength () , ) ;
a_ReBalanceKey = WmiBPKey ( t_PartitionData , GetKeyTypeLength () , TRUE ) ;
t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyElementOffSet - t_KeyPositionIncrement ;
CopyMemory (
( BYTE * ) & ( a_ReBalanceElement ) , t_Buffer , sizeof ( a_ReBalanceElement ) ) ;
t_Node->SetNodeSize ( t_PartitionPoint ) ; t_Node->SetNodeOffSet ( t_BlockOffSet ) ; t_Node->SetNodeStart ( 0 ) ;
a_Node->SetNodeSize ( t_PartitionPoint ) ; /*
* Copy Right partition to new node */ CopyMemory (
( ( BYTE * ) t_Node ) + t_StartBlockOffSet , ( ( BYTE * ) a_Node ) + t_KeyPosition , ( ULONG ) ( t_PartitionPoint * t_KeyPositionIncrement ) + ( t_Leaf ? 0 : t_KeyPositionIncrement ) ) ; /*
* Shuffle memory for key insertion */ WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + a_Node->GetNodeSize () * t_KeyPositionIncrement ; WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - a_PositionBlockOffSet ;
MoveMemory (
( ( BYTE * ) a_Node ) + a_PositionBlockOffSet + t_KeyPositionIncrement , ( ( BYTE * ) a_Node ) + a_PositionBlockOffSet , ( ULONG ) t_MoveSize + ( t_Leaf ? 0 : t_KeyPositionIncrement ) ) ;
if ( t_Leaf ) { t_StatusCode = SetLeafNode (
a_Node , a_PositionBlockOffSet , a_Key , a_Element ) ;
t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_LEAF ) ; } else { t_StatusCode = SetNode (
a_Node , a_PositionBlockOffSet , a_Key , a_Element , a_LeftCutBlockOffSet , a_RightCutBlockOffSet ) ;
t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_INTERNAL ) ; }
t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & t_Node ) ; if ( t_StatusCode == e_StatusCode_Success ) { a_LeftCutBlockOffSet = a_BlockOffSet ; a_RightCutBlockOffSet = t_BlockOffSet ; } } } else if ( a_PositionBlockOffSet > t_KeyPosition ) { /*
* Copy key to trickle up. */
BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyOffSet ;
CopyMemory (
( BYTE * ) t_PartitionData , t_Buffer , GetKeyTypeLength () , ) ;
a_ReBalanceKey = WmiBPKey ( t_PartitionData , GetKeyTypeLength () , TRUE ) ;
t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyElementOffSet ;
CopyMemory (
( BYTE * ) & ( a_ReBalanceElement ) , t_Buffer , sizeof ( a_ReBalanceElement ) ) ;
t_Node->SetNodeSize ( t_PartitionPoint ) ; t_Node->SetNodeOffSet ( t_BlockOffSet ) ; t_Node->SetNodeStart ( 0 ) ;
a_Node->SetNodeSize ( t_PartitionPoint ) ;
CopyMemory (
( ( BYTE * ) t_Node ) + t_StartBlockOffSet , ( ( BYTE * ) a_Node ) + t_KeyPosition + t_KeyPositionIncrement , ( ULONG ) ( ( t_PartitionPoint - 1 ) * t_KeyPositionIncrement ) + ( t_Leaf ? 0 : t_KeyPositionIncrement ) ) ; WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + t_Node->GetNodeSize () * t_KeyPositionIncrement ; WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) ;
MoveMemory (
( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) , ( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) - t_KeyPositionIncrement , ( ULONG ) t_MoveSize + ( t_Leaf ? 0 : t_KeyPositionIncrement ) ) ;
if ( t_Leaf ) { t_StatusCode = SetLeafNode (
t_Node , ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) - t_KeyPositionIncrement , a_Key , a_Element ) ;
t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_LEAF ) ; } else { t_StatusCode = SetNode (
t_Node , ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) - t_KeyPositionIncrement , a_Key , a_Element , a_LeftCutBlockOffSet , a_RightCutBlockOffSet ) ;
t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_INTERNAL ) ; }
t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & t_Node ) ; if ( t_StatusCode == e_StatusCode_Success ) { a_LeftCutBlockOffSet = a_BlockOffSet ; a_RightCutBlockOffSet = t_BlockOffSet ; } } } else { /*
* Copy key to trickle up. */
BYTE *t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyOffSet ;
CopyMemory (
( BYTE * ) t_PartitionData , t_Buffer , GetKeyTypeLength () , ) ; WmiBPKey t_TempKey = WmiBPKey ( t_PartitionData , GetKeyTypeLength () , TRUE ) ;
WmiBPElement t_TempElement ; t_Buffer = ( ( BYTE * ) a_Node ) + t_KeyElementOffSet ; CopyMemory (
( BYTE * ) & ( t_TempElement ) , t_Buffer , sizeof ( t_TempElement ) ) ;
a_ReBalanceKey = t_TempKey ; a_ReBalanceElement = t_TempElement ;
t_Node->SetNodeSize ( t_PartitionPoint ) ; t_Node->SetNodeOffSet ( t_BlockOffSet ) ; t_Node->SetNodeStart ( 0 ) ;
a_Node->SetNodeSize ( t_PartitionPoint ) ;
CopyMemory (
( ( BYTE * ) t_Node ) + t_StartBlockOffSet , ( ( BYTE * ) a_Node ) + t_KeyPosition + t_KeyPositionIncrement , ( ULONG ) ( ( t_PartitionPoint - 1 ) * t_KeyPositionIncrement ) + ( t_Leaf ? 0 : t_KeyPositionIncrement ) ) ;
WmiAbsoluteBlockOffSet t_LeftPointerBlockOffSet = 0 ; CopyMemory (
( BYTE * ) & t_LeftPointerBlockOffSet , ( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
WmiAbsoluteBlockOffSet t_RightPointerBlockOffSet = 0 ; CopyMemory (
( BYTE * ) & t_RightPointerBlockOffSet , ( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) + t_KeyPositionIncrement , sizeof ( WmiAbsoluteBlockOffSet ) ) ; WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + t_Node->GetNodeSize () * t_KeyPositionIncrement ; WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) ;
MoveMemory (
( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) + t_KeyPositionIncrement , ( ( BYTE * ) t_Node ) + ( t_StartBlockOffSet + a_PositionBlockOffSet - t_KeyPosition ) , ( ULONG ) t_MoveSize + ( t_Leaf ? 0 : t_KeyPositionIncrement ) ) ;
LONG t_Compare = GetComparatorFunction () ( GetComparatorOperand () , a_Key , t_TempKey ) ;
if ( t_Leaf ) { if ( t_Compare < 0 ) { t_StatusCode = SetLeafNode (
t_Node , ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) , t_TempKey , t_TempElement ) ;
CopyMemory (
( BYTE * ) t_PartitionData , a_Key.GetConstData () , GetKeyTypeLength () , ) ;
CopyMemory (
( BYTE * ) & ( a_ReBalanceElement ) , ( BYTE * ) & a_Element , sizeof ( a_ReBalanceElement ) ) ; } else { t_StatusCode = SetLeafNode (
t_Node , ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) , a_Key , a_Element ) ; }
t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_LEAF ) ; } else { if ( t_Compare < 0 ) { t_StatusCode = SetNode (
t_Node , ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) , t_TempKey , t_TempElement , a_RightCutBlockOffSet , t_LeftPointerBlockOffSet ) ;
CopyMemory (
( BYTE * ) t_PartitionData , a_Key.GetConstData () , GetKeyTypeLength () , ) ;
CopyMemory (
( BYTE * ) & ( a_ReBalanceElement ) , ( BYTE * ) & a_Element , sizeof ( a_ReBalanceElement ) ) ;
a_RightCutBlockOffSet = t_BlockOffSet ; } else { t_StatusCode = SetNode (
t_Node , ( t_StartBlockOffSet + a_PositionBlockOffSet - ( t_KeyPosition ) ) , a_Key , a_Element , a_RightCutBlockOffSet , t_RightPointerBlockOffSet ) ;
a_RightCutBlockOffSet = a_BlockOffSet ; }
t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_INTERNAL ) ; }
t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & t_Node ) ; if ( t_StatusCode == e_StatusCode_Success ) { a_LeftCutBlockOffSet = a_BlockOffSet ; a_RightCutBlockOffSet = t_BlockOffSet ; } } }
#ifdef INSERT_DEBUG
OutputDebugString ( L"\n/**************************************" ) ; wchar_t t_StringBuffer [ 1024 ] ; swprintf ( t_StringBuffer , L"\nReBalance Key = %I64x" , * ( UINT64 * ) a_ReBalanceKey.GetConstData () ) ; OutputDebugString ( t_StringBuffer ) ;
PrintNode ( L"\nRe Balanced a_Node" , a_Node , a_BlockOffSet ) ; PrintNode ( L"\nRe Balanced t_Node" , t_Node , t_BlockOffSet ) ; #endif
} } } else { /*
* Shuffle memory for insertion */
#ifdef INSERT_DEBUG
PrintNode ( L"\nPre Shuffled a_Node" , a_Node , a_BlockOffSet ) ; #endif
WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + a_Node->GetNodeSize () * t_KeyPositionIncrement ; WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - a_PositionBlockOffSet ;
MoveMemory (
( ( BYTE * ) a_Node ) + a_PositionBlockOffSet + t_KeyPositionIncrement , ( ( BYTE * ) a_Node ) + a_PositionBlockOffSet , ( ULONG ) t_MoveSize + ( t_Leaf ? 0 : t_KeyPositionIncrement ) ) ;
if ( t_Leaf ) { t_StatusCode = SetLeafNode (
a_Node , a_PositionBlockOffSet , a_Key , a_Element ) ; } else { t_StatusCode = SetNode (
a_Node , a_PositionBlockOffSet , a_Key , a_Element , a_LeftCutBlockOffSet , a_RightCutBlockOffSet ) ; }
a_Node->SetNodeSize ( a_Node->GetNodeSize () + 1 ) ;
#ifdef INSERT_DEBUG
PrintNode ( L"\nShuffled a_Node" , a_Node , a_BlockOffSet ) ; #endif
t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ;
a_ReBalanceElement = 0 ; a_LeftCutBlockOffSet = 0 ; a_RightCutBlockOffSet = 0 ; }
return t_StatusCode ; }
#if 1
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: InsertInBlock (
WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet , const WmiBPKey &a_Key , WmiBPElement &a_Element , WmiBPKey &a_ReBalanceKey , WmiBPElement &a_ReBalanceElement , WmiAbsoluteBlockOffSet &a_LeftCutBlockOffSet , WmiAbsoluteBlockOffSet &a_RightCutBlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
ULONG t_InternalKeySize = GetKeyTypeLength () ; ULONG t_KeyOffSet ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_KeyOffSet = WmiBlockLeafKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ; } else { t_KeyOffSet = WmiBlockKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ; }
ULONG t_LowerIndex = a_Node->GetNodeStart () ; ULONG t_UpperIndex = a_Node->GetNodeSize () ;
while ( t_LowerIndex < t_UpperIndex ) { ULONG t_Index = ( t_LowerIndex + t_UpperIndex ) >> 1 ;
WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) + ( t_Index * t_InternalKeySize ) ;
WmiBPKey t_Key ( ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet , GetKeyTypeLength () ) ;
LONG t_Compare = GetComparatorFunction () ( GetComparatorOperand () , a_Key , t_Key ) ; if ( t_Compare == 0 ) { /*
* Can not happen at this juncture */ return e_StatusCode_AlreadyExists ; } else { if ( t_Compare < 0 ) { t_UpperIndex = t_Index ; } else { t_LowerIndex = t_Index + 1 ; } } }
WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) + ( t_UpperIndex * t_InternalKeySize ) ;
t_StatusCode = PerformInsertion (
a_Node , a_BlockOffSet , a_Key , a_Element , a_ReBalanceKey , a_ReBalanceElement , a_LeftCutBlockOffSet , a_RightCutBlockOffSet , t_BlockOffSet ) ;
return t_StatusCode ; }
#else
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: InsertInBlock (
WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet , const WmiBPKey &a_Key , WmiBPElement &a_Element , WmiBPKey &a_ReBalanceKey , WmiBPElement &a_ReBalanceElement , WmiAbsoluteBlockOffSet &a_LeftCutBlockOffSet , WmiAbsoluteBlockOffSet &a_RightCutBlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
ULONG t_InternalKeySize = GetKeyTypeLength () ; ULONG t_KeyOffSet ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_KeyOffSet = WmiBlockLeafKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ; } else { t_KeyOffSet = WmiBlockKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ; }
ULONG t_NodeStart = a_Node->GetNodeStart () ; ULONG t_NodeSize = a_Node->GetNodeSize () ;
WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
for ( ULONG t_Index = t_NodeStart ; t_Index < t_NodeSize ; t_Index ++ ) { WmiBPKey t_Key ( ( ( BYTE * ) a_Node ) + t_BlockOffSet + t_KeyOffSet , GetKeyTypeLength () ) ;
LONG t_Compare = GetComparatorFunction () ( GetComparatorOperand () , a_Key , t_Key ) ; if ( t_Compare == 0 ) { /*
* Can not happen at this juncture */ return e_StatusCode_AlreadyExists ; } else if ( t_Compare < 0 ) { /*
* Found slot position to insert at. */
t_StatusCode = PerformInsertion (
a_Node , a_BlockOffSet , a_Key , a_Element , a_ReBalanceKey , a_ReBalanceElement , a_LeftCutBlockOffSet , a_RightCutBlockOffSet , t_BlockOffSet ) ;
return t_StatusCode ; }
t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ; }
/*
* Found slot at end */
t_StatusCode = PerformInsertion (
a_Node , a_BlockOffSet , a_Key , a_Element , a_ReBalanceKey , a_ReBalanceElement , a_LeftCutBlockOffSet , a_RightCutBlockOffSet , t_BlockOffSet ) ;
return t_StatusCode ; }
#endif
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: RecursiveInsert (
WmiStack <WmiAbsoluteBlockOffSet,8> &a_Stack , WmiAbsoluteBlockOffSet &a_BlockOffSet , const WmiBPKey &a_Key , const WmiBPElement &a_Element ) { WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ; WmiBPElement t_Element = 0 ;
BYTE *t_Block = NULL ; WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , a_BlockOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
WmiRelativeBlockOffSet t_NodeOffSet = 0 ; ULONG t_NodeIndex = 0 ;
t_StatusCode = FindInBlock (
t_Node , a_BlockOffSet , a_Key , t_ChildOffSet , t_Element , t_NodeOffSet , t_NodeIndex ) ;
if ( t_StatusCode == e_StatusCode_Success ) { if ( t_Element ) { t_StatusCode = e_StatusCode_AlreadyExists ; } else { t_StatusCode = a_Stack.Push ( a_BlockOffSet ) ;
if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = RecursiveInsert (
a_Stack , t_ChildOffSet , a_Key , a_Element ) ; } }
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } else { WmiAbsoluteBlockOffSet t_OffSet = a_BlockOffSet ; WmiBPKey t_Key = a_Key ; WmiBPElement t_Element = a_Element ; WmiBPKey t_ReBalanceKey ; WmiBPElement t_ReBalanceElement = a_Element ;
WmiAbsoluteBlockOffSet t_LeftCutBlockOffSet = 0 ; WmiAbsoluteBlockOffSet t_RightCutBlockOffSet = 0 ;
do { if ( t_ReBalanceElement ) { t_Node = ( WmiBPKeyNode * ) t_Block ;
t_StatusCode = InsertInBlock (
t_Node , t_OffSet , t_Key , t_Element , t_ReBalanceKey , t_ReBalanceElement , t_LeftCutBlockOffSet , t_RightCutBlockOffSet ) ;
m_BlockAllocator.ReleaseBlock ( t_Block ) ;
if ( t_StatusCode == e_StatusCode_Success ) { WmiStatusCode t_TempStatusCode = a_Stack.Top ( t_OffSet ) ; if ( t_TempStatusCode != e_StatusCode_Success ) { if ( t_ReBalanceElement ) { t_OffSet = 0 ; t_Block = NULL ; t_StatusCode = m_BlockAllocator.AllocateBlock (
1 , t_OffSet , t_Block ) ;
if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_INTERNAL ) ; t_Node->SetNodeSize ( 1 ) ; t_Node->SetNodeOffSet ( t_OffSet ) ; t_Node->SetNodeStart ( 0 ) ;
t_StatusCode = SetNode (
t_Node , sizeof ( WmiBPKeyNode ) , t_ReBalanceKey , t_ReBalanceElement , t_LeftCutBlockOffSet , t_RightCutBlockOffSet ) ;
if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & t_Node ) ; if ( t_StatusCode == e_StatusCode_Success ) { SetRoot ( t_OffSet ) ;
#ifdef INSERT_DEBUG
PrintNode ( L"\nRoot Creation" , t_Node , t_OffSet ) ; #endif
}
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } else { m_BlockAllocator.ReleaseBlock ( t_Block ) ;
m_BlockAllocator.FreeBlock (
1 , t_OffSet ) ; } } }
if ( t_ReBalanceKey.GetAllocated () ) { m_Allocator.Delete ( t_ReBalanceKey.GetData () ) ; }
return t_StatusCode ; } else { m_BlockAllocator.ReleaseBlock ( t_Block ) ;
if ( t_ReBalanceElement ) { t_Block = NULL ; t_StatusCode = m_BlockAllocator.ReadBlock (
1 , t_OffSet , t_Block ) ;
if ( t_Key.GetAllocated () ) { m_Allocator.Delete ( t_Key.GetData () ) ; }
t_Key = t_ReBalanceKey ; t_Element = t_ReBalanceElement ; }
a_Stack.Pop () ; } } } else { if ( t_Key.GetAllocated () ) { m_Allocator.Delete ( t_Key.GetData () ) ; }
m_BlockAllocator.ReleaseBlock ( t_Block ) ;
return e_StatusCode_Success ; }
} while ( t_StatusCode == e_StatusCode_Success ) ;
if ( t_Key.GetAllocated () ) { m_Allocator.Delete ( t_Key.GetData () ) ; } } } return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: Insert (
const WmiBPKey &a_Key , const WmiBPElement &a_Element ) { #ifdef INSERT_DEBUG
OutputDebugString ( L"\n/**************************************" ) ; wchar_t t_StringBuffer [ 1024 ] ; swprintf ( t_StringBuffer , L"\nKey = %I64x" , * ( UINT64 * ) a_Key.GetConstData () ) ; OutputDebugString ( t_StringBuffer ) ; OutputDebugString ( L"\n======================================" ) ; #endif
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
if ( m_Root ) { WmiStack <WmiAbsoluteBlockOffSet,8> t_Stack ( m_Allocator ) ;
t_StatusCode = t_Stack.Initialize () ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = RecursiveInsert (
t_Stack , m_Root , a_Key , a_Element ) ; } } else { WmiAbsoluteBlockOffSet t_BlockOffSet = 0 ; BYTE *t_Block = NULL ; WmiStatusCode t_StatusCode = m_BlockAllocator.AllocateBlock (
1 , t_BlockOffSet , t_Block ) ;
if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
t_Node->SetFlags ( WMIBPLUS_TREE_FLAG_LEAF ) ; t_Node->SetNodeSize ( 1 ) ; t_Node->SetNodeOffSet ( t_BlockOffSet ) ; t_Node->SetNodeStart ( 0 ) ;
t_StatusCode = SetLeafNode (
t_Node , sizeof ( WmiBPKeyNode ) , a_Key , a_Element ) ;
if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & t_Node ) ; if ( t_StatusCode == e_StatusCode_Success ) { SetRoot ( t_BlockOffSet ) ; }
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } else {
m_BlockAllocator.ReleaseBlock ( t_Block ) ;
m_BlockAllocator.FreeBlock (
1 , t_BlockOffSet ) ; } } }
if ( t_StatusCode == e_StatusCode_Success ) { m_Size ++ ; }
#ifdef INSERT_DEBUG
OutputDebugString ( L"\n**************************************\\" ) ; #endif
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: StealSiblingNode (
WmiBPKeyNode *a_ParentNode , WmiAbsoluteBlockOffSet &a_ParentBlockOffSet , WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet , WmiRelativeBlockOffSet &a_PositionBlockOffSet , WmiBPKeyNode *a_SiblingNode , WmiAbsoluteBlockOffSet &a_SiblingBlockOffSet , WmiAbsoluteBlockOffSet &a_LeftSiblingBlockOffSet , WmiAbsoluteBlockOffSet &a_RightSiblingBlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
ULONG t_InternalKeySize ; ULONG t_KeyOffSet ; ULONG t_ElementOffSet ; ULONG t_PointerOffSet ;
#ifdef DELETE_DEBUG
OutputDebugString ( L"\nSteal Sibling" ) ; PrintNode ( L"\nParent" , a_ParentNode , a_ParentBlockOffSet ) ; PrintNode ( L"\nNode" , a_Node , a_BlockOffSet ) ; PrintNode ( L"\nSibling" , a_SiblingNode , a_SiblingBlockOffSet ) ; #endif
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_InternalKeySize = GetKeyTypeLength () + WmiBlockLeafKeyOffSet ; t_KeyOffSet = WmiBlockLeafKeyOffSet ; t_ElementOffSet = WmiBlockLeafKeyElementOffSet ; } else { t_InternalKeySize = GetKeyTypeLength () + WmiBlockKeyOffSet ; t_KeyOffSet = WmiBlockKeyOffSet ; t_ElementOffSet = WmiBlockKeyElementOffSet ; t_PointerOffSet = WmiBlockKeyPointerOffSet ; }
WmiAbsoluteBlockOffSet t_StartBlockOffSet = sizeof ( WmiBPKeyNode ) ;
if ( a_LeftSiblingBlockOffSet ) {
/*
* Shuffle node for insertion */
WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize ;
MoveMemory (
( ( BYTE * ) a_Node ) + t_StartBlockOffSet + t_InternalKeySize , ( ( BYTE * ) a_Node ) + t_StartBlockOffSet , ( ULONG ) t_TotalSize + t_InternalKeySize ) ;
/*
* Copy parent key down */
BYTE *t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ; BYTE *t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + t_KeyOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , GetKeyTypeLength () , ) ;
t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ; t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + t_ElementOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , sizeof ( WmiBPElement ) ) ; /*
* Copy from left */
t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + ( a_SiblingNode->GetNodeSize () - 1 ) * t_InternalKeySize + t_KeyOffSet ; t_ToBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , GetKeyTypeLength () , ) ;
t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + ( a_SiblingNode->GetNodeSize () - 1 ) * t_InternalKeySize + t_ElementOffSet ; t_ToBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , sizeof ( WmiBPElement ) ) ;
/*
* Copy pointers from sibling to node */
if ( t_Leaf == FALSE ) { t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + a_SiblingNode->GetNodeSize () * t_InternalKeySize + t_PointerOffSet ; t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + t_PointerOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , sizeof ( WmiAbsoluteBlockOffSet ) ) ; } } else { /*
* Copy parent key down */
BYTE *t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ; BYTE *t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_KeyOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , GetKeyTypeLength () , ) ;
t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ; t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_ElementOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , sizeof ( WmiBPElement ) ) ;
/*
* Copy from right */
t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + t_KeyOffSet ; t_ToBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , GetKeyTypeLength () , ) ;
t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + t_ElementOffSet ; t_ToBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , sizeof ( WmiBPElement ) ) ;
if ( t_Leaf == FALSE ) { t_FromBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + t_PointerOffSet ; t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_InternalKeySize + WmiBlockKeyPointerOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , sizeof ( WmiAbsoluteBlockOffSet ) ) ; }
/*
* Shuffle memory due to deletion */ WmiRelativeBlockOffSet t_TotalSize = a_SiblingNode->GetNodeSize () * t_InternalKeySize - t_InternalKeySize ;
MoveMemory (
( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet , ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + t_InternalKeySize , ( ULONG ) t_TotalSize + ( t_Leaf ? 0 : t_InternalKeySize ) ) ; }
a_Node->SetNodeSize ( a_Node->GetNodeSize () + 1 ) ; a_SiblingNode->SetNodeSize ( a_SiblingNode->GetNodeSize () - 1 ) ;
#ifdef DELETE_DEBUG
PrintNode ( L"\nParent" , a_ParentNode , a_ParentBlockOffSet ) ; PrintNode ( L"\nSibling" , a_SiblingNode , a_SiblingBlockOffSet ) ; PrintNode ( L"\nNode" , a_Node , a_BlockOffSet ) ; #endif
t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_SiblingNode ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_ParentNode ) ; } }
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: MergeSiblingNode (
WmiBPKeyNode *a_ParentNode , WmiAbsoluteBlockOffSet &a_ParentBlockOffSet , WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet , WmiRelativeBlockOffSet &a_PositionBlockOffSet , WmiBPKeyNode *a_SiblingNode , WmiAbsoluteBlockOffSet &a_SiblingBlockOffSet , WmiAbsoluteBlockOffSet &a_LeftSiblingBlockOffSet , WmiAbsoluteBlockOffSet &a_RightSiblingBlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
#ifdef DELETE_DEBUG
OutputDebugString ( L"\nMerging Node and Sibling" ) ; PrintNode ( L"\nParent" , a_ParentNode , a_ParentBlockOffSet ) ; PrintNode ( L"\nNode" , a_Node , a_BlockOffSet ) ; PrintNode ( L"\nSibling" , a_SiblingNode , a_SiblingBlockOffSet ) ; #endif
ULONG t_InternalKeySize ; ULONG t_KeyOffSet ; ULONG t_ElementOffSet ; ULONG t_PointerOffSet ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_InternalKeySize = GetKeyTypeLength () + WmiBlockLeafKeyOffSet ; t_KeyOffSet = WmiBlockLeafKeyOffSet ; t_ElementOffSet = WmiBlockLeafKeyElementOffSet ; } else { t_InternalKeySize = GetKeyTypeLength () + WmiBlockKeyOffSet ; t_KeyOffSet = WmiBlockKeyOffSet ; t_ElementOffSet = WmiBlockKeyElementOffSet ; t_PointerOffSet = WmiBlockKeyPointerOffSet ; }
WmiAbsoluteBlockOffSet t_StartBlockOffSet = sizeof ( WmiBPKeyNode ) ;
/*
* Copy sibling key up to parent */
if ( a_LeftSiblingBlockOffSet ) { /*
* Copy parent key down */ BYTE *t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ; BYTE *t_ToBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + a_SiblingNode->GetNodeSize () * t_InternalKeySize + t_KeyOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , GetKeyTypeLength () , ) ;
t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ; t_ToBuffer = ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + a_SiblingNode->GetNodeSize () * t_InternalKeySize + t_ElementOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , sizeof ( WmiBPElement ) ) ;
/*
* Copy node into sibling */
if ( t_Leaf ) { WmiRelativeBlockOffSet t_TotalSize = a_Node->GetNodeSize () * t_InternalKeySize ;
CopyMemory (
( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + a_SiblingNode->GetNodeSize () * t_InternalKeySize + t_InternalKeySize , ( ( BYTE * ) a_Node ) + t_StartBlockOffSet , ( ULONG ) t_TotalSize ) ; } else { WmiRelativeBlockOffSet t_TotalSize = a_Node->GetNodeSize () * t_InternalKeySize ;
CopyMemory (
( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet + a_SiblingNode->GetNodeSize () * t_InternalKeySize + t_InternalKeySize , ( ( BYTE * ) a_Node ) + t_StartBlockOffSet , ( ULONG ) t_TotalSize + t_InternalKeySize ) ; }
/*
* Shuffle memory due to deletion */
ULONG t_ParentInternalKeySize = WmiBlockKeyOffSet + GetKeyTypeLength () ;
WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + ( a_ParentNode->GetNodeSize () * t_ParentInternalKeySize ) ; WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - a_PositionBlockOffSet ; MoveMemory (
( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet , ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + t_ParentInternalKeySize , ( ULONG ) t_MoveSize ) ;
CopyMemory (
( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyPointerOffSet , ( BYTE * ) & a_SiblingBlockOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
a_ParentNode->SetNodeSize ( a_ParentNode->GetNodeSize () - 1 ) ; a_SiblingNode->SetNodeSize ( a_SiblingNode->GetNodeSize () + a_Node->GetNodeSize () + 1 ) ;
#ifdef DELETE_DEBUG
PrintNode ( L"\nParent" , a_ParentNode , a_ParentBlockOffSet ) ; PrintNode ( L"\nSibling" , a_SiblingNode , a_SiblingBlockOffSet ) ; #endif
t_StatusCode = m_BlockAllocator.FreeBlock ( 1 , a_BlockOffSet ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_SiblingNode ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_ParentNode ) ; } } } else { /*
* Copy parent key down */ BYTE *t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ; BYTE *t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_KeyOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , GetKeyTypeLength () , ) ;
t_FromBuffer = ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ; t_ToBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_ElementOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , sizeof ( WmiBPElement ) ) ;
/*
* Copy sibling into node */
if ( t_Leaf ) { WmiRelativeBlockOffSet t_TotalSize = a_SiblingNode->GetNodeSize () * t_InternalKeySize ;
CopyMemory (
( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_InternalKeySize , ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet , ( ULONG ) t_TotalSize ) ; } else { WmiRelativeBlockOffSet t_TotalSize = a_SiblingNode->GetNodeSize () * t_InternalKeySize ;
CopyMemory (
( ( BYTE * ) a_Node ) + t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize + t_InternalKeySize , ( ( BYTE * ) a_SiblingNode ) + t_StartBlockOffSet , ( ULONG ) t_TotalSize + t_InternalKeySize ) ; }
/*
* Shuffle memory due to deletion */
ULONG t_ParentInternalKeySize = WmiBlockKeyOffSet + GetKeyTypeLength () ;
WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + a_ParentNode->GetNodeSize () * t_ParentInternalKeySize ; WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - a_PositionBlockOffSet ; MoveMemory (
( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet , ( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + t_ParentInternalKeySize , ( ULONG ) t_MoveSize ) ;
CopyMemory (
( ( BYTE * ) a_ParentNode ) + a_PositionBlockOffSet + WmiBlockKeyPointerOffSet , ( BYTE * ) & a_BlockOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
a_ParentNode->SetNodeSize ( a_ParentNode->GetNodeSize () - 1 ) ; a_Node->SetNodeSize ( a_Node->GetNodeSize () + a_SiblingNode->GetNodeSize () + 1 ) ;
#ifdef DELETE_DEBUG
PrintNode ( L"\nParent" , a_ParentNode , a_ParentBlockOffSet ) ; PrintNode ( L"\nNode" , a_Node , a_BlockOffSet ) ; #endif
t_StatusCode = m_BlockAllocator.FreeBlock ( 1 , a_SiblingBlockOffSet ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_ParentNode ) ; } } }
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: LocateSuitableSibling (
WmiBPKeyNode *a_ParentNode , WmiAbsoluteBlockOffSet &a_ParentBlockOffSet , WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet , WmiRelativeBlockOffSet &a_PositionBlockOffSet , WmiAbsoluteBlockOffSet &a_LeftSiblingBlockOffSet , WmiAbsoluteBlockOffSet &a_RightSiblingBlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
ULONG t_InternalKeySize = GetKeyTypeLength () + WmiBlockKeyOffSet ;
ULONG t_NodeStart = a_ParentNode->GetNodeStart () ; ULONG t_NodeSize = a_ParentNode->GetNodeSize () ;
for ( ULONG t_Index = t_NodeStart ; t_Index <= t_NodeSize ; t_Index ++ ) { WmiAbsoluteBlockOffSet t_PointerBlockOffSet ;
CopyMemory (
( BYTE * ) & t_PointerBlockOffSet , ( ( BYTE * ) ( a_ParentNode ) ) + t_BlockOffSet + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
if ( t_PointerBlockOffSet == a_BlockOffSet ) { if ( t_Index ) { a_PositionBlockOffSet = t_BlockOffSet - t_InternalKeySize ;
CopyMemory (
( BYTE * ) & a_LeftSiblingBlockOffSet , ( ( BYTE * ) ( a_ParentNode ) ) + t_BlockOffSet - t_InternalKeySize + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
a_RightSiblingBlockOffSet = 0 ; } else { a_PositionBlockOffSet = t_BlockOffSet ;
a_LeftSiblingBlockOffSet = 0 ;
CopyMemory (
( BYTE * ) & a_RightSiblingBlockOffSet , ( ( BYTE * ) ( a_ParentNode ) ) + t_BlockOffSet + t_InternalKeySize + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ; }
return t_StatusCode ; }
t_BlockOffSet = t_BlockOffSet + t_InternalKeySize ; }
t_StatusCode = e_StatusCode_NotFound ;
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: DeleteReBalance (
WmiBPKeyNode *a_ParentNode , WmiAbsoluteBlockOffSet &a_ParentBlockOffSet , WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
WmiAbsoluteBlockOffSet t_StartBlockOffSet = sizeof ( WmiBPKeyNode ) ;
ULONG t_InternalKeySize = GetKeyTypeLength () + WmiBlockKeyOffSet ;
WmiRelativeBlockOffSet t_PositionBlockOffSet ; WmiAbsoluteBlockOffSet t_LeftSiblingBlockOffSet ; WmiAbsoluteBlockOffSet t_RightSiblingBlockOffSet ;
t_StatusCode = LocateSuitableSibling (
a_ParentNode , a_ParentBlockOffSet , a_Node , a_BlockOffSet , t_PositionBlockOffSet , t_LeftSiblingBlockOffSet , t_RightSiblingBlockOffSet ) ;
if ( t_StatusCode == e_StatusCode_Success ) { BYTE *t_Block = NULL ;
if ( t_LeftSiblingBlockOffSet ) { t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_LeftSiblingBlockOffSet , t_Block ) ; } else { t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_RightSiblingBlockOffSet , t_Block ) ; }
if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_SiblingNode = ( WmiBPKeyNode * ) t_Block ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; ULONG t_Balance = t_Leaf ? MaxLeafKeys () : MaxKeys () ;
if ( t_SiblingNode->GetNodeSize () > ( t_Balance >> 1 ) ) { /*
* Steal a key */
t_StatusCode = StealSiblingNode (
a_ParentNode , a_ParentBlockOffSet , a_Node , a_BlockOffSet , t_PositionBlockOffSet , t_SiblingNode , t_LeftSiblingBlockOffSet ? t_LeftSiblingBlockOffSet : t_RightSiblingBlockOffSet , t_LeftSiblingBlockOffSet , t_RightSiblingBlockOffSet ) ; } else { /*
* Merge sibling nodes */
t_StatusCode = MergeSiblingNode (
a_ParentNode , a_ParentBlockOffSet , a_Node , a_BlockOffSet , t_PositionBlockOffSet , t_SiblingNode , t_LeftSiblingBlockOffSet ? t_LeftSiblingBlockOffSet : t_RightSiblingBlockOffSet , t_LeftSiblingBlockOffSet , t_RightSiblingBlockOffSet ) ; }
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } }
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: RecursiveDeleteFixup (
WmiStack <WmiAbsoluteBlockOffSet,8> &a_Stack , WmiBPKeyNode *a_RootNode , WmiAbsoluteBlockOffSet &a_RootBlockOffSet , WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet , WmiRelativeBlockOffSet &a_PositionBlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
WmiAbsoluteBlockOffSet t_StartBlockOffSet = sizeof ( WmiBPKeyNode ) ;
ULONG t_InternalKeySize = GetKeyTypeLength () ; ULONG t_KeyOffSet ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_KeyOffSet = WmiBlockLeafKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ; } else { t_KeyOffSet = WmiBlockKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ; }
ULONG t_NodeSize = a_Node->GetNodeSize () ;
if ( t_Leaf ) { if ( a_RootBlockOffSet == a_BlockOffSet ) { /*
* Shuffle memory to remove deleted fixup node */
WmiRelativeBlockOffSet t_TotalSize = t_StartBlockOffSet + a_Node->GetNodeSize () * t_InternalKeySize ; WmiRelativeBlockOffSet t_MoveSize = t_TotalSize - a_PositionBlockOffSet - t_InternalKeySize ;
MoveMemory (
( ( BYTE * ) a_Node ) + a_PositionBlockOffSet , ( ( BYTE * ) a_Node ) + a_PositionBlockOffSet + t_InternalKeySize , ( ULONG ) t_MoveSize + ( t_Leaf ? 0 : t_InternalKeySize ) ) ; } else { /*
* Copy node up to place we deleted from. */
#ifdef DELETE_DEBUG
PrintNode ( L"\nCopy Down a_RootNode" , a_RootNode , a_RootBlockOffSet ) ; PrintNode ( L"\na_Node" , a_Node , a_BlockOffSet ) ; #endif
BYTE *t_FromBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + WmiBlockLeafKeyOffSet ; BYTE *t_ToBuffer = ( ( BYTE * ) a_RootNode ) + a_PositionBlockOffSet + WmiBlockKeyOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , GetKeyTypeLength () , ) ;
t_FromBuffer = ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + WmiBlockLeafKeyElementOffSet ; t_ToBuffer = ( ( BYTE * ) a_RootNode ) + a_PositionBlockOffSet + WmiBlockKeyElementOffSet ;
CopyMemory (
t_ToBuffer , t_FromBuffer , sizeof ( WmiBPElement ) ) ;
/*
* Shuffle memory to remove deleted fixup node */
WmiRelativeBlockOffSet t_TotalSize = a_Node->GetNodeSize () * t_InternalKeySize - t_InternalKeySize ;
MoveMemory (
( ( BYTE * ) a_Node ) + t_StartBlockOffSet , ( ( BYTE * ) a_Node ) + t_StartBlockOffSet + t_InternalKeySize , ( ULONG ) t_TotalSize + ( t_Leaf ? 0 : t_InternalKeySize ) ) ;
}
a_Node->SetNodeSize ( a_Node->GetNodeSize () - 1 ) ;
#ifdef DELETE_DEBUG
PrintNode ( L"\na_Node" , a_Node , a_BlockOffSet ) ; #endif
t_StatusCode = m_BlockAllocator.WriteBlock ( ( BYTE * ) & a_Node ) ; if ( t_StatusCode == e_StatusCode_Success ) { /*
* Finally re balance as required */
WmiBPKeyNode *t_Node = a_Node ; WmiAbsoluteBlockOffSet t_BlockOffSet = a_BlockOffSet ;
m_BlockAllocator.AddRefBlock ( ( BYTE * ) & a_Node ) ;
do { BOOL t_ReBalance ; if ( t_Leaf ) { t_ReBalance = t_Node->GetNodeSize () < ( MaxLeafKeys () >> 1 ) ? TRUE : FALSE ; } else { t_ReBalance = t_Node->GetNodeSize () < ( MaxKeys () >> 1 ) ? TRUE : FALSE ; }
if ( t_ReBalance ) { WmiAbsoluteBlockOffSet t_ParentOffSet = 0 ; WmiStatusCode t_TempStatusCode = a_Stack.Top ( t_ParentOffSet ) ; if ( t_TempStatusCode == e_StatusCode_Success ) { m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ;
BYTE *t_Block = NULL ; t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ParentOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_ParentNode = ( WmiBPKeyNode * ) t_Block ;
t_StatusCode = DeleteReBalance (
t_ParentNode , t_ParentOffSet , t_Node , t_BlockOffSet ) ;
t_Node = t_ParentNode ; t_BlockOffSet = t_ParentOffSet ; t_Leaf = ( ( t_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; }
a_Stack.Pop () ; } else { if ( t_Leaf ) { if ( t_Node->GetNodeSize () == 0 ) { if ( t_BlockOffSet == GetRoot () ) { SetRoot ( 0 ) ; }
m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ;
m_BlockAllocator.FreeBlock (
1 , t_BlockOffSet ) ; } else { m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ; } } else { if ( t_Node->GetNodeSize () == 0 ) { WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
CopyMemory (
( BYTE * ) & t_ChildOffSet , ( ( BYTE * ) ( t_Node ) ) + t_StartBlockOffSet + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
SetRoot ( t_ChildOffSet ) ;
m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ;
m_BlockAllocator.FreeBlock (
1 , t_BlockOffSet ) ; } else { m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ; } }
return t_StatusCode ; } } else { m_BlockAllocator.ReleaseBlock ( ( BYTE * ) & t_Node ) ;
return t_StatusCode ; }
} while ( t_StatusCode == e_StatusCode_Success ) ; } } else { WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
CopyMemory (
( BYTE * ) & t_ChildOffSet , ( ( BYTE * ) ( a_Node ) ) + t_StartBlockOffSet + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
BYTE *t_Block = NULL ; t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ChildOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
t_StatusCode = a_Stack.Push ( a_BlockOffSet ) ; if ( t_StatusCode == e_StatusCode_Success ) { RecursiveDeleteFixup (
a_Stack , a_RootNode , a_RootBlockOffSet , t_Node , t_ChildOffSet , a_PositionBlockOffSet ) ; }
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } }
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: DeleteFixup (
WmiStack <WmiAbsoluteBlockOffSet,8> &a_Stack , WmiBPKeyNode *a_Node , WmiAbsoluteBlockOffSet &a_BlockOffSet , WmiRelativeBlockOffSet &a_PositionBlockOffSet ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ;
WmiAbsoluteBlockOffSet t_BlockOffSet = sizeof ( WmiBPKeyNode ) ;
ULONG t_InternalKeySize = GetKeyTypeLength () ; ULONG t_KeyOffSet ;
BOOL t_Leaf = ( ( a_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf ) { t_KeyOffSet = WmiBlockLeafKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockLeafKeyOffSet ; } else { t_KeyOffSet = WmiBlockKeyOffSet ; t_InternalKeySize = t_InternalKeySize + WmiBlockKeyOffSet ; }
ULONG t_NodeSize = a_Node->GetNodeSize () ;
if ( t_Leaf ) { t_StatusCode = RecursiveDeleteFixup (
a_Stack , a_Node , a_BlockOffSet , a_Node , a_BlockOffSet , a_PositionBlockOffSet ) ; } else { /*
* Move right one and descend left most to get next key. */
WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ;
CopyMemory (
( BYTE * ) & t_ChildOffSet , ( ( BYTE * ) ( a_Node ) ) + a_PositionBlockOffSet + t_InternalKeySize + WmiBlockKeyPointerOffSet , sizeof ( WmiAbsoluteBlockOffSet ) ) ;
BYTE *t_Block = NULL ; t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , t_ChildOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_ChildNode = ( WmiBPKeyNode * ) t_Block ;
t_StatusCode = RecursiveDeleteFixup (
a_Stack , a_Node , a_BlockOffSet , t_ChildNode , t_ChildOffSet , a_PositionBlockOffSet ) ;
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } }
return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: RecursiveDelete (
WmiStack <WmiAbsoluteBlockOffSet,8> &a_Stack , WmiAbsoluteBlockOffSet &a_BlockOffSet , const WmiBPKey &a_Key , WmiBPElement &a_Element ) { WmiAbsoluteBlockOffSet t_ChildOffSet = 0 ; WmiBPElement t_Element = 0 ;
BYTE *t_Block = NULL ; WmiStatusCode t_StatusCode = m_BlockAllocator.ReadBlock ( 1 , a_BlockOffSet , t_Block ) ; if ( t_StatusCode == e_StatusCode_Success ) { WmiBPKeyNode *t_Node = ( WmiBPKeyNode * ) t_Block ;
WmiRelativeBlockOffSet t_NodeOffSet = 0 ; ULONG t_NodeIndex = 0 ;
t_StatusCode = FindInBlock (
t_Node , a_BlockOffSet , a_Key , t_ChildOffSet , t_Element , t_NodeOffSet , t_NodeIndex ) ;
if ( t_StatusCode == e_StatusCode_Success ) { if ( t_Element ) { BOOL t_Leaf = ( ( t_Node->GetFlags () & WMIBPLUS_TREE_FLAG_LEAF ) == WMIBPLUS_TREE_FLAG_LEAF ) ; if ( t_Leaf == FALSE ) { t_StatusCode = a_Stack.Push ( a_BlockOffSet ) ; }
if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = DeleteFixup (
a_Stack , t_Node , a_BlockOffSet , t_NodeOffSet ) ; } } else { t_StatusCode = a_Stack.Push ( a_BlockOffSet ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = RecursiveDelete (
a_Stack , t_ChildOffSet , a_Key , a_Element ) ; } } } else { t_StatusCode = e_StatusCode_NotFound ; }
m_BlockAllocator.ReleaseBlock ( t_Block ) ; } return t_StatusCode ; }
/******************************************************************************
* * Name: * * * Description: * * *****************************************************************************/
WmiStatusCode WmiBPlusTree :: Delete (
const WmiBPKey &a_Key , WmiBPElement &a_Element ) { #ifdef DELETE_DEBUG
OutputDebugString ( L"\n/**************************************" ) ; wchar_t t_StringBuffer [ 1024 ] ; swprintf ( t_StringBuffer , L"\nKey = %I64x" , * ( UINT64 * ) a_Key.GetConstData () ) ; OutputDebugString ( t_StringBuffer ) ; OutputDebugString ( L"\n======================================" ) ; #endif
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
if ( m_Root ) { WmiStack <WmiAbsoluteBlockOffSet,8> t_Stack ( m_Allocator ) ;
t_StatusCode = t_Stack.Initialize () ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = RecursiveDelete (
t_Stack , m_Root , a_Key , a_Element ) ; } } else { t_StatusCode = e_StatusCode_NotFound ; }
if ( t_StatusCode == e_StatusCode_Success ) { m_Size -- ; }
#ifdef DELETE_DEBUG
OutputDebugString ( L"\n**************************************\\" ) ; #endif
return t_StatusCode ; }
#endif _BPLUSTREE_CPP
|