From 68746e1bdbaa9ea5345ea9065566f720f425f68a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 12 Apr 2016 17:04:40 +0200 Subject: [PATCH 1/2] chunk the cleaning up of shared locks --- lib/private/Lock/DBLockingProvider.php | 27 +++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/private/Lock/DBLockingProvider.php b/lib/private/Lock/DBLockingProvider.php index 9e97df44d3..1865e94925 100644 --- a/lib/private/Lock/DBLockingProvider.php +++ b/lib/private/Lock/DBLockingProvider.php @@ -24,6 +24,7 @@ namespace OC\Lock; +use OC\DB\QueryBuilder\Literal; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IDBConnection; use OCP\ILogger; @@ -257,13 +258,25 @@ class DBLockingProvider extends AbstractLockingProvider { parent::releaseAll(); // since we keep shared locks we need to manually clean those - foreach ($this->sharedLocks as $path => $lock) { - if ($lock) { - $this->connection->executeUpdate( - 'UPDATE `*PREFIX*file_locks` SET `lock` = `lock` - 1 WHERE `key` = ? AND `lock` > 0', - [$path] - ); - } + $lockedPaths = array_keys($this->sharedLocks); + $lockedPaths = array_filter($lockedPaths, function ($path) { + return $this->sharedLocks[$path]; + }); + + $chunkedPaths = array_chunk($lockedPaths, 100); + + foreach ($chunkedPaths as $chunk) { + $builder = $this->connection->getQueryBuilder(); + $params = array_map(function ($path) use ($builder) { + return $builder->createNamedParameter($path); + }, $chunk); + + $query = $builder->update('file_locks') + ->set('lock', $builder->createFunction('`lock` -1')) + ->where($builder->expr()->in('key', $params)) + ->andWhere($builder->expr()->gt('lock', new Literal(0))); + + $query->execute(); } } } From 7b3191705c27c43e62c4459d0ce1f923fd5c2d8e Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 13 Apr 2016 10:05:11 +0200 Subject: [PATCH 2/2] Let the querybuilder convert --- lib/private/Lock/DBLockingProvider.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/private/Lock/DBLockingProvider.php b/lib/private/Lock/DBLockingProvider.php index 1865e94925..3a599a61e7 100644 --- a/lib/private/Lock/DBLockingProvider.php +++ b/lib/private/Lock/DBLockingProvider.php @@ -26,6 +26,7 @@ namespace OC\Lock; use OC\DB\QueryBuilder\Literal; use OCP\AppFramework\Utility\ITimeFactory; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use OCP\ILogger; use OCP\Lock\ILockingProvider; @@ -267,13 +268,10 @@ class DBLockingProvider extends AbstractLockingProvider { foreach ($chunkedPaths as $chunk) { $builder = $this->connection->getQueryBuilder(); - $params = array_map(function ($path) use ($builder) { - return $builder->createNamedParameter($path); - }, $chunk); $query = $builder->update('file_locks') ->set('lock', $builder->createFunction('`lock` -1')) - ->where($builder->expr()->in('key', $params)) + ->where($builder->expr()->in('key', $builder->createNamedParameter($chunk, IQueryBuilder::PARAM_STR_ARRAY))) ->andWhere($builder->expr()->gt('lock', new Literal(0))); $query->execute();