windows-nt/Source/XPSP1/NT/termsrv/remdsk/rds/as/h/ch.h
2020-09-26 16:20:57 +08:00

159 lines
3.4 KiB
C

//
// CH.H
// Cache Handler
//
// Copyright (c) Microsoft 1997-
//
#ifndef _H_CH
#define _H_CH
//
//
// DEFINES
//
//
#define CH_NUM_EVICTION_CATEGORIES 3
//
// NOTES:
// 64K limit on cache
// CHCACHE includes one entry, so only subtract out header part
//
#define CH_MAX_CACHE_ENTRIES \
( (65535 - (sizeof(CHCACHE) - sizeof(CHENTRY))) / sizeof(CHENTRY) )
//
//
// TYPEDEFS
//
//
typedef struct tagCHCHAIN
{
WORD next;
WORD prev;
} CHCHAIN;
typedef CHCHAIN * PCHCHAIN;
//
// There are going to be thousands of cache entries so we need to keep
// the header as compact as possible. We could drop the eviction
// category, but it is useful info and does round the entry to 16 bytes
// which makes indexing efficient.
//
// Note that the 16 bit code is restricted to 4096 entries unless we take
// steps to allow huge addressing of the entry array.
//
//
// CHENTRY
// Cache entry in a Cache tree
//
typedef struct tagCHENTRY
{
struct tagCHENTRY * pParent;
struct tagCHENTRY * pLeft;
struct tagCHENTRY * pRight;
WORD lHeight;
WORD rHeight;
UINT cbData;
LPBYTE pData;
UINT checkSum;
CHCHAIN chain;
WORD evictionCategory;
WORD free;
} CHENTRY;
typedef CHENTRY * PCHENTRY;
//
// A CACHE
//
// FORWARD DECLARATION
typedef struct tagCHCACHE * PCHCACHE;
#ifdef __cplusplus
typedef void (* PFNCACHEDEL)(class ASHost * pHost, PCHCACHE pCache, UINT iEntry, LPBYTE pData);
//
// Each cache may have several eviction categories. These allow the caller
// to define classes of data so that it can control what is evicted from
// the cache. To be a candidate for eviction the eviction class of a LRU
// entry must match, unless the number of entries in that category is
// less than the eviction threshold, in which case any cache entry is
// up for grabs.
//
// The EvictionThreshold() function can be used to tune eviction thresholds
// which default to cEntries/cNumEvictionCategories
//
typedef struct tagCHCACHE
{
STRUCTURE_STAMP
PFNCACHEDEL pfnCacheDel;
UINT cEntries;
UINT cNumEvictionCategories;
UINT cbNotHashed;
//
// NOTE: CH_NUM_EVICTION_CATEGORIES is 3, so 3 words + 3 words +
// 3 words == 9 words, not DWORD aligned. Hence we stick the WORD
// field free after iMRUTail. If CH_NUM_EVICTION_CATEGORIES ever
// changes to an even value, reshuffle this structure.
//
WORD cEvictThreshold[CH_NUM_EVICTION_CATEGORIES];
WORD iMRUHead[CH_NUM_EVICTION_CATEGORIES];
WORD iMRUTail[CH_NUM_EVICTION_CATEGORIES];
WORD free;
PCHENTRY pRoot;
PCHENTRY pFirst;
PCHENTRY pLast;
CHENTRY Entry[1];
}
CHCACHE;
typedef CHCACHE * PCHCACHE;
#endif // __cplusplus
//
//
// MACROS
//
//
//
// BOGUS LAURABU
// In future, have debug signatures at front of objects to catch heap corruption
//
#define IsValidCache(pCache) \
(!IsBadWritePtr((pCache), sizeof(CHCACHE)))
#define IsValidCacheEntry(pEntry) \
(!IsBadWritePtr((pEntry), sizeof(CHENTRY)))
#define IsValidCacheIndex(pCache, iEntry) \
((iEntry >= 0) && (iEntry < (pCache)->cEntries))
#define IsCacheEntryInTree(pEntry) \
(((pEntry)->lHeight != 0xFFFF) && ((pEntry)->rHeight != 0xFFFF))
#endif // _H_CH