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.

147 lines
2.8 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 32-bit keys.
  8. Author:
  9. Abolade Gbadegesin (aboladeg) 19-Feb-1998
  10. Revision History:
  11. --*/
  12. #ifndef _CACHE_H_
  13. #define _CACHE_H_
  14. #define CACHE_SHIFT 4
  15. #define CACHE_SIZE (1 << (8 - CACHE_SHIFT))
  16. #define CACHE_INDEX(k) ((unsigned char)(k) & (0xFF >> CACHE_SHIFT))
  17. typedef struct _CACHE_ENTRY {
  18. unsigned long Key;
  19. void* Value;
  20. long Hits;
  21. long Misses;
  22. } CACHE_ENTRY, *PCACHE_ENTRY;
  23. __inline
  24. void
  25. InitializeCache(
  26. CACHE_ENTRY Cache[]
  27. )
  28. {
  29. memset(Cache, 0, CACHE_SIZE * sizeof(CACHE_ENTRY));
  30. }
  31. __inline
  32. void
  33. ClearCache(
  34. CACHE_ENTRY Cache[],
  35. unsigned long Key
  36. )
  37. {
  38. long Index = CACHE_INDEX(Key);
  39. Cache[Index].Key = 0;
  40. Cache[Index].Value = 0;
  41. Cache[Index].Hits = 0;
  42. Cache[Index].Misses = 0;
  43. }
  44. __inline
  45. void*
  46. ProbeCache(
  47. CACHE_ENTRY Cache[],
  48. unsigned long Key
  49. )
  50. {
  51. long Index = CACHE_INDEX(Key);
  52. if (Key == Cache[Index].Key) {
  53. Cache[Index].Hits++;
  54. return Cache[Index].Value;
  55. }
  56. Cache[Index].Misses++;
  57. return NULL;
  58. }
  59. __inline
  60. int
  61. UpdateCache(
  62. CACHE_ENTRY Cache[],
  63. unsigned long Key,
  64. void* Value
  65. )
  66. {
  67. long Index = CACHE_INDEX(Key);
  68. if (Key == Cache[Index].Key ||
  69. Cache[Index].Hits >=
  70. (Cache[Index].Misses - (Cache[Index].Misses >> 2))) { return 0; }
  71. Cache[Index].Key = Key;
  72. Cache[Index].Value = Value;
  73. Cache[Index].Hits = 0;
  74. Cache[Index].Misses = 0;
  75. return 1;
  76. }
  77. __inline
  78. void
  79. InterlockedClearCache(
  80. CACHE_ENTRY Cache[],
  81. unsigned long Key
  82. )
  83. {
  84. long Index = CACHE_INDEX(Key);
  85. InterlockedExchange(&Cache[Index].Key, 0);
  86. InterlockedExchangePointer(&Cache[Index].Value, 0);
  87. InterlockedExchange(&Cache[Index].Hits, 0);
  88. InterlockedExchange(&Cache[Index].Misses, 0);
  89. }
  90. __inline
  91. void*
  92. InterlockedProbeCache(
  93. CACHE_ENTRY Cache[],
  94. unsigned long Key
  95. )
  96. {
  97. long Index = CACHE_INDEX(Key);
  98. if (Key == Cache[Index].Key) {
  99. InterlockedIncrement(&Cache[Index].Hits);
  100. return Cache[Index].Value;
  101. }
  102. InterlockedIncrement(&Cache[Index].Misses);
  103. return NULL;
  104. }
  105. __inline
  106. int
  107. InterlockedUpdateCache(
  108. CACHE_ENTRY Cache[],
  109. unsigned long Key,
  110. void* Value
  111. )
  112. {
  113. long Index = CACHE_INDEX(Key);
  114. if (Key == Cache[Index].Key ||
  115. Cache[Index].Hits >=
  116. (Cache[Index].Misses - (Cache[Index].Misses >> 2))) { return 0; }
  117. InterlockedExchange(&Cache[Index].Key, Key);
  118. InterlockedExchangePointer(&Cache[Index].Value, Value);
  119. InterlockedExchange(&Cache[Index].Hits, 0);
  120. InterlockedExchange(&Cache[Index].Misses, 0);
  121. return 1;
  122. }
  123. #endif // _CACHE_H_