diff --git a/includes/lru.inc b/includes/lru.inc new file mode 100644 index 0000000..be26869 --- /dev/null +++ b/includes/lru.inc @@ -0,0 +1,61 @@ +slots = $slots; + } + + function offsetGet($offset) { + if (parent::offsetExists($offset)) { + // If the item is not at the end of the positions array, move it + // there. + if (end($this->positions) != $offset) { + $current_position = array_search($offset, $this->positions); + unset($this->positions[$current_position]); + $this->positions[] = $offset; + } + } + return parent::offsetGet($offset); + } + function offsetSet($offset, $value) { + parent::offsetSet($offset, $value); + if ($this->slots > 0) { + $this->slots--; + } + else { + // Replace the item in first position in the array. + $key = array_shift($this->positions); + $this->offsetUnset($key); + } + $this->positions[] = $offset; + } +} diff --git a/modules/simpletest/simpletest.info b/modules/simpletest/simpletest.info index 54b020d..ffbfcc0 100644 --- a/modules/simpletest/simpletest.info +++ b/modules/simpletest/simpletest.info @@ -23,6 +23,7 @@ files[] = tests/filetransfer.test files[] = tests/form.test files[] = tests/graph.test files[] = tests/image.test +files[] = tests/lru.test files[] = tests/lock.test files[] = tests/mail.test files[] = tests/menu.test diff --git a/modules/simpletest/tests/lru.test b/modules/simpletest/tests/lru.test new file mode 100644 index 0000000..950dcba --- /dev/null +++ b/modules/simpletest/tests/lru.test @@ -0,0 +1,64 @@ + 'LRU', + 'description' => 'LRU in-memory cache LRU tests.', + 'group' => 'System', + ); + } + + /** + * Test the LRU cache. + */ + function testLRUCache() { + // Manually require the file to avoid a registry lookup. + require_once DRUPAL_ROOT . '/includes/lru.inc'; + // Create an in-memory LRU cache with 5 slots. + $this->lru = new LRU(5); + $this->lru['banana'] = 'banana'; + // Confirm the item is in the cache. + $this->assertOffset('banana'); + // Now add five more items to the cache. + foreach (array('apple', 'mango', 'grapefruit', 'kiwi', 'orange') as $fruit) { + $this->lru[$fruit] = $fruit; + $this->assertOffset($fruit); + } + // When 'orange' was added, it should have remove 'banana' from the cache. + $this->assertNoOffset('banana'); + // Apple should be in the first position of the array, request it from the + // cache. This should move it to the front of the array, and put the mango + // into the LRU position. + $apple = $this->lru['apple']; + $this->assertEqual($apple, 'apple'); + // Add banana back to the cache. + $this->lru['banana'] = 'banana'; + // Confirm that mango was removed. + $this->assertNoOffset('mango'); + // Confirm that the other fruits are cached. + foreach (array('apple', 'grapefruit', 'kiwi', 'orange') as $fruit) { + $this->assertOffset($fruit); + } + } + + /** + * Assert that an item is in the LRU cache. + */ + function assertOffset($offset) { + $this->assertTrue(isset($this->lru[$offset]), t('@item exists in the LRU cache.', array('@item' => $offset))); + } + + function assertNoOffset($offset) { + $this->assertFalse(isset($this->lru[$offset]), t('@item does not exist in the LRU cache.', array('@item' => $offset))); + } +} +