Merge pull request #14598 from nextcloud/backport/14425/stable14
[stable14] Do not calculate folder size for parent that also needs proper scan, fixes #3524
This commit is contained in:
commit
c9b87701d0
|
@ -3,6 +3,7 @@
|
||||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||||
*
|
*
|
||||||
* @author Andreas Fischer <bantu@owncloud.com>
|
* @author Andreas Fischer <bantu@owncloud.com>
|
||||||
|
* @author Ari Selseng <ari@selseng.net>
|
||||||
* @author Artem Kochnev <MrJeos@gmail.com>
|
* @author Artem Kochnev <MrJeos@gmail.com>
|
||||||
* @author Björn Schießle <bjoern@schiessle.org>
|
* @author Björn Schießle <bjoern@schiessle.org>
|
||||||
* @author Florin Peter <github@florin-peter.de>
|
* @author Florin Peter <github@florin-peter.de>
|
||||||
|
@ -760,16 +761,39 @@ class Cache implements ICache {
|
||||||
* @param string|boolean $path
|
* @param string|boolean $path
|
||||||
* @param array $data (optional) meta data of the folder
|
* @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);
|
$this->calculateFolderSize($path, $data);
|
||||||
if ($path !== '') {
|
if ($path !== '') {
|
||||||
$parent = dirname($path);
|
$parent = dirname($path);
|
||||||
if ($parent === '.' or $parent === '/') {
|
if ($parent === '.' or $parent === '/') {
|
||||||
$parent = '';
|
$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);
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calculate the size of a folder and set it in the cache
|
* calculate the size of a folder and set it in the cache
|
||||||
|
|
|
@ -532,7 +532,7 @@ class Scanner extends BasicEmitter implements IScanner {
|
||||||
$callback();
|
$callback();
|
||||||
\OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path));
|
\OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path));
|
||||||
if ($this->cacheActive && $this->cache instanceof Cache) {
|
if ($this->cacheActive && $this->cache instanceof Cache) {
|
||||||
$this->cache->correctFolderSize($path);
|
$this->cache->correctFolderSize($path, null, true);
|
||||||
}
|
}
|
||||||
} catch (\OCP\Files\StorageInvalidException $e) {
|
} catch (\OCP\Files\StorageInvalidException $e) {
|
||||||
// skip unavailable storages
|
// skip unavailable storages
|
||||||
|
|
|
@ -265,9 +265,9 @@ class CacheJail extends CacheWrapper {
|
||||||
* @param string|boolean $path
|
* @param string|boolean $path
|
||||||
* @param array $data (optional) meta data of the folder
|
* @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) {
|
if ($this->getCache() instanceof Cache) {
|
||||||
$this->getCache()->correctFolderSize($this->getSourcePath($path), $data);
|
$this->getCache()->correctFolderSize($this->getSourcePath($path), $data, $isBackgroundSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,9 +252,9 @@ class CacheWrapper extends Cache {
|
||||||
* @param string|boolean $path
|
* @param string|boolean $path
|
||||||
* @param array $data (optional) meta data of the folder
|
* @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) {
|
if ($this->getCache() instanceof Cache) {
|
||||||
$this->getCache()->correctFolderSize($path, $data);
|
$this->getCache()->correctFolderSize($path, $data, $isBackgroundScan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,44 @@ class ScannerTest extends \Test\TestCase {
|
||||||
$this->assertFalse($this->cache->getIncomplete());
|
$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() {
|
public function testReuseExisting() {
|
||||||
$this->fillTestFolders();
|
$this->fillTestFolders();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue