LRUCache.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. namespace Elgg\Cache;
  3. /**
  4. * Least Recently Used Cache
  5. *
  6. * A fixed sized cache that removes the element used last when it reaches its
  7. * size limit.
  8. *
  9. * Based on https://github.com/cash/LRUCache
  10. *
  11. * @access private
  12. *
  13. * @package Elgg.Core
  14. * @subpackage Cache
  15. */
  16. class LRUCache implements \ArrayAccess {
  17. /** @var int */
  18. protected $maximumSize;
  19. /**
  20. * The front of the array contains the LRU element
  21. *
  22. * @var array
  23. */
  24. protected $data = array();
  25. /**
  26. * Create a LRU Cache
  27. *
  28. * @param int $size The size of the cache
  29. * @throws \InvalidArgumentException
  30. */
  31. public function __construct($size) {
  32. if (!is_int($size) || $size <= 0) {
  33. throw new \InvalidArgumentException();
  34. }
  35. $this->maximumSize = $size;
  36. }
  37. /**
  38. * Get the value cached with this key
  39. *
  40. * @param int|string $key The key. Strings that are ints are cast to ints.
  41. * @param mixed $default The value to be returned if key not found. (Optional)
  42. * @return mixed
  43. */
  44. public function get($key, $default = null) {
  45. if (isset($this->data[$key])) {
  46. $this->recordAccess($key);
  47. return $this->data[$key];
  48. } else {
  49. return $default;
  50. }
  51. }
  52. /**
  53. * Add something to the cache
  54. *
  55. * @param int|string $key The key. Strings that are ints are cast to ints.
  56. * @param mixed $value The value to cache
  57. * @return void
  58. */
  59. public function set($key, $value) {
  60. if (isset($this->data[$key])) {
  61. $this->data[$key] = $value;
  62. $this->recordAccess($key);
  63. } else {
  64. $this->data[$key] = $value;
  65. if ($this->size() > $this->maximumSize) {
  66. // remove least recently used element (front of array)
  67. reset($this->data);
  68. unset($this->data[key($this->data)]);
  69. }
  70. }
  71. }
  72. /**
  73. * Get the number of elements in the cache
  74. *
  75. * @return int
  76. */
  77. public function size() {
  78. return count($this->data);
  79. }
  80. /**
  81. * Does the cache contain an element with this key
  82. *
  83. * @param int|string $key The key
  84. * @return boolean
  85. */
  86. public function containsKey($key) {
  87. return isset($this->data[$key]);
  88. }
  89. /**
  90. * Remove the element with this key.
  91. *
  92. * @param int|string $key The key
  93. * @return mixed Value or null if not set
  94. */
  95. public function remove($key) {
  96. if (isset($this->data[$key])) {
  97. $value = $this->data[$key];
  98. unset($this->data[$key]);
  99. return $value;
  100. } else {
  101. return null;
  102. }
  103. }
  104. /**
  105. * Clear the cache
  106. *
  107. * @return void
  108. */
  109. public function clear() {
  110. $this->data = array();
  111. }
  112. /**
  113. * Moves the element from current position to end of array
  114. *
  115. * @param int|string $key The key
  116. * @return void
  117. */
  118. protected function recordAccess($key) {
  119. $value = $this->data[$key];
  120. unset($this->data[$key]);
  121. $this->data[$key] = $value;
  122. }
  123. /**
  124. * Assigns a value for the specified key
  125. *
  126. * @see \ArrayAccess::offsetSet()
  127. *
  128. * @param int|string $key The key to assign the value to.
  129. * @param mixed $value The value to set.
  130. * @return void
  131. */
  132. public function offsetSet($key, $value) {
  133. $this->set($key, $value);
  134. }
  135. /**
  136. * Get the value for specified key
  137. *
  138. * @see \ArrayAccess::offsetGet()
  139. *
  140. * @param int|string $key The key to retrieve.
  141. * @return mixed
  142. */
  143. public function offsetGet($key) {
  144. return $this->get($key);
  145. }
  146. /**
  147. * Unsets a key.
  148. *
  149. * @see \ArrayAccess::offsetUnset()
  150. *
  151. * @param int|string $key The key to unset.
  152. * @return void
  153. */
  154. public function offsetUnset($key) {
  155. $this->remove($key);
  156. }
  157. /**
  158. * Does key exist?
  159. *
  160. * @see \ArrayAccess::offsetExists()
  161. *
  162. * @param int|string $key A key to check for.
  163. * @return boolean
  164. */
  165. public function offsetExists($key) {
  166. return $this->containsKey($key);
  167. }
  168. }