Source code of Windows XP (NT5)
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.
|
|
/*===================================================================
Microsoft Denali
Microsoft Confidential. Copyright 1996 Microsoft Corporation. All Rights Reserved.
Component: Hash table for Script Manager
File: SMHash.cpp
Owner: AndrewS
This is the Link list and Hash table for use by the Script Manager only ===================================================================*/ #include "denpre.h"
#pragma hdrstop
#include "memchk.h"
/*===================================================================
CSMHash::AddElem
Adds a CLruLinkElem to the SM Hash table. User is responsible for allocating the Element to be added.
Note: This is identical to the standard CHashTable::AddElem, except that it allows for elements with duplicate names
Parameters: CLruLinkElem *pElem Object to be added
Returns: Pointer to element added/found. ===================================================================*/ CLruLinkElem *CSMHash::AddElem ( CLruLinkElem *pElem ) { AssertValid();
if (m_rgpBuckets == NULL) { if (FAILED(AllocateBuckets())) return NULL; } if (pElem == NULL) return NULL;
UINT iBucket = m_pfnHash(pElem->m_pKey, pElem->m_cbKey) % m_cBuckets; CLruLinkElem * pT = static_cast<CLruLinkElem *>(m_rgpBuckets[iBucket]); while (pT) { if (pT->m_Info > 0) pT = static_cast<CLruLinkElem *>(pT->m_pNext); else break; }
if (pT) { // There are other elements in bucket
pT = static_cast<CLruLinkElem *>(m_rgpBuckets[iBucket]); m_rgpBuckets[iBucket] = pElem; pElem->m_Info = pT->m_Info + 1; pElem->m_pNext = pT; pElem->m_pPrev = pT->m_pPrev; pT->m_pPrev = pElem; if (pElem->m_pPrev == NULL) m_pHead = pElem; else pElem->m_pPrev->m_pNext = pElem; } else { // This is the first element in the bucket
m_rgpBuckets[iBucket] = pElem; pElem->m_pPrev = NULL; pElem->m_pNext = m_pHead; pElem->m_Info = 0; if (m_pHead) m_pHead->m_pPrev = pElem; else m_pTail = pElem; m_pHead = pElem; } m_Count++; pElem->PrependTo(m_lruHead); AssertValid(); return pElem; }
/*===================================================================
CSMHash::FindElem
Finds a script engine element in the hash table based on the name and language type.
Parameters: void * pKey - the key to look for int cbKey - length of the key to look for PROGLANG_ID proglang_id - program language name DWORD dwInstanceID - instance ID to find BOOL fCheckLoaded - if true, only return engines flagged as "loaded"
Returns: Pointer to CLruLinkElem if found, otherwise NULL. ===================================================================*/ CLruLinkElem * CSMHash::FindElem ( const void *pKey, int cbKey, PROGLANG_ID proglang_id, DWORD dwInstanceID, BOOL fCheckLoaded ) { AssertValid(); if (m_rgpBuckets == NULL || pKey == NULL) return NULL;
UINT iBucket = m_pfnHash(static_cast<const BYTE *>(pKey), cbKey) % m_cBuckets; CLruLinkElem * pT = static_cast<CLruLinkElem *>(m_rgpBuckets[iBucket]); CLruLinkElem * pRet = NULL;
/*
* We have the right bucket based on the hashed name. * Search through the bucket chain looking for elements whose name * is correct (multiple names can hash to the same bucket), and * whose language is the one we want, and (optionally) skip * elements that are not fully "loaded" * * Note: This all relys on intimate knowlege of the format of an ActiveScriptEngine. * these elements better be ASE's. */ while (pT && pRet == NULL) { if (FIsEqual(pT->m_pKey, pT->m_cbKey, pKey, cbKey)) { CASEElem *pASEElem = static_cast<CASEElem *>(pT); Assert(pASEElem != NULL); CActiveScriptEngine *pASE = pASEElem->PASE(); Assert(pASE != NULL); // Element has the right name. Is it really the one we want?
if (proglang_id != pASE->ProgLang_Id()) goto LNext;
if (dwInstanceID != pASE->DWInstanceID()) goto LNext;
if (fCheckLoaded && !pASE->FFullyLoaded()) goto LNext;
// Yup, its the right one!
pRet = pT; break; } LNext: if (pT->m_Info > 0) pT = static_cast<CLruLinkElem *>(pT->m_pNext); else { // got to the last element in this bucket chain
break; } } if (pRet) pRet->PrependTo(m_lruHead);
AssertValid(); return pRet; }
|