1
0
mirror of synced 2024-12-05 03:06:05 +03:00

Merge pull request #1382 from holtkamp/patch-second-level-cache-association-hydration

Patch second level cache association hydration
This commit is contained in:
Guilherme Blanco 2015-04-14 11:37:54 -04:00
commit 5f18618355
5 changed files with 57 additions and 26 deletions

View File

@ -23,7 +23,7 @@ namespace Doctrine\ORM\Cache;
/** /**
* Defines a region that supports multi-get reading. * Defines a region that supports multi-get reading.
* *
* With one method call we can get multipe items. * With one method call we can get multiple items.
* *
* @since 2.5 * @since 2.5
* @author Asmir Mustafic * @author Asmir Mustafic
@ -31,7 +31,7 @@ namespace Doctrine\ORM\Cache;
interface MultiGetRegion interface MultiGetRegion
{ {
/** /**
* Get all items from the cache indentifed by $keys. * Get all items from the cache identified by $keys.
* It returns NULL if some elements can not be found. * It returns NULL if some elements can not be found.
* *
* @param CollectionCacheEntry $collection The collection of the items to be retrieved. * @param CollectionCacheEntry $collection The collection of the items to be retrieved.

View File

@ -57,8 +57,9 @@ class DefaultMultiGetRegion extends DefaultRegion
public function getMultiple(CollectionCacheEntry $collection) public function getMultiple(CollectionCacheEntry $collection)
{ {
$keysToRetrieve = array(); $keysToRetrieve = array();
foreach ($collection->identifiers as $index => $key) { foreach ($collection->identifiers as $index => $key) {
$keysToRetrieve[$index] = $this->name . '_' . $key->hash; $keysToRetrieve[$index] = $this->getCacheEntryKey($key);
} }
$items = $this->cache->fetchMultiple($keysToRetrieve); $items = $this->cache->fetchMultiple($keysToRetrieve);
@ -70,6 +71,7 @@ class DefaultMultiGetRegion extends DefaultRegion
foreach ($keysToRetrieve as $index => $key) { foreach ($keysToRetrieve as $index => $key) {
$returnableItems[$index] = $items[$key]; $returnableItems[$index] = $items[$key];
} }
return $returnableItems; return $returnableItems;
} }
} }

View File

@ -36,6 +36,8 @@ use Doctrine\ORM\Cache\Region;
*/ */
class DefaultRegion implements Region class DefaultRegion implements Region
{ {
const REGION_KEY_SEPARATOR = '_';
/** /**
* @var CacheAdapter * @var CacheAdapter
*/ */
@ -84,7 +86,7 @@ class DefaultRegion implements Region
*/ */
public function contains(CacheKey $key) public function contains(CacheKey $key)
{ {
return $this->cache->contains($this->name . '_' . $key->hash); return $this->cache->contains($this->getCacheEntryKey($key));
} }
/** /**
@ -92,7 +94,7 @@ class DefaultRegion implements Region
*/ */
public function get(CacheKey $key) public function get(CacheKey $key)
{ {
return $this->cache->fetch($this->name . '_' . $key->hash) ?: null; return $this->cache->fetch($this->getCacheEntryKey($key)) ?: null;
} }
/** /**
@ -100,30 +102,29 @@ class DefaultRegion implements Region
*/ */
public function getMultiple(CollectionCacheEntry $collection) public function getMultiple(CollectionCacheEntry $collection)
{ {
$keysToRetrieve = array(); $result = array();
foreach ($collection->identifiers as $index => $key) { foreach ($collection->identifiers as $key) {
$keysToRetrieve[$index] = $this->name . '_' . $key->hash; $entryKey = $this->getCacheEntryKey($key);
} $entryValue = $this->cache->fetch($entryKey);
$items = array_filter( if ($entryValue === false) {
array_map([$this->cache, 'fetch'], $keysToRetrieve), return null;
function ($retrieved) {
return false !== $retrieved;
} }
);
if (count($items) !== count($keysToRetrieve)) { $result[] = $entryValue;
return null;
} }
$returnableItems = array(); return $result;
}
foreach ($keysToRetrieve as $index => $key) { /**
$returnableItems[$index] = $items[$key]; * @param CacheKey $key
} * @return string
*/
return $returnableItems; protected function getCacheEntryKey(CacheKey $key)
{
return $this->name . self::REGION_KEY_SEPARATOR . $key->hash;
} }
/** /**
@ -131,7 +132,7 @@ class DefaultRegion implements Region
*/ */
public function put(CacheKey $key, CacheEntry $entry, Lock $lock = null) public function put(CacheKey $key, CacheEntry $entry, Lock $lock = null)
{ {
return $this->cache->save($this->name . '_' . $key->hash, $entry, $this->lifetime); return $this->cache->save($this->getCacheEntryKey($key), $entry, $this->lifetime);
} }
/** /**
@ -139,7 +140,7 @@ class DefaultRegion implements Region
*/ */
public function evict(CacheKey $key) public function evict(CacheKey $key)
{ {
return $this->cache->delete($this->name . '_' . $key->hash); return $this->cache->delete($this->getCacheEntryKey($key));
} }
/** /**

View File

@ -3,10 +3,12 @@
namespace Doctrine\Tests\ORM\Cache; namespace Doctrine\Tests\ORM\Cache;
use Doctrine\Common\Cache\ArrayCache; use Doctrine\Common\Cache\ArrayCache;
use Doctrine\ORM\Cache\CollectionCacheEntry;
use Doctrine\ORM\Cache\Region\DefaultRegion; use Doctrine\ORM\Cache\Region\DefaultRegion;
use Doctrine\Tests\Mocks\CacheEntryMock; use Doctrine\Tests\Mocks\CacheEntryMock;
use Doctrine\Tests\Mocks\CacheKeyMock; use Doctrine\Tests\Mocks\CacheKeyMock;
/** /**
* @group DDC-2183 * @group DDC-2183
*/ */
@ -72,4 +74,27 @@ class DefaultRegionTest extends AbstractRegionTest
$region->evictAll(); $region->evictAll();
} }
public function testGetMulti()
{
$key1 = new CacheKeyMock('key.1');
$value1 = new CacheEntryMock(array('id' => 1, 'name' => 'bar'));
$key2 = new CacheKeyMock('key.2');
$value2 = new CacheEntryMock(array('id' => 2, 'name' => 'bar'));
$this->assertFalse($this->region->contains($key1));
$this->assertFalse($this->region->contains($key2));
$this->region->put($key1, $value1);
$this->region->put($key2, $value2);
$this->assertTrue($this->region->contains($key1));
$this->assertTrue($this->region->contains($key2));
$actual = $this->region->getMultiple(new CollectionCacheEntry(array($key1, $key2)));
$this->assertEquals($value1, $actual[0]);
$this->assertEquals($value2, $actual[1]);
}
} }

