159 lines
3.4 KiB
C
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
|