apply object store copy optimization when 'cross storage' copy is within the same object store

Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
Robin Appelman 2021-02-19 15:52:58 +01:00 committed by backportbot[bot]
parent 60756e8e3e
commit 5827a156af
3 changed files with 39 additions and 1 deletions

View File

@ -38,6 +38,7 @@ use OCP\Files\Cache\ICacheEntry;
use OCP\Files\FileInfo; use OCP\Files\FileInfo;
use OCP\Files\NotFoundException; use OCP\Files\NotFoundException;
use OCP\Files\ObjectStore\IObjectStore; use OCP\Files\ObjectStore\IObjectStore;
use OCP\Files\Storage\IStorage;
class ObjectStoreStorage extends \OC\Files\Storage\Common { class ObjectStoreStorage extends \OC\Files\Storage\Common {
use CopyDirectory; use CopyDirectory;
@ -529,6 +530,19 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
return $this->objectStore; return $this->objectStore;
} }
public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class)) {
/** @var ObjectStoreStorage $sourceStorage */
if ($sourceStorage->getObjectStore()->getStorageId() === $this->getObjectStore()->getStorageId()) {
$sourceEntry = $sourceStorage->getCache()->get($sourceInternalPath);
$this->copyInner($sourceEntry, $targetInternalPath);
return true;
}
}
return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
}
public function copy($path1, $path2) { public function copy($path1, $path2) {
$path1 = $this->normalizePath($path1); $path1 = $this->normalizePath($path1);
$path2 = $this->normalizePath($path2); $path2 = $this->normalizePath($path2);

View File

@ -45,7 +45,7 @@ class Jail extends Wrapper {
protected $rootPath; protected $rootPath;
/** /**
* @param array $arguments ['storage' => $storage, 'mask' => $root] * @param array $arguments ['storage' => $storage, 'root' => $root]
* *
* $storage: The storage that will be wrapper * $storage: The storage that will be wrapper
* $root: The folder in the wrapped storage that will become the root folder of the wrapped storage * $root: The folder in the wrapped storage that will become the root folder of the wrapped storage

View File

@ -22,6 +22,7 @@ namespace Test\Files\ObjectStore;
use OC\Files\ObjectStore\StorageObjectStore; use OC\Files\ObjectStore\StorageObjectStore;
use OC\Files\Storage\Temporary; use OC\Files\Storage\Temporary;
use OC\Files\Storage\Wrapper\Jail;
use OCP\Files\ObjectStore\IObjectStore; use OCP\Files\ObjectStore\IObjectStore;
use Test\Files\Storage\Storage; use Test\Files\Storage\Storage;
@ -204,4 +205,27 @@ class ObjectStoreStorageTest extends Storage {
$this->assertTrue($cache->inCache('foo')); $this->assertTrue($cache->inCache('foo'));
$this->assertTrue($cache->inCache('foo/test.txt')); $this->assertTrue($cache->inCache('foo/test.txt'));
} }
public function testCopyBetweenJails() {
$this->instance->mkdir('a');
$this->instance->mkdir('b');
$jailA = new Jail([
'storage' => $this->instance,
'root' => 'a'
]);
$jailB = new Jail([
'storage' => $this->instance,
'root' => 'b'
]);
$jailA->mkdir('sub');
$jailA->file_put_contents('1.txt', '1');
$jailA->file_put_contents('sub/2.txt', '2');
$jailA->file_put_contents('sub/3.txt', '3');
$jailB->copyFromStorage($jailA, '', 'target');
$this->assertEquals('1', $this->instance->file_get_contents('b/target/1.txt'));
$this->assertEquals('2', $this->instance->file_get_contents('b/target/sub/2.txt'));
$this->assertEquals('3', $this->instance->file_get_contents('b/target/sub/3.txt'));
}
} }