Merge pull request #11409 from owncloud/watcher-reuse

Pass the cached data to the filesystem watcher
This commit is contained in:
Vincent Petry 2014-10-29 16:38:16 +01:00
commit 106b9eb55c
5 changed files with 53 additions and 43 deletions

View File

@ -145,26 +145,23 @@ class Shared_Cache extends Cache {
/** /**
* get the metadata of all files stored in $folder * get the metadata of all files stored in $folder
* *
* @param string $folder * @param string $folderId
* @return array * @return array
*/ */
public function getFolderContents($folder) { public function getFolderContentsById($folderId) {
$cache = $this->getSourceCache('');
if ($folder === false) {
$folder = '';
}
$dir = ($folder !== '') ? $folder . '/' : '';
$cache = $this->getSourceCache($folder);
if ($cache) { if ($cache) {
$parent = $this->storage->getFile($folder); $owner = $this->storage->getSharedFrom();
$sourceFolderContent = $cache->getFolderContents($this->files[$folder]); $parentPath = $this->getPathById($folderId);
foreach ($sourceFolderContent as $key => $c) { if ($parentPath !== '') {
$sourceFolderContent[$key]['path'] = $dir . $c['name']; $parentPath .= '/';
$sourceFolderContent[$key]['uid_owner'] = $parent['uid_owner']; }
$sourceFolderContent[$key]['displayname_owner'] = \OC_User::getDisplayName($parent['uid_owner']); $sourceFolderContent = $cache->getFolderContentsById($folderId);
$sourceFolderContent[$key]['permissions'] = $sourceFolderContent[$key]['permissions'] & $this->storage->getPermissions($dir . $c['name']); foreach ($sourceFolderContent as &$c) {
$c['path'] = ltrim($parentPath . $c['name'], '/');
$c['uid_owner'] = $owner;
$c['displayname_owner'] = \OC_User::getDisplayName($owner);
$c['permissions'] = $c['permissions'] & $this->storage->getPermissions(false);
} }
return $sourceFolderContent; return $sourceFolderContent;

View File

@ -30,9 +30,11 @@ class Shared_Watcher extends Watcher {
* check $path for updates * check $path for updates
* *
* @param string $path * @param string $path
* @param array $cachedEntry
* @return boolean true if path was updated
*/ */
public function checkUpdate($path) { public function checkUpdate($path, $cachedEntry = null) {
if (parent::checkUpdate($path) === true) { if (parent::checkUpdate($path, $cachedEntry) === true) {
// since checkUpdate() has already updated the size of the subdirs, // since checkUpdate() has already updated the size of the subdirs,
// only apply the update to the owner's parent dirs // only apply the update to the owner's parent dirs

View File

@ -55,11 +55,14 @@ class Watcher {
* check $path for updates * check $path for updates
* *
* @param string $path * @param string $path
* @return boolean|array true if path was updated, otherwise the cached data is returned * @param array $cachedEntry
* @return boolean true if path was updated
*/ */
public function checkUpdate($path) { public function checkUpdate($path, $cachedEntry = null) {
if ($this->watchPolicy === self::CHECK_ALWAYS or ($this->watchPolicy === self::CHECK_ONCE and array_search($path, $this->checkedPaths) === false)) { if ($this->watchPolicy === self::CHECK_ALWAYS or ($this->watchPolicy === self::CHECK_ONCE and array_search($path, $this->checkedPaths) === false)) {
$cachedEntry = $this->cache->get($path); if (is_null($cachedEntry)) {
$cachedEntry = $this->cache->get($path);
}
$this->checkedPaths[] = $path; $this->checkedPaths[] = $path;
if ($this->storage->hasUpdated($path, $cachedEntry['storage_mtime'])) { if ($this->storage->hasUpdated($path, $cachedEntry['storage_mtime'])) {
if ($this->storage->is_dir($path)) { if ($this->storage->is_dir($path)) {
@ -73,7 +76,7 @@ class Watcher {
$this->cache->correctFolderSize($path); $this->cache->correctFolderSize($path);
return true; return true;
} }
return $cachedEntry; return false;
} else { } else {
return false; return false;
} }

View File

@ -313,7 +313,7 @@ class View {
if (!$result) { if (!$result) {
// If create file fails because of permissions on external storage like SMB folders, // If create file fails because of permissions on external storage like SMB folders,
// check file exists and return false if not. // check file exists and return false if not.
if(!$this->file_exists($path)){ if (!$this->file_exists($path)) {
return false; return false;
} }
if (is_null($mtime)) { if (is_null($mtime)) {
@ -891,22 +891,23 @@ class View {
if ($storage) { if ($storage) {
$cache = $storage->getCache($internalPath); $cache = $storage->getCache($internalPath);
if (!$cache->inCache($internalPath)) { $data = $cache->get($internalPath);
$watcher = $storage->getWatcher($internalPath);
// if the file is not in the cache or needs to be updated, trigger the scanner and reload the data
if (!$data) {
if (!$storage->file_exists($internalPath)) { if (!$storage->file_exists($internalPath)) {
return false; return false;
} }
$scanner = $storage->getScanner($internalPath); $scanner = $storage->getScanner($internalPath);
$scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
} else { $data = $cache->get($internalPath);
$watcher = $storage->getWatcher($internalPath); } else if ($watcher->checkUpdate($internalPath, $data)) {
$data = $watcher->checkUpdate($internalPath);
}
if (!is_array($data)) {
$data = $cache->get($internalPath); $data = $cache->get($internalPath);
} }
if ($data and isset($data['fileid'])) { if ($data and isset($data['fileid'])) {
// upgrades from oc6 or lower might not have the permissions set in the file cache
if ($data['permissions'] === 0) { if ($data['permissions'] === 0) {
$data['permissions'] = $storage->getPermissions($data['path']); $data['permissions'] = $storage->getPermissions($data['path']);
$cache->update($data['fileid'], array('permissions' => $data['permissions'])); $cache->update($data['fileid'], array('permissions' => $data['permissions']));
@ -956,26 +957,32 @@ class View {
if (!Filesystem::isValidPath($directory)) { if (!Filesystem::isValidPath($directory)) {
return $result; return $result;
} }
$path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory); $path = $this->getAbsolutePath($directory);
list($storage, $internalPath) = Filesystem::resolvePath($path); /** @var \OC\Files\Storage\Storage $storage */
list($storage, $internalPath) = $this->resolvePath($directory);
if ($storage) { if ($storage) {
$cache = $storage->getCache($internalPath); $cache = $storage->getCache($internalPath);
$user = \OC_User::getUser(); $user = \OC_User::getUser();
if ($cache->getStatus($internalPath) < Cache\Cache::COMPLETE) { $data = $cache->get($internalPath);
$watcher = $storage->getWatcher($internalPath);
if (!$data or $data['size'] === -1) {
if (!$storage->file_exists($internalPath)) {
return array();
}
$scanner = $storage->getScanner($internalPath); $scanner = $storage->getScanner($internalPath);
$scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
} else { $data = $cache->get($internalPath);
$watcher = $storage->getWatcher($internalPath); } else if ($watcher->checkUpdate($internalPath, $data)) {
$watcher->checkUpdate($internalPath); $data = $cache->get($internalPath);
} }
$folderId = $cache->getId($internalPath); $folderId = $data['fileid'];
/** /**
* @var \OC\Files\FileInfo[] $files * @var \OC\Files\FileInfo[] $files
*/ */
$files = array(); $files = array();
$contents = $cache->getFolderContents($internalPath, $folderId); //TODO: mimetype_filter $contents = $cache->getFolderContentsById($folderId); //TODO: mimetype_filter
foreach ($contents as $content) { foreach ($contents as $content) {
if ($content['permissions'] === 0) { if ($content['permissions'] === 0) {
$content['permissions'] = $storage->getPermissions($content['path']); $content['permissions'] = $storage->getPermissions($content['path']);
@ -1032,7 +1039,7 @@ class View {
break; break;
} }
} }
$rootEntry['path'] = substr($path . '/' . $rootEntry['name'], strlen($user) + 2); // full path without /$user/ $rootEntry['path'] = substr(Filesystem::normalizePath($path . '/' . $rootEntry['name']), strlen($user) + 2); // full path without /$user/
// if sharing was disabled for the user we remove the share permissions // if sharing was disabled for the user we remove the share permissions
if (\OCP\Util::isSharingDisabledForUser()) { if (\OCP\Util::isSharingDisabledForUser()) {
@ -1213,7 +1220,7 @@ class View {
* @return string|null * @return string|null
*/ */
public function getPath($id) { public function getPath($id) {
$id = (int) $id; $id = (int)$id;
$manager = Filesystem::getMountManager(); $manager = Filesystem::getMountManager();
$mounts = $manager->findIn($this->fakeRoot); $mounts = $manager->findIn($this->fakeRoot);
$mounts[] = $manager->find($this->fakeRoot); $mounts[] = $manager->find($this->fakeRoot);

View File

@ -177,8 +177,9 @@ class View extends \PHPUnit_Framework_TestCase {
function testCacheIncompleteFolder() { function testCacheIncompleteFolder() {
$storage1 = $this->getTestStorage(false); $storage1 = $this->getTestStorage(false);
\OC\Files\Filesystem::mount($storage1, array(), '/'); \OC\Files\Filesystem::clearMounts();
$rootView = new \OC\Files\View(''); \OC\Files\Filesystem::mount($storage1, array(), '/incomplete');
$rootView = new \OC\Files\View('/incomplete');
$entries = $rootView->getDirectoryContent('/'); $entries = $rootView->getDirectoryContent('/');
$this->assertEquals(3, count($entries)); $this->assertEquals(3, count($entries));