Skip to content

Commit d16cfb5

Browse files
committed
Avoid calculating folder size for parent that needs scan.
Signed-off-by: Ari Selseng <ari@selseng.net>
1 parent 679afa2 commit d16cfb5

5 files changed

Lines changed: 70 additions & 8 deletions

File tree

lib/private/Files/Cache/Cache.php

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* @copyright Copyright (c) 2016, ownCloud, Inc.
44
*
55
* @author Andreas Fischer <bantu@owncloud.com>
6+
* @author Ari Selseng <ari@selseng.net>
67
* @author Artem Kochnev <MrJeos@gmail.com>
78
* @author Björn Schießle <bjoern@schiessle.org>
89
* @author Florin Peter <github@florin-peter.de>
@@ -774,15 +775,38 @@ public function searchByTag($tag, $userId) {
774775
* @param string|boolean $path
775776
* @param array $data (optional) meta data of the folder
776777
*/
777-
public function correctFolderSize($path, $data = null) {
778+
public function correctFolderSize($path, $data = null, $isBackgroundScan = false) {
778779
$this->calculateFolderSize($path, $data);
779780
if ($path !== '') {
780781
$parent = dirname($path);
781782
if ($parent === '.' or $parent === '/') {
782783
$parent = '';
783784
}
784-
$this->correctFolderSize($parent);
785+
if ($isBackgroundScan) {
786+
$parentData = $this->get($parent);
787+
if ($parentData['size'] !== -1 && $this->getIncompleteChildrenCount($parentData['fileid']) === 0) {
788+
$this->correctFolderSize($parent, $parentData, $isBackgroundScan);
789+
}
790+
} else {
791+
$this->correctFolderSize($parent);
792+
}
793+
}
794+
}
795+
796+
/**
797+
* get the incomplete count that shares parent $folder
798+
*
799+
* @param int $fileId the file id of the folder
800+
* @return int
801+
*/
802+
public function getIncompleteChildrenCount($fileId) {
803+
if ($fileId > -1) {
804+
$sql = 'SELECT count(*)
805+
FROM `*PREFIX*filecache` WHERE `parent` = ? AND size = -1';
806+
$result = $this->connection->executeQuery($sql, [$fileId]);
807+
return (int)$result->fetchColumn();
785808
}
809+
return -1;
786810
}
787811

788812
/**
@@ -919,4 +943,4 @@ public function normalize($path) {
919943

920944
return trim(\OC_Util::normalizeUnicode($path), '/');
921945
}
922-
}
946+
}

lib/private/Files/Cache/Scanner.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ private function runBackgroundScanJob(callable $callback, $path) {
532532
$callback();
533533
\OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path));
534534
if ($this->cacheActive && $this->cache instanceof Cache) {
535-
$this->cache->correctFolderSize($path);
535+
$this->cache->correctFolderSize($path, null, true);
536536
}
537537
} catch (\OCP\Files\StorageInvalidException $e) {
538538
// skip unavailable storages

lib/private/Files/Cache/Wrapper/CacheJail.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,9 @@ public function searchByTag($tag, $userId) {
265265
* @param string|boolean $path
266266
* @param array $data (optional) meta data of the folder
267267
*/
268-
public function correctFolderSize($path, $data = null) {
268+
public function correctFolderSize($path, $data = null, $isBackgroundSize = false) {
269269
if ($this->getCache() instanceof Cache) {
270-
$this->getCache()->correctFolderSize($this->getSourcePath($path), $data);
270+
$this->getCache()->correctFolderSize($this->getSourcePath($path), $data, $isBackgroundSize);
271271
}
272272
}
273273

lib/private/Files/Cache/Wrapper/CacheWrapper.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,9 @@ public function searchByTag($tag, $userId) {
258258
* @param string|boolean $path
259259
* @param array $data (optional) meta data of the folder
260260
*/
261-
public function correctFolderSize($path, $data = null) {
261+
public function correctFolderSize($path, $data = null, $isBackgroundScan = false) {
262262
if ($this->getCache() instanceof Cache) {
263-
$this->getCache()->correctFolderSize($path, $data);
263+
$this->getCache()->correctFolderSize($path, $data, $isBackgroundScan);
264264
}
265265
}
266266

tests/lib/Files/Cache/ScannerTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,44 @@ function testBackgroundScanOnlyRecurseIncomplete() {
203203
$this->assertFalse($this->cache->getIncomplete());
204204
}
205205

206+
public function testBackgroundScanNestedIncompleteFolders() {
207+
$this->storage->mkdir('folder');
208+
$this->scanner->backgroundScan();
209+
210+
$this->storage->mkdir('folder/subfolder1');
211+
$this->storage->mkdir('folder/subfolder2');
212+
213+
$this->storage->mkdir('folder/subfolder1/subfolder3');
214+
$this->cache->put('folder', ['size' => -1]);
215+
$this->cache->put('folder/subfolder1', ['size' => -1]);
216+
217+
// do a scan to get the folders into the cache.
218+
$this->scanner->backgroundScan();
219+
220+
$this->assertTrue($this->cache->inCache('folder/subfolder1/subfolder3'));
221+
222+
$this->storage->file_put_contents('folder/subfolder1/bar1.txt', 'foobar');
223+
$this->storage->file_put_contents('folder/subfolder1/subfolder3/bar3.txt', 'foobar');
224+
$this->storage->file_put_contents('folder/subfolder2/bar2.txt', 'foobar');
225+
226+
//mark folders as incomplete.
227+
$this->cache->put('folder/subfolder1', ['size' => -1]);
228+
$this->cache->put('folder/subfolder2', ['size' => -1]);
229+
$this->cache->put('folder/subfolder1/subfolder3', ['size' => -1]);
230+
231+
$this->scanner->backgroundScan();
232+
233+
$this->assertTrue($this->cache->inCache('folder/subfolder1/bar1.txt'));
234+
$this->assertTrue($this->cache->inCache('folder/subfolder2/bar2.txt'));
235+
$this->assertTrue($this->cache->inCache('folder/subfolder1/subfolder3/bar3.txt'));
236+
237+
//check if folder sizes are correct.
238+
$this->assertEquals(18, $this->cache->get('folder')['size']);
239+
$this->assertEquals(12, $this->cache->get('folder/subfolder1')['size']);
240+
$this->assertEquals(6, $this->cache->get('folder/subfolder1/subfolder3')['size']);
241+
$this->assertEquals(6, $this->cache->get('folder/subfolder2')['size']);
242+
}
243+
206244
public function testReuseExisting() {
207245
$this->fillTestFolders();
208246

0 commit comments

Comments
 (0)