Source code of Windows XP (NT5)
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.

546 lines
11 KiB

  1. /*++
  2. CacheMt.h
  3. This header file defines a template for
  4. --*/
  5. #ifndef _CACHEMT_H_
  6. #define _CACHEMT_H_
  7. // This callback function is used to issue a stop hint during a
  8. // long spin while shutting down so that the shutdown won't time
  9. // out.
  10. typedef void (*PSTOPHINT_FN)();
  11. #include "smartptr.h"
  12. #include <fhashex.h>
  13. #include <mtlib.h>
  14. #include "cachemti.h"
  15. //
  16. // This is a little helper function for _ASSERT's - returns
  17. // TRUE if lpv is an address on the calling thread's stack !
  18. //
  19. BOOL
  20. FOnMyStack( LPVOID lpv ) ;
  21. //
  22. // CacheCallback class - clients can pass an object derived from
  23. // this into the Cache for functions which require some kind of user
  24. // callback processing !
  25. //
  26. template< class Data >
  27. class CacheCallback {
  28. public :
  29. virtual BOOL fRemoveCacheItem( Data& d ) {
  30. return FALSE ;
  31. }
  32. } ;
  33. template< class Data,
  34. class Key,
  35. class Constructor
  36. >
  37. class CacheImp : public CacheSelector
  38. {
  39. //
  40. // This class exists to implement a generic Caching system.
  41. // We assume that only a single thread ever enters any of our
  42. // API's at a time. This class is not to be directly exposed
  43. // to customers, instead CacheInterface<> exists to provide
  44. // an API for customers.
  45. //
  46. public :
  47. //
  48. // Defines an element of the cache !
  49. //
  50. typedef TEntry< Data, Key > TENTRY ;
  51. private :
  52. //
  53. // A signature DWORD for identifying these things in memory !
  54. //
  55. DWORD m_dwSignature ;
  56. //
  57. // Define the hashtable we use to hold Cache Elements !
  58. //
  59. typedef TFHashEx< TENTRY, Key > CACHELOOKUP ;
  60. //
  61. // The hash table we use to keep track of entries in the cache !
  62. //
  63. CACHELOOKUP m_Lookup ;
  64. //
  65. // This is the doubly linked list of elements in our cache !
  66. //
  67. CacheList m_ExpireList ;
  68. //
  69. // The number of subtract from the current time to
  70. // determine our expire date !
  71. //
  72. ULARGE_INTEGER m_qwExpire ;
  73. public :
  74. //
  75. // The following structures and functions define the
  76. // portion of our interface designed to work with ASYNC
  77. // mechanisms provide by TMtService<>
  78. //
  79. //
  80. // Defines the structure that holds all of the
  81. // arguments for FindOrCreate
  82. // We wrap this stuff all into one struct to make it
  83. // easy to use the TMtServce<> family of templates !
  84. //
  85. struct FORC_ARG {
  86. DWORD m_dwHash ;
  87. Key& m_key ;
  88. Constructor& m_constructor ;
  89. FORC_ARG( DWORD dw,
  90. Key& key,
  91. Constructor& constructor
  92. ) :
  93. m_dwHash( dw ),
  94. m_key( key ),
  95. m_constructor( constructor ) {
  96. }
  97. } ;
  98. //
  99. // Define the object that selects items for removal from the
  100. // Cache -
  101. //
  102. typedef CacheCallback< Data > CCB_OBJ ;
  103. //
  104. // Arguments for Expunge !
  105. //
  106. struct EXP_ARG {
  107. Key* m_pkey ;
  108. TENTRY* m_pData ;
  109. EXP_ARG( Key* pkey, TENTRY* pData ) :
  110. m_pkey( pkey ),
  111. m_pData( pData ) {
  112. }
  113. } ;
  114. //
  115. // Define the structure that holds all arguments for
  116. // Expunge interface.
  117. //
  118. struct EXP_SPECIFIC_ARG {
  119. //
  120. // The object which selects what is to be removed from the cache
  121. //
  122. CCB_OBJ* m_pCacheCallback ;
  123. //
  124. // A pointer to an entry which should NOT be removed !
  125. //
  126. TENTRY* m_pProtected ;
  127. //
  128. // If TRUE kick things out even if they aren't ready to expire !
  129. //
  130. BOOL m_fForced ;
  131. EXP_SPECIFIC_ARG( CCB_OBJ* pCallback,
  132. TENTRY* pProtected,
  133. BOOL fForced
  134. ) :
  135. m_pCacheCallback( pCallback ),
  136. m_pProtected( pProtected ),
  137. m_fForced( fForced ) {
  138. }
  139. } ;
  140. protected :
  141. //
  142. // When Executing ExpungeSpecific() - this holds onto the user
  143. // provided Callback for selecting deleted items !
  144. //
  145. CCB_OBJ* m_pCurrent ;
  146. //
  147. // This member function removes entries from the cache -
  148. // we remove them from the hash table which leads to destruction !
  149. //
  150. void
  151. RemoveEntry(
  152. CacheState* pCacheState
  153. ) ;
  154. //
  155. // This function checks to see whether we wish to remove an element !
  156. //
  157. BOOL
  158. QueryRemoveEntry(
  159. CacheState* pState
  160. ) ;
  161. //
  162. // FindOrCreate results
  163. //
  164. typedef CRefPtr< Data > FORC_RES ;
  165. public :
  166. CacheImp() ;
  167. //
  168. // If this function returns TRUE then callers can be
  169. // notified at arbitrary times of the results.
  170. // The BOOL return value is required by the TMtService templates.
  171. //
  172. //
  173. BOOL
  174. FindOrCreate(
  175. FORC_ARG& args,
  176. FORC_RES& result
  177. ) ;
  178. //
  179. // This function removes specified items from the cache !
  180. //
  181. BOOL
  182. Expunge(
  183. EXP_ARG& args,
  184. DWORD& countExpunged
  185. ) ;
  186. BOOL
  187. ExpungeSpecific(
  188. EXP_SPECIFIC_ARG& args,
  189. DWORD& countExpunged
  190. ) ;
  191. BOOL
  192. Expire(
  193. DWORD& countExpunged
  194. ) ;
  195. //
  196. // The following set of functions are for synchronous use
  197. // such as Initialization and Termination of the Cache.
  198. //
  199. //
  200. // Initialization function - take pointer to function
  201. // which should be used to compute hash values on Key's
  202. // Also takes the number of seconds objects should live in
  203. // the cache !
  204. //
  205. BOOL
  206. Init(
  207. DWORD (*pfnHash)( const Key& ),
  208. DWORD dwLifetimeSeconds,
  209. DWORD cMaxInstances,
  210. PSTOPHINT_FN pfnStopHint = NULL
  211. ) ;
  212. //
  213. // Compute the hash of a key - provided for debug purposes and _ASSERT's
  214. // not for regular use !
  215. //
  216. DWORD
  217. ComputeHash( Key& k ) ;
  218. } ;
  219. template< class Data,
  220. class Key,
  221. class Constructor >
  222. class TAsyncCache {
  223. public :
  224. //
  225. // The template class that implements the Cache.
  226. //
  227. typedef CacheImp< Data, Key, Constructor > IMP ;
  228. private:
  229. //
  230. // Singature for identifying these Async Cache things
  231. //
  232. DWORD m_dwSignature ;
  233. //
  234. // This is the object which actually implements the Cache functionality
  235. // NOTE: appears before CACHE_SERVICE so its constructor is called first !
  236. //
  237. IMP m_Implementation ;
  238. public :
  239. //
  240. // A typedef for the objects we will take in our
  241. // interface which get completion notifications.
  242. //
  243. typedef TCompletion< IMP::FORC_RES > COMP_OBJ ;
  244. //
  245. // A typedef for the objects which handle Expunge Completions !
  246. // The completion function gets the number of objects expunged
  247. // from the cache !
  248. //
  249. typedef TCompletion< DWORD > EXP_COMP_OBJ ;
  250. //
  251. // Some typedefs so that users can extract our template parameters
  252. // back out !
  253. //
  254. typedef Data CACHEDATA ;
  255. typedef Key CACHEKEY ;
  256. private :
  257. //
  258. // The kind of object we use to encapsulate a call
  259. // to the cache.
  260. //
  261. typedef TMFnDelay<
  262. IMP,
  263. IMP::FORC_RES,
  264. IMP::FORC_ARG
  265. > CACHE_CREATE_CALL ;
  266. //
  267. // The kind of object we use to encapsulate an Expunge Call
  268. //
  269. typedef TMFnDelay<
  270. IMP,
  271. DWORD,
  272. IMP::EXP_ARG
  273. > EXPUNGE_CALL ;
  274. typedef TMFnDelay<
  275. IMP,
  276. DWORD,
  277. IMP::EXP_SPECIFIC_ARG
  278. > EXPUNGE_SPECIFIC ;
  279. typedef TMFnNoArgDelay<
  280. IMP,
  281. DWORD
  282. > EXPIRE_CALL ;
  283. //
  284. // Define the type of our CACHE_SERVICE
  285. //
  286. typedef TMtService< IMP > CACHE_SERVICE ;
  287. //
  288. // This is the object which manages the Queue of Async Cache requests !
  289. //
  290. CACHE_SERVICE m_Service ;
  291. //
  292. // Set to TRUE if we have been successfully initialized.
  293. //
  294. BOOL m_fGood ;
  295. public :
  296. //
  297. // Default constructor
  298. //
  299. TAsyncCache() ;
  300. //
  301. // Find an Item in the Cache or Create an Item to be held in the Cache !
  302. //
  303. BOOL
  304. FindOrCreate( CStateStackInterface& allocator,
  305. DWORD dwHash,
  306. Key& key,
  307. Constructor& constructor,
  308. COMP_OBJ* pComplete ) ;
  309. //
  310. // Remove an Item from the cache !
  311. //
  312. //
  313. // Function which can be used to remove items from the Cache
  314. //
  315. BOOL
  316. Expunge(
  317. CStateStackInterface& allocator,
  318. EXP_COMP_OBJ* pComplete,
  319. Key* key = 0,
  320. IMP::TENTRY* pData = 0
  321. ) ;
  322. //
  323. // Function which can be passed a function pointer to determine
  324. // exactly what items are to be removed from the Cache.
  325. // if fForced == TRUE then items are removed from the Cache
  326. // no matter what.
  327. //
  328. BOOL
  329. ExpungeSpecific(
  330. CStateStackInterface& allocator,
  331. EXP_COMP_OBJ* pComplete,
  332. class CacheCallback< Data >* pSelector,
  333. BOOL fForced,
  334. TEntry<Data,Key>* pProtected = 0
  335. ) ;
  336. //
  337. // Expire old stuff in the cache - everything older than
  338. // dwLifetimeSeconds (specified at Init() time
  339. // which is NOT in use should be kicked out.
  340. //
  341. BOOL
  342. Expire(
  343. CStateStackInterface& allocator,
  344. EXP_COMP_OBJ* pComplete
  345. ) ;
  346. //
  347. // Initialization function - take pointer to function
  348. // which should be used to compute hash values on Key's
  349. // Also takes the number of seconds objects should live in
  350. // the cache !
  351. //
  352. BOOL
  353. Init(
  354. DWORD (*pfnHash)( const Key& ),
  355. DWORD dwLifetimeSeconds,
  356. DWORD cMaxInstances,
  357. PSTOPHINT_FN pfnStopHint = NULL
  358. ) ;
  359. } ;
  360. template< class Data,
  361. class Key,
  362. class Constructor
  363. >
  364. class TMultiAsyncCache {
  365. private :
  366. typedef TAsyncCache< Data, Key, Constructor > ASYNCCACHEINSTANCE ;
  367. //
  368. // Signature for these objects in memory !
  369. //
  370. DWORD m_dwSignature ;
  371. //
  372. // Array of Caches to use for client requests
  373. //
  374. ASYNCCACHEINSTANCE* m_pCaches ;
  375. //
  376. // Number of ASYNCCACHEINSTANCE objects pointed to be m_pCaches !
  377. //
  378. DWORD m_cSubCaches ;
  379. //
  380. // The Hash Function to be used !
  381. //
  382. DWORD (*m_pfnHash)( const Key& ) ;
  383. //
  384. // Function which computes which of our child caches to use !
  385. //
  386. DWORD
  387. ChooseInstance( DWORD dwHash ) ;
  388. public :
  389. typedef ASYNCCACHEINSTANCE::COMP_OBJ COMP_OBJ ;
  390. typedef ASYNCCACHEINSTANCE::EXP_COMP_OBJ EXP_COMP_OBJ ;
  391. TMultiAsyncCache() ;
  392. ~TMultiAsyncCache() ;
  393. //
  394. // Initialization function - take pointer to function
  395. // which should be used to compute hash values on Key's
  396. // Also takes the number of seconds objects should live in
  397. // the cache !
  398. //
  399. BOOL
  400. Init(
  401. DWORD cCaches,
  402. DWORD (*pfnHash)( const Key& ),
  403. DWORD dwLifetimeSeconds,
  404. DWORD cMaxInstances,
  405. PSTOPHINT_FN pfnStopHint = NULL
  406. ) ;
  407. //
  408. // Find an Item in the Cache or Create an Item to be held in the Cache !
  409. //
  410. BOOL
  411. FindOrCreate( CStateStackInterface& allocator,
  412. DWORD dwHash,
  413. Key& key,
  414. Constructor& constructor,
  415. COMP_OBJ* pComplete ) ;
  416. //
  417. //
  418. //
  419. BOOL
  420. FindOrCreate( CStateStackInterface& allocator,
  421. Key& key,
  422. Constructor& constructor,
  423. COMP_OBJ* pComplete
  424. ) ;
  425. //
  426. // Remove an Item from the cache !
  427. //
  428. //
  429. // Function which can be used to remove items from the Cache
  430. //
  431. BOOL
  432. Expunge(
  433. CStateStackInterface& allocator,
  434. EXP_COMP_OBJ* pComplete,
  435. Key* key = 0
  436. ) ;
  437. //
  438. // Function which can be passed a function pointer to determine
  439. // exactly what items are to be removed from the Cache.
  440. // if fForced == TRUE then items are removed from the Cache
  441. // no matter what.
  442. //
  443. BOOL
  444. ExpungeSpecific(
  445. CStateStackInterface& allocator,
  446. EXP_COMP_OBJ* pComplete,
  447. class CacheCallback< Data >* pSelector,
  448. BOOL fForced
  449. ) ;
  450. //
  451. // Expire old stuff in the cache - everything older than
  452. // dwLifetimeSeconds (specified at Init() time
  453. // which is NOT in use should be kicked out.
  454. //
  455. BOOL
  456. Expire(
  457. CStateStackInterface& allocator,
  458. EXP_COMP_OBJ* pComplete
  459. ) ;
  460. } ;
  461. #include "cachemtx.h"
  462. #endif // _CACHEMT_H_