aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2019-03-08 09:12:33 +0100
committerGitHub <noreply@github.com>2019-03-08 09:12:33 +0100
commit772303309df7e85c3e3f1d5c93daf473a5d1e3ac (patch)
tree08b16f38cdea60d288ffd98d7d11f7fdb5ed7ca2
parent70aa85997d53a5a44e8e91edcb6265e085963fa1 (diff)
parentd16cfb519e267c64b0ed816901b97f097576821a (diff)
downloadnextcloud-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.php30
-rw-r--r--lib/private/Files/Cache/Scanner.php2
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheJail.php4
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheWrapper.php4
-rw-r--r--tests/lib/Files/Cache/ScannerTest.php38
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();