Guest User

Untitled

a guest
Jun 22nd, 2018
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.58 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. typedef struct LRUCacheMember LRUCacheMember;
  6.  
  7. struct LRUCacheMember
  8. {
  9. LRUCacheMember *next;
  10. LRUCacheMember *prev;
  11. int key;
  12. int value;
  13. };
  14.  
  15. typedef struct LRUCache
  16. {
  17. int capacity;
  18. int count;
  19. int hash_size;
  20. LRUCacheMember *head;
  21. LRUCacheMember *hash;
  22. } LRUCache;
  23.  
  24. LRUCache *lRUCacheCreate(int capacity)
  25. {
  26. LRUCache *cache = (LRUCache *)malloc(sizeof(LRUCache));
  27. cache->capacity = capacity;
  28. cache->count = 0;
  29. cache->head = NULL;
  30. cache->hash_size = 2 * capacity;
  31. cache->hash = (LRUCacheMember *)
  32. calloc(cache->hash_size, sizeof(LRUCacheMember));
  33. return cache;
  34. }
  35.  
  36. /*
  37. ******************************************************************************
  38. */
  39.  
  40. static void
  41. l2c_insert_before(LRUCacheMember *curr, LRUCacheMember *new)
  42. {
  43. new->next = curr;
  44. new->prev = curr->prev;
  45. curr->prev->next = new;
  46. curr->prev = new;
  47. }
  48.  
  49. static void
  50. l2c_delete(LRUCacheMember *curr)
  51. {
  52. curr->prev->next = curr->next;
  53. curr->next->prev = curr->prev;
  54. }
  55.  
  56. /*
  57. ******************************************************************************
  58. */
  59.  
  60. static LRUCacheMember *
  61. hash_enter(LRUCache *obj, int key, int value, int *found)
  62. {
  63. int offset = key % obj->hash_size;
  64.  
  65. while (obj->hash[offset].value != 0 &&
  66. obj->hash[offset].key != key)
  67. {
  68. offset++;
  69. offset %= obj->hash_size;
  70. }
  71.  
  72. *found = obj->hash[offset].key == key;
  73. obj->hash[offset].key = key;
  74. obj->hash[offset].value = value;
  75. return (obj->hash + offset);
  76. }
  77.  
  78. static LRUCacheMember *
  79. hash_search(LRUCache *obj, int key)
  80. {
  81. int offset = key % obj->hash_size;
  82.  
  83. while (obj->hash[offset].value != 0 &&
  84. obj->hash[offset].key != key)
  85. {
  86. offset++;
  87. offset %= obj->hash_size;
  88. }
  89.  
  90. if (obj->hash[offset].key == key && obj->hash[offset].value)
  91. return (obj->hash + offset);
  92. else
  93. return NULL;
  94. }
  95.  
  96. /*
  97. ******************************************************************************
  98. */
  99.  
  100. int lRUCacheGet(LRUCache *obj, int key)
  101. {
  102. LRUCacheMember *curr;
  103.  
  104. if (obj->capacity == 0)
  105. return -1;
  106.  
  107. curr = hash_search(obj, key);
  108. if (curr)
  109. {
  110. // retop
  111. if (curr != obj->head && obj->head)
  112. {
  113. l2c_delete(curr);
  114. l2c_insert_before(obj->head, curr);
  115. obj->head = curr;
  116. }
  117. return curr->value;
  118. }
  119. else
  120. return -1;
  121. }
  122.  
  123. void lRUCachePut(LRUCache *obj, int key, int value)
  124. {
  125. LRUCacheMember *member;
  126. int found = 0;
  127.  
  128. if (obj->capacity == 0)
  129. return;
  130.  
  131. member = hash_enter(obj, key, value, &found);
  132.  
  133. // create if not found
  134. if (!found)
  135. {
  136. obj->count++;
  137.  
  138. // put on top
  139. if (obj->head == NULL)
  140. {
  141. obj->head = member;
  142. member->next = member;
  143. member->prev = member;
  144. }
  145. else
  146. {
  147. l2c_insert_before(obj->head, member);
  148. obj->head = member;
  149. }
  150.  
  151. // evict old if needed
  152. if (obj->count > obj->capacity)
  153. {
  154. LRUCacheMember *least = obj->head->prev;
  155. l2c_delete(least);
  156. least->value = 0;
  157. least->key = 0;
  158. obj->count--;
  159. }
  160. }
  161. else
  162. {
  163. member->value = value;
  164. // retop
  165. // if (member != obj->head)
  166. if (member != obj->head && obj->head)
  167. {
  168. l2c_delete(member);
  169. l2c_insert_before(obj->head, member);
  170. obj->head = member;
  171. }
  172. }
  173. }
  174.  
  175. void lRUCacheFree(LRUCache *obj)
  176. {
  177. free(obj->hash);
  178. free(obj);
  179. }
Add Comment
Please, Sign In to add comment