View File

@ -22,10 +22,10 @@ class MultiGetRegionTest extends AbstractRegionTest
public function testGetMulti() public function testGetMulti()
{ {
$key1 = new CacheKeyMock('key.1'); $key1 = new CacheKeyMock('key.1');
$value1 = new CacheEntryMock(array('id'=>1, 'name' => 'bar')); $value1 = new CacheEntryMock(array('id' => 1, 'name' => 'bar'));
$key2 = new CacheKeyMock('key.2'); $key2 = new CacheKeyMock('key.2');
$value2 = new CacheEntryMock(array('id'=>2, 'name' => 'bar')); $value2 = new CacheEntryMock(array('id' => 2, 'name' => 'bar'));
$this->assertFalse($this->region->contains($key1)); $this->assertFalse($this->region->contains($key1));
$this->assertFalse($this->region->contains($key2)); $this->assertFalse($this->region->contains($key2));
@ -33,6 +33,9 @@ class MultiGetRegionTest extends AbstractRegionTest
$this->region->put($key1, $value1); $this->region->put($key1, $value1);
$this->region->put($key2, $value2); $this->region->put($key2, $value2);
$this->assertTrue($this->region->contains($key1));
$this->assertTrue($this->region->contains($key2));
$actual = $this->region->getMultiple(new CollectionCacheEntry(array($key1, $key2))); $actual = $this->region->getMultiple(new CollectionCacheEntry(array($key1, $key2)));
$this->assertEquals($value1, $actual[0]); $this->assertEquals($value1, $actual[0]);