windows-nt/Source/XPSP1/NT/com/rpc/runtime/mtrt/hashtabl.hxx
2020-09-26 16:20:57 +08:00

232 lines
3.7 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//+-------------------------------------------------------------------------
//
// 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_