mirror of https://github.com/tongzx/nt5src
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.
231 lines
3.7 KiB
231 lines
3.7 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// 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_
|
|
|