diff options
author | Morris Jobke <hey@morrisjobke.de> | 2019-03-08 09:12:33 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-08 09:12:33 +0100 |
commit | 772303309df7e85c3e3f1d5c93daf473a5d1e3ac (patch) | |
tree | 08b16f38cdea60d288ffd98d7d11f7fdb5ed7ca2 | |
parent | 70aa85997d53a5a44e8e91edcb6265e085963fa1 (diff) | |
parent | d16cfb519e267c64b0ed816901b97f097576821a (diff) | |
download | nextcloud-server-772303309df7e85c3e3f1d5c93daf473a5d1e3ac.tar.gz nextcloud-server-772303309df7e85c3e3f1d5c93daf473a5d1e3ac.zip |
Merge pull request #14425 from cowai/fix-multiple-incomplete-folders
Do not calculate folder size for parent that also needs proper scan, fixes #3524
-rw-r--r-- | lib/private/Files/Cache/Cache.php | 30 | ||||
-rw-r--r-- | lib/private/Files/Cache/Scanner.php | 2 | ||||
-rw-r--r-- | lib/private/Files/Cache/Wrapper/CacheJail.php | 4 | ||||
-rw-r--r-- | lib/private/Files/Cache/Wrapper/CacheWrapper.php | 4 | ||||
-rw-r--r-- | tests/lib/Files/Cache/ScannerTest.php | 38 |
5 files changed, 70 insertions, 8 deletions
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index 7b42cc2aa57..ef1f0f3c870 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -3,6 +3,7 @@ * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Andreas Fischer <bantu@owncloud.com> + * @author Ari Selseng <ari@selseng.net> * @author Artem Kochnev <MrJeos@gmail.com> * @author Björn Schießle <bjoern@schiessle.org> * @author Florin Peter <github@florin-peter.de> @@ -774,15 +775,38 @@ class Cache implements ICache { * @param string|boolean $path * @param array $data (optional) meta data of the folder */ - public function correctFolderSize($path, $data = null) { + public function correctFolderSize($path, $data = null, $isBackgroundScan = false) { $this->calculateFolderSize($path, $data); if ($path !== '') { $parent = dirname($path); if ($parent === '.' or $parent === '/') { $parent = ''; } - $this->correctFolderSize($parent); + if ($isBackgroundScan) { + $parentData = $this->get($parent); + if ($parentData['size'] !== -1 && $this->getIncompleteChildrenCount($parentData['fileid']) === 0) { + $this->correctFolderSize($parent, $parentData, $isBackgroundScan); + } + } else { + $this->correctFolderSize($parent); + } + } + } + + /** + * get the incomplete count that shares parent $folder + * + * @param int $fileId the file id of the folder + * @return int + */ + public function getIncompleteChildrenCount($fileId) { + if ($fileId > -1) { + $sql = 'SELECT count(*) + FROM `*PREFIX*filecache` WHERE `parent` = ? AND size = -1'; + $result = $this->connection->executeQuery($sql, [$fileId]); + return (int)$result->fetchColumn(); } + return -1; } /** @@ -919,4 +943,4 @@ class Cache implements ICache { return trim(\OC_Util::normalizeUnicode($path), '/'); } -} +}
\ No newline at end of file diff --git a/lib/private/Files/Cache/Scanner.php b/lib/private/Files/Cache/Scanner.php index ca9a0b794f9..e684b853103 100644 --- a/lib/private/Files/Cache/Scanner.php +++ b/lib/private/Files/Cache/Scanner.php @@ -532,7 +532,7 @@ class Scanner extends BasicEmitter implements IScanner { $callback(); \OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path)); if ($this->cacheActive && $this->cache instanceof Cache) { - $this->cache->correctFolderSize($path); + $this->cache->correctFolderSize($path, null, true); } } catch (\OCP\Files\StorageInvalidException $e) { // skip unavailable storages diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php index 57f58e7d839..7e113d13678 100644 --- a/lib/private/Files/Cache/Wrapper/CacheJail.php +++ b/lib/private/Files/Cache/Wrapper/CacheJail.php @@ -265,9 +265,9 @@ class CacheJail extends CacheWrapper { * @param string|boolean $path * @param array $data (optional) meta data of the folder */ - public function correctFolderSize($path, $data = null) { + public function correctFolderSize($path, $data = null, $isBackgroundSize = false) { if ($this->getCache() instanceof Cache) { - $this->getCache()->correctFolderSize($this->getSourcePath($path), $data); + $this->getCache()->correctFolderSize($this->getSourcePath($path), $data, $isBackgroundSize); } } diff --git a/lib/private/Files/Cache/Wrapper/CacheWrapper.php b/lib/private/Files/Cache/Wrapper/CacheWrapper.php index da0a1b54e7f..223e678f323 100644 --- a/lib/private/Files/Cache/Wrapper/CacheWrapper.php +++ b/lib/private/Files/Cache/Wrapper/CacheWrapper.php @@ -258,9 +258,9 @@ class CacheWrapper extends Cache { * @param string|boolean $path * @param array $data (optional) meta data of the folder */ - public function correctFolderSize($path, $data = null) { + public function correctFolderSize($path, $data = null, $isBackgroundScan = false) { if ($this->getCache() instanceof Cache) { - $this->getCache()->correctFolderSize($path, $data); + $this->getCache()->correctFolderSize($path, $data, $isBackgroundScan); } } diff --git a/tests/lib/Files/Cache/ScannerTest.php b/tests/lib/Files/Cache/ScannerTest.php index 736df2174d1..0f5335f4416 100644 --- a/tests/lib/Files/Cache/ScannerTest.php +++ b/tests/lib/Files/Cache/ScannerTest.php @@ -203,6 +203,44 @@ class ScannerTest extends \Test\TestCase { $this->assertFalse($this->cache->getIncomplete()); } + public function testBackgroundScanNestedIncompleteFolders() { + $this->storage->mkdir('folder'); + $this->scanner->backgroundScan(); + + $this->storage->mkdir('folder/subfolder1'); + $this->storage->mkdir('folder/subfolder2'); + + $this->storage->mkdir('folder/subfolder1/subfolder3'); + $this->cache->put('folder', ['size' => -1]); + $this->cache->put('folder/subfolder1', ['size' => -1]); + + // do a scan to get the folders into the cache. + $this->scanner->backgroundScan(); + + $this->assertTrue($this->cache->inCache('folder/subfolder1/subfolder3')); + + $this->storage->file_put_contents('folder/subfolder1/bar1.txt', 'foobar'); + $this->storage->file_put_contents('folder/subfolder1/subfolder3/bar3.txt', 'foobar'); + $this->storage->file_put_contents('folder/subfolder2/bar2.txt', 'foobar'); + + //mark folders as incomplete. + $this->cache->put('folder/subfolder1', ['size' => -1]); + $this->cache->put('folder/subfolder2', ['size' => -1]); + $this->cache->put('folder/subfolder1/subfolder3', ['size' => -1]); + + $this->scanner->backgroundScan(); + + $this->assertTrue($this->cache->inCache('folder/subfolder1/bar1.txt')); + $this->assertTrue($this->cache->inCache('folder/subfolder2/bar2.txt')); + $this->assertTrue($this->cache->inCache('folder/subfolder1/subfolder3/bar3.txt')); + + //check if folder sizes are correct. + $this->assertEquals(18, $this->cache->get('folder')['size']); + $this->assertEquals(12, $this->cache->get('folder/subfolder1')['size']); + $this->assertEquals(6, $this->cache->get('folder/subfolder1/subfolder3')['size']); + $this->assertEquals(6, $this->cache->get('folder/subfolder2')['size']); + } + public function testReuseExisting() { $this->fillTestFolders(); |