Skip to content

Commit

Permalink
[SPI Cache] Small refactoring to make multi load abstract more solid (#…
Browse files Browse the repository at this point in the history
…2250)

* [SPI Cache] Small refactoring to make multi load abstract more solid

* CS

* CS
  • Loading branch information
andrerom committed Feb 20, 2018
1 parent d5499fc commit cf5cfde
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 48 deletions.
44 changes: 36 additions & 8 deletions eZ/Publish/Core/Persistence/Cache/AbstractHandler.php
Expand Up @@ -58,34 +58,62 @@ public function __construct(
*
* @param array $ids
* @param string $keyPrefix
* @param callable $missingLoader Function for loading missing objects, gets array with missing id's as argument,
* expects return value to be array with id as key. Missing items should be missing.
* @param callable $loadedTagger Function for tagging loaded object, gets object as argument, return array of tags.
*
* @return array Format [id[] $cacheMisses, CacheItem[<id>] $list], list contains hits & misses (if there where any).
* @return array
*/
final protected function getMultipleCacheItems(array $ids, string $keyPrefix): array
{
final protected function getMultipleCacheItems(
array $ids,
string $keyPrefix,
callable $missingLoader,
callable $loadedTagger
): array {
if (empty($ids)) {
return [[], []];
return [];
}

// Generate unique cache keys
$cacheKeys = [];
foreach (array_unique($ids) as $id) {
$cacheKeys[] = $keyPrefix . $id;
}

// Load cache items by cache keys (will contain hits and misses)
$list = [];
$cacheMisses = [];
$keyPrefixLength = strlen($keyPrefix);
foreach ($this->cache->getItems($cacheKeys) as $key => $cacheItem) {
$id = substr($key, $keyPrefixLength);
if ($cacheItem->isHit()) {
$list[$id] = $cacheItem->get();
continue;
} else {
$cacheMisses[] = $id;
$list[$id] = $cacheItem;
}
}

// No misses, return completely cached list
if (empty($cacheMisses)) {
return $list;
}

$cacheMisses[] = $id;
$list[$id] = $cacheItem;
// Load missing items, save to cache & apply to list if found
$loadedList = $missingLoader($cacheMisses);
foreach ($cacheMisses as $id) {
if (isset($loadedList[$id])) {
$this->cache->save(
$list[$id]
->set($loadedList[$id])
->tag($loadedTagger($loadedList[$id]))
);
$list[$id] = $loadedList[$id];
} else {
unset($list[$id]);
}
}

return [$cacheMisses, $list];
return $list;
}
}
32 changes: 12 additions & 20 deletions eZ/Publish/Core/Persistence/Cache/ContentHandler.php
Expand Up @@ -98,26 +98,18 @@ public function loadContentInfo($contentId)

public function loadContentInfoList(array $contentIds)
{
list($cacheMisses, $list) = $this->getMultipleCacheItems($contentIds, 'ez-content-info-');
if (empty($cacheMisses)) {
return $list;
}

// Load cache misses
$this->logger->logCall(__METHOD__, array('content' => $cacheMisses));
$cacheMissList = $this->persistenceHandler->contentHandler()->loadContentInfoList($cacheMisses);

// Populate cache misses with data and set final info data instead on list
foreach ($cacheMissList as $id => $contentInfo) {
$this->cache->save(
$list[$id]
->set($contentInfo)
->tag($this->getCacheTags($contentInfo))
);
$list[$id] = $contentInfo;
}

return $list;
return $this->getMultipleCacheItems(
$contentIds,
'ez-content-info-',
function (array $cacheMissIds) {
$this->logger->logCall(__METHOD__, ['content' => $cacheMissIds]);

return $this->persistenceHandler->contentHandler()->loadContentInfoList($cacheMissIds);
},
function (ContentInfo $info) {
return $this->getCacheTags($info);
}
);
}

/**
Expand Down
32 changes: 12 additions & 20 deletions eZ/Publish/Core/Persistence/Cache/ContentTypeHandler.php
Expand Up @@ -86,26 +86,18 @@ public function loadGroup($groupId)
*/
public function loadGroups(array $groupIds)
{
list($cacheMissIds, $list) = $this->getMultipleCacheItems($groupIds, 'ez-content-type-group-');
if (empty($cacheMissIds)) {
return $list;
}

// Load cache misses
$this->logger->logCall(__METHOD__, array('groups' => $cacheMissIds));
$cacheMissList = $this->persistenceHandler->contentTypeHandler()->loadGroups($cacheMissIds);

// Populate cache misses with data and set final group data instead on list
foreach ($cacheMissList as $id => $group) {
$this->cache->save(
$list[$id]
->set($group)
->tag('type-group-' . $id)
);
$list[$id] = $group;
}

return $list;
return $this->getMultipleCacheItems(
$groupIds,
'ez-content-type-group-',
function (array $cacheMissIds) {
$this->logger->logCall(__METHOD__, ['groups' => $cacheMissIds]);

return $this->persistenceHandler->contentTypeHandler()->loadGroups($cacheMissIds);
},
function (Type\Group $group) {
return ['type-group-' . $group->id];
}
);
}

/**
Expand Down

0 comments on commit cf5cfde

Please sign in to comment.