232 lines
3.7 KiB
C++
232 lines
3.7 KiB
C++
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Microsoft Windows
|
|||
|
//
|
|||
|
// Copyright (C) Microsoft Corporation, 1994 - 1999
|
|||
|
//
|
|||
|
// File: hashtabl.hxx
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
hashtabl.hxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
interface for a hash table indexed by UUID
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Jeff Roberts (jroberts) 9-Nov-1994
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
9-Nov-1994 jroberts
|
|||
|
|
|||
|
Created this module.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#ifndef _HASHTABL_HXX_
|
|||
|
#define _HASHTABL_HXX_
|
|||
|
|
|||
|
#define NO_HASH ((unsigned)(-1))
|
|||
|
#define INVALID_NODE ((UUID_HASH_TABLE_NODE *) (-1))
|
|||
|
|
|||
|
|
|||
|
class UUID_HASH_TABLE_NODE
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
UUID_HASH_TABLE_NODE * pNext;
|
|||
|
UUID_HASH_TABLE_NODE * pPrev;
|
|||
|
|
|||
|
RPC_UUID Uuid;
|
|||
|
|
|||
|
UUID_HASH_TABLE_NODE(
|
|||
|
)
|
|||
|
{
|
|||
|
#ifdef DEBUGRPC
|
|||
|
|
|||
|
pNext = INVALID_NODE;
|
|||
|
pPrev = INVALID_NODE;
|
|||
|
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
UUID_HASH_TABLE_NODE(
|
|||
|
RPC_UUID * pNewUuid
|
|||
|
)
|
|||
|
{
|
|||
|
Initialize(pNewUuid);
|
|||
|
#ifdef DEBUGRPC
|
|||
|
|
|||
|
pNext = INVALID_NODE;
|
|||
|
pPrev = INVALID_NODE;
|
|||
|
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
inline void
|
|||
|
Initialize(
|
|||
|
RPC_UUID * pNewUuid
|
|||
|
)
|
|||
|
{
|
|||
|
Uuid = *pNewUuid;
|
|||
|
}
|
|||
|
|
|||
|
int
|
|||
|
CompareUuid(
|
|||
|
void * Buffer
|
|||
|
)
|
|||
|
{
|
|||
|
RPC_UUID * UuidBuffer = (RPC_UUID *) Buffer;
|
|||
|
return Uuid.MatchUuid(UuidBuffer);
|
|||
|
}
|
|||
|
|
|||
|
inline void
|
|||
|
VerifyFree(
|
|||
|
)
|
|||
|
{
|
|||
|
ASSERT(pNext == INVALID_NODE);
|
|||
|
ASSERT(pPrev == INVALID_NODE);
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
QueryUuid(
|
|||
|
void * Buffer
|
|||
|
)
|
|||
|
{
|
|||
|
RPC_UUID * UuidBuffer = (RPC_UUID *) Buffer;
|
|||
|
*UuidBuffer = Uuid;
|
|||
|
}
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
class UUID_HASH_TABLE
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
UUID_HASH_TABLE(
|
|||
|
RPC_STATUS * pStatus,
|
|||
|
unsigned long SpinCount = 0
|
|||
|
);
|
|||
|
|
|||
|
~UUID_HASH_TABLE();
|
|||
|
|
|||
|
unsigned
|
|||
|
Add(
|
|||
|
UUID_HASH_TABLE_NODE * pNode,
|
|||
|
unsigned Hash = NO_HASH
|
|||
|
);
|
|||
|
|
|||
|
void
|
|||
|
Remove(
|
|||
|
UUID_HASH_TABLE_NODE * pNode,
|
|||
|
unsigned Hash = NO_HASH
|
|||
|
);
|
|||
|
|
|||
|
inline UUID_HASH_TABLE_NODE *
|
|||
|
Lookup(
|
|||
|
RPC_UUID * Uuid,
|
|||
|
unsigned Hash = NO_HASH
|
|||
|
);
|
|||
|
|
|||
|
inline unsigned
|
|||
|
MakeHash(
|
|||
|
RPC_UUID * Uuid
|
|||
|
)
|
|||
|
{
|
|||
|
return (Uuid->HashUuid() & BUCKET_COUNT_MASK);
|
|||
|
}
|
|||
|
|
|||
|
protected:
|
|||
|
|
|||
|
inline void
|
|||
|
RequestHashMutex(
|
|||
|
unsigned Hash
|
|||
|
)
|
|||
|
{
|
|||
|
BucketMutexes[Hash % MUTEX_COUNT]->Request();
|
|||
|
}
|
|||
|
|
|||
|
inline void
|
|||
|
ReleaseHashMutex(
|
|||
|
unsigned Hash
|
|||
|
)
|
|||
|
{
|
|||
|
BucketMutexes[Hash % MUTEX_COUNT]->Clear();
|
|||
|
}
|
|||
|
|
|||
|
enum
|
|||
|
{
|
|||
|
// number of hash buckets
|
|||
|
//
|
|||
|
BUCKET_COUNT = 128,
|
|||
|
|
|||
|
// XOR this with any number to get a hash bucket index
|
|||
|
//
|
|||
|
BUCKET_COUNT_MASK = 0x007f,
|
|||
|
|
|||
|
MUTEX_COUNT = 4
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
#ifdef DEBUGRPC
|
|||
|
unsigned Counts[BUCKET_COUNT];
|
|||
|
#endif
|
|||
|
|
|||
|
// hash buckets - each bucket has a linked list of nodes
|
|||
|
// in no particular order
|
|||
|
//
|
|||
|
UUID_HASH_TABLE_NODE * Buckets[BUCKET_COUNT];
|
|||
|
|
|||
|
// a mutex protexts each bucket
|
|||
|
//
|
|||
|
MUTEX * BucketMutexes[MUTEX_COUNT];
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
UUID_HASH_TABLE_NODE *
|
|||
|
UUID_HASH_TABLE::Lookup(
|
|||
|
RPC_UUID * Uuid,
|
|||
|
unsigned Hash
|
|||
|
)
|
|||
|
{
|
|||
|
if (Hash == NO_HASH)
|
|||
|
{
|
|||
|
Hash = MakeHash(Uuid);
|
|||
|
}
|
|||
|
|
|||
|
ASSERT( Hash < BUCKET_COUNT );
|
|||
|
|
|||
|
UUID_HASH_TABLE_NODE * pScan = Buckets[Hash];
|
|||
|
while (pScan)
|
|||
|
{
|
|||
|
if (0 == Uuid->MatchUuid(&pScan->Uuid))
|
|||
|
{
|
|||
|
return pScan;
|
|||
|
}
|
|||
|
|
|||
|
if (pScan->pNext && pScan->pNext->pPrev != pScan)
|
|||
|
{
|
|||
|
#ifdef NTENV
|
|||
|
DbgBreakPoint();
|
|||
|
#else
|
|||
|
RpcpBreakPoint();
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
pScan = pScan->pNext;
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
#endif // _HASHTABL_HXX_
|
|||
|
|