Leaked source code of windows server 2003
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.

178 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1998, Microsoft Corporation
  3. Module Name:
  4. cache.h
  5. Abstract:
  6. This module contains declarations for a simple cache system.
  7. Cache entries are stored as void pointers with 2 32-bit keys.
  8. Author:
  9. Abolade Gbadegesin (aboladeg) 19-Feb-1998
  10. Revision History:
  11. rajeshd : 17-Sep-1999 : Modified the cache parameters.
  12. Notes:
  13. This code is copied from the NAT's implementation of cache and modified to accept
  14. two cache keys.
  15. --*/
  16. #ifndef _CACHE_H_
  17. #define _CACHE_H_
  18. #define CACHE_SHIFT 0
  19. #define CACHE_SIZE (1 << (8 - CACHE_SHIFT))
  20. //#define CACHE_INDEX(k1,k2) (((unsigned char)(k1) & (0xF)) | (((unsigned char)(k2) & (0xF)) << 4))
  21. #define CACHE_INDEX(k1,k2) \
  22. (unsigned char)(( ((DWORD)(k1)&0xff) + (((k1)>>8)&0xff) + ((k2)&0xff) + \
  23. (((k2)>>8)&0xff) + (((k2)>>16)&0xff) + (((k2)>>24)&0xff)) & 0xff)
  24. typedef struct _CACHE_ENTRY {
  25. unsigned long Key1;
  26. unsigned long Key2;
  27. void* Value;
  28. long Hits;
  29. long Misses;
  30. } CACHE_ENTRY, *PCACHE_ENTRY;
  31. __inline
  32. void
  33. InitializeCache(
  34. CACHE_ENTRY Cache[]
  35. )
  36. {
  37. memset(Cache, 0, CACHE_SIZE * sizeof(CACHE_ENTRY));
  38. TRACE2("ipfltdrv: CacheSize=%d, CacheEntry=%d\n", CACHE_SIZE, sizeof(CACHE_ENTRY));
  39. }
  40. __inline
  41. void
  42. CleanCache(
  43. CACHE_ENTRY Cache[],
  44. unsigned long Key1,
  45. unsigned long Key2
  46. )
  47. {
  48. long Index = CACHE_INDEX(Key1, Key2);
  49. TRACE3("ipfltdrv: Clearing Cache at Index=%d, Key1=%d, Key2=%d\n", Index, Key1, Key2);
  50. Cache[Index].Key1 = 0;
  51. Cache[Index].Key2 = 0;
  52. Cache[Index].Value = 0;
  53. Cache[Index].Hits = 0;
  54. Cache[Index].Misses = 0;
  55. }
  56. __inline
  57. void*
  58. ProbeCache(
  59. CACHE_ENTRY Cache[],
  60. unsigned long Key1,
  61. unsigned long Key2
  62. )
  63. {
  64. long Index = CACHE_INDEX(Key1, Key2);
  65. //TRACE3("ipfltdrv: Probing Cache at Index=%d, Key1=%d, Key2=%d\n", Index, Key1, Key2);
  66. if ((Key1 == Cache[Index].Key1) && (Key2 == Cache[Index].Key2)) {
  67. Cache[Index].Hits++;
  68. //TRACE1("ipfltdrv: Probing Cache, Found Value=%8x\n", Cache[Index].Value);
  69. return Cache[Index].Value;
  70. }
  71. Cache[Index].Misses++;
  72. return NULL;
  73. }
  74. __inline
  75. int
  76. UpdateCache(
  77. CACHE_ENTRY Cache[],
  78. unsigned long Key1,
  79. unsigned long Key2,
  80. void* Value
  81. )
  82. {
  83. long Index = CACHE_INDEX(Key1, Key2);
  84. TRACE3("ipfltdrv: Updating Cache at Index=%d, Key1=%d, Key2=%d\n", Index, Key1, Key2);
  85. if (((Key1 == Cache[Index].Key1) && (Key2 == Cache[Index].Key2)) ||
  86. Cache[Index].Hits >=
  87. (Cache[Index].Misses - (Cache[Index].Misses >> 2))) { return 0; }
  88. Cache[Index].Key1 = Key1;
  89. Cache[Index].Key2 = Key2;
  90. Cache[Index].Value = Value;
  91. Cache[Index].Hits = 0;
  92. Cache[Index].Misses = 0;
  93. return 1;
  94. }
  95. __inline
  96. void
  97. InterlockedCleanCache(
  98. CACHE_ENTRY Cache[],
  99. unsigned long Key1,
  100. unsigned long Key2
  101. )
  102. {
  103. long Index = CACHE_INDEX(Key1, Key2);
  104. TRACE3("ipfltdrv: ILocked Clearing Cache at Index=%d, Key1=%d, Key2=%d\n", Index, Key1, Key2);
  105. InterlockedExchange(&Cache[Index].Key1, 0);
  106. InterlockedExchange(&Cache[Index].Key2, 0);
  107. InterlockedExchangePointer(&Cache[Index].Value, 0);
  108. InterlockedExchange(&Cache[Index].Hits, 0);
  109. InterlockedExchange(&Cache[Index].Misses, 0);
  110. }
  111. __inline
  112. void*
  113. InterlockedProbeCache(
  114. CACHE_ENTRY Cache[],
  115. unsigned long Key1,
  116. unsigned long Key2
  117. )
  118. {
  119. long Index = CACHE_INDEX(Key1, Key2);
  120. //TRACE3("ipfltdrv: ILocked Probing Cache at Index=%d, Key1=%d, Key2=%d\n", Index, Key1, Key2);
  121. if ((Key1 == Cache[Index].Key1) && (Key2 == Cache[Index].Key2)) {
  122. InterlockedIncrement(&Cache[Index].Hits);
  123. //TRACE1("ipfltdrv: ILocked Probing Cache, Found Value=%8x\n", Cache[Index].Value);
  124. return Cache[Index].Value;
  125. }
  126. InterlockedIncrement(&Cache[Index].Misses);
  127. return NULL;
  128. }
  129. __inline
  130. int
  131. InterlockedUpdateCache(
  132. CACHE_ENTRY Cache[],
  133. unsigned long Key1,
  134. unsigned long Key2,
  135. void* Value
  136. )
  137. {
  138. long Index = CACHE_INDEX(Key1, Key2);
  139. TRACE4("ipfltdrv: ILocked Updating Cache at Index=%d, Key1=%d, Key2=%d, Value=%08x\n", Index, Key1, Key2, Value);
  140. if (((Key1 == Cache[Index].Key1) && (Key2 == Cache[Index].Key2)) ||
  141. Cache[Index].Hits >=
  142. (Cache[Index].Misses - (Cache[Index].Misses >> 2))) { return 0; }
  143. InterlockedExchange(&Cache[Index].Key1, Key1);
  144. InterlockedExchange(&Cache[Index].Key2, Key2);
  145. InterlockedExchangePointer(&Cache[Index].Value, Value);
  146. InterlockedExchange(&Cache[Index].Hits, 0);
  147. InterlockedExchange(&Cache[Index].Misses, 0);
  148. return 1;
  149. }
  150. #endif // _CACHE_H_