Skip to content

Commit

Permalink
Refactor CacheInterface so that it deals only with a value object (#45)
Browse files Browse the repository at this point in the history
* Add CacheObject as a value object for the cache data

* Refactor CacheInterface so that it deals only with CacheObject
  • Loading branch information
sirbrillig authored Mar 11, 2021
1 parent 249e9ee commit 9821541
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 50 deletions.
6 changes: 3 additions & 3 deletions PhpcsChanged/CacheInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

namespace PhpcsChanged;

use PhpcsChanged\CacheManager;
use PhpcsChanged\CacheObject;

interface CacheInterface {
public function load(CacheManager $manager): void;
public function load(): CacheObject;

public function save(CacheManager $manager): void;
public function save(CacheObject $cacheObject): void;
}
62 changes: 35 additions & 27 deletions PhpcsChanged/CacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,6 @@ class CacheManager {
*/
private $fileDataByPath = [];

/**
* @var string
*/
private $revisionId;

/**
* @var string
*/
private $cacheVersion;

/**
* @var bool
*/
Expand All @@ -40,28 +30,42 @@ class CacheManager {
*/
private $cache;

/**
* @var CacheObject
*/
private $cacheObject;

/**
* @var callable
*/
private $debug;

public function __construct(CacheInterface $cache, callable $debug = null) {
$this->cache = $cache;
$this->cacheVersion = getVersion();
$noopDebug = function(...$output) {}; // phpcs:ignore VariableAnalysis
$this->debug = $debug ?? $noopDebug;
}

public function load(): void {
($this->debug)("Loading cache...");
$this->cache->load($this);
$this->cacheObject = $this->cache->load();

// Don't try to use old cache versions
$version = getVersion();
if ($this->cacheVersion !== $version) {
($this->debug)("Cache version has changed ({$this->cacheVersion} -> {$version}). Clearing cache.");
if (! $this->cacheObject->cacheVersion) {
$this->cacheObject->cacheVersion = $version;
}
if ($this->cacheObject->cacheVersion !== $version) {
($this->debug)("Cache version has changed ({$this->cacheObject->cacheVersion} -> {$version}). Clearing cache.");
$this->clearCache();
$this->cacheVersion = $version;
$this->cacheObject->cacheVersion = $version;
}

// Keep a map of cache data so it's faster to access
foreach($this->cacheObject->entries as $entry) {
$this->addCacheEntry($entry);
}

$this->hasBeenModified = false;
($this->debug)("Cache loaded.");
}
Expand All @@ -72,16 +76,20 @@ public function save(): void {
return;
}
($this->debug)("Saving cache.");
$this->cache->save($this);

// Copy cache data map back to object
$this->cacheObject->entries = $this->getEntries();

$this->cache->save($this->cacheObject);
$this->hasBeenModified = false;
}

public function getRevision(): ?string {
return $this->revisionId;
return $this->cacheObject->revisionId;
}

public function getCacheVersion(): string {
return $this->cacheVersion;
return $this->cacheObject->cacheVersion;
}

/**
Expand Down Expand Up @@ -114,25 +122,24 @@ private function flattenArray($array): array {
}

public function setCacheVersion(string $cacheVersion): void {
if (! $this->cacheVersion || $this->cacheVersion === $cacheVersion) {
$this->cacheVersion = $cacheVersion;
if ($this->cacheObject->cacheVersion === $cacheVersion) {
return;
}
($this->debug)("Cache version has changed ('{$this->cacheVersion}' -> '{$cacheVersion}'). Clearing cache.");
($this->debug)("Cache version has changed ('{$this->cacheObject->cacheVersion}' -> '{$cacheVersion}'). Clearing cache.");
$this->hasBeenModified = true;
$this->clearCache();
$this->cacheVersion = $cacheVersion;
$this->cacheObject->cacheVersion = $cacheVersion;
}

public function setRevision(string $revisionId): void {
if (! $this->revisionId || $this->revisionId === $revisionId) {
$this->revisionId = $revisionId;
if (! $this->cacheObject->revisionId || $this->cacheObject->revisionId === $revisionId) {
$this->cacheObject->revisionId = $revisionId;
return;
}
($this->debug)("Revision has changed ('{$this->revisionId}' -> '{$revisionId}'). Clearing cache.");
($this->debug)("Revision has changed ('{$this->cacheObject->revisionId}' -> '{$revisionId}'). Clearing cache.");
$this->hasBeenModified = true;
$this->clearCache();
$this->revisionId = $revisionId;
$this->cacheObject->revisionId = $revisionId;
}

public function getCacheForFile(string $filePath, string $type, string $hash, string $phpcsStandard): ?string {
Expand Down Expand Up @@ -196,7 +203,8 @@ public function removeCacheEntry(CacheEntry $entry): void {
public function clearCache(): void {
($this->debug)("Cache cleared");
$this->hasBeenModified = true;
$this->revisionId = '';
$this->cacheObject->revisionId = '';
$this->fileDataByPath = [];
$this->cacheObject->entries = [];
}
}
22 changes: 22 additions & 0 deletions PhpcsChanged/CacheObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);

namespace PhpcsChanged;

class CacheObject {
/**
* @var CacheEntry[]
*/
public $entries = [];

/**
* @var string
*/
public $revisionId;

/**
* @var string
*/
public $cacheVersion;
}

22 changes: 12 additions & 10 deletions PhpcsChanged/FileCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace PhpcsChanged;

use PhpcsChanged\CacheInterface;
use PhpcsChanged\CacheManager;
use PhpcsChanged\CacheObject;
use PhpcsChanged\CacheEntry;

define('DEFAULT_CACHE_FILE', '.phpcs-changed-cache');
Expand All @@ -15,9 +15,9 @@ class FileCache implements CacheInterface {
*/
public $cacheFilePath = DEFAULT_CACHE_FILE; // phpcs:ignore ImportDetection -- apparently ImportDetection does not understand constants

public function load(CacheManager $manager): void {
public function load(): CacheObject {
if (! file_exists($this->cacheFilePath)) {
return;
return new CacheObject();
}
$contents = file_get_contents($this->cacheFilePath);
if ($contents === false) {
Expand All @@ -27,21 +27,23 @@ public function load(CacheManager $manager): void {
if (! $this->isDecodedDataValid($decoded)) {
throw new \Exception('Invalid cache file');
}
$manager->setCacheVersion($decoded['cacheVersion']);
$manager->setRevision($decoded['revisionId']);
$cacheObject = new CacheObject();
$cacheObject->cacheVersion = $decoded['cacheVersion'];
$cacheObject->revisionId = $decoded['revisionId'];
foreach($decoded['entries'] as $entry) {
if (! $this->isDecodedEntryValid($entry)) {
throw new \Exception('Invalid cache file entry: ' . $entry);
}
$manager->addCacheEntry(CacheEntry::fromJson($entry));
$cacheObject->entries[] = CacheEntry::fromJson($entry);
}
return $cacheObject;
}

public function save(CacheManager $manager): void {
public function save(CacheObject $cacheObject): void {
$data = [
'cacheVersion' => $manager->getCacheVersion(),
'revisionId' => $manager->getRevision(),
'entries' => $manager->getEntries(),
'cacheVersion' => $cacheObject->cacheVersion,
'revisionId' => $cacheObject->revisionId,
'entries' => $cacheObject->entries,
];
$result = file_put_contents($this->cacheFilePath, json_encode($data));
if ($result === false) {
Expand Down
1 change: 1 addition & 0 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
require_once __DIR__ . '/PhpcsChanged/ShellOperator.php';
require_once __DIR__ . '/PhpcsChanged/UnixShell.php';
require_once __DIR__ . '/PhpcsChanged/CacheEntry.php';
require_once __DIR__ . '/PhpcsChanged/CacheObject.php';
require_once __DIR__ . '/PhpcsChanged/CacheInterface.php';
require_once __DIR__ . '/PhpcsChanged/CacheManager.php';
require_once __DIR__ . '/PhpcsChanged/FileCache.php';
Expand Down
22 changes: 12 additions & 10 deletions tests/helpers/TestCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace PhpcsChangedTests;

use PhpcsChanged\CacheInterface;
use PhpcsChanged\CacheManager;
use PhpcsChanged\CacheObject;
use PhpcsChanged\CacheEntry;
use function PhpcsChanged\getVersion;

Expand Down Expand Up @@ -34,27 +34,29 @@ class TestCache implements CacheInterface {
*/
public $disabled = false;

public function load(CacheManager $manager): void {
public function load(): CacheObject {
if ($this->disabled) {
return;
return new CacheObject();
}
$this->didSave = false;
$manager->setCacheVersion($this->cacheVersion ?? getVersion());
$manager->setRevision($this->revisionId);
$cacheObject = new CacheObject();
$cacheObject->cacheVersion = $this->cacheVersion ?? getVersion();
$cacheObject->revisionId = $this->revisionId;
foreach(array_values($this->savedFileData) as $entry) {
$manager->addCacheEntry(CacheEntry::fromJson($entry));
$cacheObject->entries[] = CacheEntry::fromJson($entry);
}
return $cacheObject;
}

public function save(CacheManager $manager): void {
public function save(CacheObject $cacheObject): void {
if ($this->disabled) {
return;
}
$this->didSave = true;
$this->setCacheVersion($manager->getCacheVersion());
$this->setRevision($manager->getRevision());
$this->setCacheVersion($cacheObject->cacheVersion);
$this->setRevision($cacheObject->revisionId);
$this->savedFileData = [];
foreach($manager->getEntries() as $entry) {
foreach($cacheObject->entries as $entry) {
$this->setEntry($entry->path, $entry->type, $entry->hash, $entry->phpcsStandard, $entry->data);
}
}
Expand Down

0 comments on commit 9821541

Please sign in to comment.