From eca57be3367d9ea462f54cfb227701c8524a6764 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 18 May 2016 15:06:15 +0200 Subject: [PATCH] Only recurse into incomplete folders during background scans --- lib/private/Files/Cache/Scanner.php | 9 ++++++--- lib/public/Files/Cache/IScanner.php | 1 + tests/lib/Files/Cache/ScannerTest.php | 27 +++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/private/Files/Cache/Scanner.php b/lib/private/Files/Cache/Scanner.php index fd309a4ac4..06cc6426c5 100644 --- a/lib/private/Files/Cache/Scanner.php +++ b/lib/private/Files/Cache/Scanner.php @@ -371,7 +371,7 @@ class Scanner extends BasicEmitter implements IScanner { $childQueue = $this->handleChildren($path, $recursive, $reuse, $folderId, $lock, $size); foreach ($childQueue as $child => $childId) { - $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse, $childId, $lock); + $childSize = $this->scanChildren($child, $recursive, $reuse, $childId, $lock); if ($childSize === -1) { $size = -1; } else if ($size !== -1) { @@ -402,6 +402,9 @@ class Scanner extends BasicEmitter implements IScanner { if ($data) { if ($data['mimetype'] === 'httpd/unix-directory' and $recursive === self::SCAN_RECURSIVE) { $childQueue[$child] = $data['fileid']; + } else if ($data['mimetype'] === 'httpd/unix-directory' and $recursive === self::SCAN_RECURSIVE_INCOMPLETE and $data['size'] === -1) { + // only recurse into folders which aren't fully scanned + $childQueue[$child] = $data['fileid']; } else if ($data['size'] === -1) { $size = -1; } else if ($size !== -1) { @@ -469,8 +472,8 @@ class Scanner extends BasicEmitter implements IScanner { } else { $lastPath = null; while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { - $this->runBackgroundScanJob(function () use ($path) { - $this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG); + $this->runBackgroundScanJob(function() use ($path) { + $this->scan($path, self::SCAN_RECURSIVE_INCOMPLETE, self::REUSE_ETAG | self::REUSE_SIZE); }, $path); // FIXME: this won't proceed with the next item, needs revamping of getIncomplete() // to make this possible diff --git a/lib/public/Files/Cache/IScanner.php b/lib/public/Files/Cache/IScanner.php index ce1f408028..74bc2fc884 100644 --- a/lib/public/Files/Cache/IScanner.php +++ b/lib/public/Files/Cache/IScanner.php @@ -27,6 +27,7 @@ namespace OCP\Files\Cache; * @since 9.0.0 */ interface IScanner { + const SCAN_RECURSIVE_INCOMPLETE = 2; // only recursive into not fully scanned folders const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; diff --git a/tests/lib/Files/Cache/ScannerTest.php b/tests/lib/Files/Cache/ScannerTest.php index 4a93f3ee01..b44b6f5d0f 100644 --- a/tests/lib/Files/Cache/ScannerTest.php +++ b/tests/lib/Files/Cache/ScannerTest.php @@ -7,6 +7,7 @@ */ namespace Test\Files\Cache; + use OC\Files\Cache\CacheEntry; /** @@ -150,6 +151,32 @@ class ScannerTest extends \Test\TestCase { $this->assertFalse($this->cache->getIncomplete()); } + function testBackgroundScanOnlyRecurseIncomplete() { + $this->fillTestFolders(); + $this->storage->mkdir('folder2'); + $this->storage->file_put_contents('folder2/bar.txt', 'foobar'); + + $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $this->assertFalse($this->cache->inCache('folder/bar.txt')); + $this->assertFalse($this->cache->inCache('folder/2bar.txt')); + $this->assertFalse($this->cache->inCache('folder2/bar.txt')); + $this->cache->put('folder2', ['size' => 1]); // mark as complete + + $cachedData = $this->cache->get(''); + $this->assertEquals(-1, $cachedData['size']); + + $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE_INCOMPLETE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE); + + $this->assertTrue($this->cache->inCache('folder/bar.txt')); + $this->assertTrue($this->cache->inCache('folder/bar.txt')); + $this->assertFalse($this->cache->inCache('folder2/bar.txt')); + + $cachedData = $this->cache->get(''); + $this->assertNotEquals(-1, $cachedData['size']); + + $this->assertFalse($this->cache->getIncomplete()); + } + public function testReuseExisting() { $this->fillTestFolders();