Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
#include <precomp.h>
CTreeElement :: CTreeElement(LPCWSTR lpszHashedName, CRefCountedObject *pObject) { m_lpszHashedName = new WCHAR[wcslen(lpszHashedName) + 1]; wcscpy(m_lpszHashedName, lpszHashedName);
m_pObject = pObject; m_pObject->AddRef(); m_pLeft = NULL; m_pRight = NULL; }
CTreeElement :: ~CTreeElement() { if (m_lpszHashedName) { delete [] m_lpszHashedName; } m_pObject->Release(); }
LPCWSTR CTreeElement :: GetHashedName() const { return m_lpszHashedName; }
CRefCountedObject *CTreeElement :: GetObject() const { m_pObject->AddRef(); return m_pObject; }
CTreeElement *CTreeElement :: GetRight() const { return m_pRight; }
CTreeElement *CTreeElement :: GetLeft() const { return m_pLeft; }
void CTreeElement :: SetRight(CTreeElement *pNext) { m_pRight = pNext; }
void CTreeElement :: SetLeft(CTreeElement *pNext) { m_pLeft = pNext; }
CObjectTree :: CObjectTree() { // Initialize the critical section
InitializeCriticalSection(&m_ModificationSection);
m_dwNumElements = 0; m_pHead = NULL;
}
CObjectTree :: ~CObjectTree() { // Destroy the data
DeleteTree();
// Destroy the critical section
DeleteCriticalSection(&m_ModificationSection);
}
void CObjectTree :: DeleteTree() { EnterCriticalSection(&m_ModificationSection); if(m_pHead) DeleteSubTree(m_pHead); m_dwNumElements = 0; LeaveCriticalSection(&m_ModificationSection); }
void CObjectTree :: DeleteSubTree(CTreeElement *pRoot) { if(pRoot->GetLeft()) DeleteSubTree(pRoot->GetLeft()); if(pRoot->GetRight()) DeleteSubTree(pRoot->GetRight()); delete pRoot; }
BOOLEAN CObjectTree :: AddElement(LPCWSTR lpszHashedName, CRefCountedObject *pObject) { BOOLEAN retVal = TRUE;
EnterCriticalSection(&m_ModificationSection); CTreeElement *pCurrent = m_pHead; CTreeElement *pParent = NULL; int iCompare; // Locate the position where the new element is to be inserted
while(pCurrent) { iCompare = _wcsicmp(lpszHashedName, pCurrent->GetHashedName()); if(iCompare == 0) { retVal = FALSE; // The element already exists
break; } else if(iCompare > 0) { pParent = pCurrent; pCurrent = pCurrent->GetRight(); } else { pParent = pCurrent; pCurrent = pCurrent->GetLeft(); } }
// Create the new element at the appropriate position
if(retVal == TRUE && pParent) { iCompare = _wcsicmp(lpszHashedName, pParent->GetHashedName()); if(iCompare == 0) retVal = FALSE; else if(iCompare > 0) { retVal = TRUE; pParent->SetRight(new CTreeElement(lpszHashedName, pObject)); } else { retVal = TRUE; pParent->SetLeft(new CTreeElement(lpszHashedName, pObject)); } } else if (retVal == TRUE) { m_pHead = new CTreeElement(lpszHashedName, pObject); retVal = TRUE; } // Increment the object count if the insertion was successful
if(retVal) m_dwNumElements ++;
LeaveCriticalSection(&m_ModificationSection); return retVal; }
BOOLEAN CObjectTree :: DeleteElement(LPCWSTR lpszHashedName) { BOOLEAN retVal = FALSE; int iDirection = 0; // 0 indicates Unknown, 1 indicates LEFT and 2 indicates RIGHT
EnterCriticalSection(&m_ModificationSection); if(m_pHead == NULL) retVal = FALSE; else { // Find the node to be deleted and its parent
CTreeElement *pParent = NULL; CTreeElement *pCurrent = m_pHead; int iCompare; while(pCurrent) { iCompare = _wcsicmp(lpszHashedName, pCurrent->GetHashedName()); if(iCompare == 0) break; else if(iCompare < 0) { iDirection = 1; pParent = pCurrent; pCurrent = pCurrent->GetLeft(); } else { iDirection = 2; pParent = pCurrent; pCurrent = pCurrent->GetRight(); } }
if(!pCurrent) // The element was not found
retVal = FALSE; else { CTreeElement *pCutPart = NULL;
// If its left child is null, attach the right subtree to parent
if(pCurrent->GetLeft() == NULL) pCutPart = pCurrent->GetRight(); // If its right child is null, attach the left subtree to parent
else if(pCurrent->GetRight() == NULL) pCutPart = pCurrent->GetLeft(); else // We need to find the inorder successor
{ CTreeElement *pInorderSuccessor = pCurrent->GetRight(); if(pInorderSuccessor->GetLeft() == NULL) { pInorderSuccessor->SetLeft(pCurrent->GetLeft()); pCutPart = pInorderSuccessor; } else { CTreeElement *pPredecessor = pCurrent->GetRight(); pInorderSuccessor = pPredecessor->GetLeft(); while(pInorderSuccessor->GetLeft()) { pPredecessor = pInorderSuccessor; pInorderSuccessor = pPredecessor->GetLeft(); } pPredecessor->SetLeft(pInorderSuccessor->GetRight()); pInorderSuccessor->SetLeft(pCurrent->GetLeft()); pInorderSuccessor->SetRight(pCurrent->GetRight()); pCutPart = pInorderSuccessor; } }
if(iDirection == 0) m_pHead = pCutPart; else if (iDirection == 1) pParent->SetLeft(pCutPart); else pParent->SetRight(pCutPart);
delete pCurrent; retVal = TRUE;
} } // Decrement the count of items in the tree
if(retVal) m_dwNumElements --;
LeaveCriticalSection(&m_ModificationSection);
return retVal; }
CRefCountedObject * CObjectTree :: GetElement(LPCWSTR lpszHashedName) { EnterCriticalSection(&m_ModificationSection); CTreeElement *pCurrent = m_pHead; CRefCountedObject *pRetVal = NULL;
int iCompare; while(pCurrent) { iCompare = _wcsicmp(lpszHashedName, pCurrent->GetHashedName()); if(iCompare == 0) { pRetVal = pCurrent->GetObject(); break; } else if (iCompare > 0) pCurrent = pCurrent->GetRight(); else pCurrent = pCurrent->GetLeft(); } LeaveCriticalSection(&m_ModificationSection); return pRetVal; }
BOOLEAN CObjectTree :: DeleteLeastRecentlyAccessedElement() { BOOLEAN retVal = FALSE; EnterCriticalSection(&m_ModificationSection); if(m_pHead) { CRefCountedObject *pOldestElement = m_pHead->GetObject(); CRefCountedObject *pLeftOldestElement = GetLeastRecentlyAccessedElementRecursive(m_pHead->GetLeft()); CRefCountedObject *pRightOldestElement = GetLeastRecentlyAccessedElementRecursive(m_pHead->GetRight());
if (pLeftOldestElement) { if(pLeftOldestElement->GetLastAccessTime() < pOldestElement->GetLastAccessTime()) { pOldestElement->Release(); pOldestElement = pLeftOldestElement; } else pLeftOldestElement->Release(); }
if (pRightOldestElement) { if(pRightOldestElement->GetLastAccessTime() < pOldestElement->GetLastAccessTime()) { pOldestElement->Release(); pOldestElement = pRightOldestElement; } else pRightOldestElement->Release(); }
retVal = DeleteElement(pOldestElement->GetName()); pOldestElement->Release(); } LeaveCriticalSection(&m_ModificationSection); return retVal; }
CRefCountedObject * CObjectTree :: GetLeastRecentlyAccessedElementRecursive(CTreeElement *pElement) { CRefCountedObject *pObject = NULL; if(pElement) { pObject = pElement->GetObject(); CRefCountedObject *pLeftObject = GetLeastRecentlyAccessedElementRecursive(pElement->GetLeft()); if(pLeftObject) { if(pLeftObject->GetCreationTime() < pObject->GetCreationTime()) { pObject->Release(); pObject = pLeftObject; } else pLeftObject->Release(); }
CRefCountedObject *pRightObject = GetLeastRecentlyAccessedElementRecursive(pElement->GetRight()); if(pRightObject) { if (pRightObject->GetCreationTime() < pObject->GetCreationTime()) { pObject->Release(); pObject = pRightObject; } else pRightObject->Release(); }
}
return pObject; }
|