Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2021-05-05 20:36:41 +0300
committerRobin Appelman <robin@icewind.nl>2021-06-14 17:11:29 +0300
commit5d1d53c42e9a8342f9fd2da815e6653a64203c0c (patch)
treeab4821636cf77ef7d4cfa0cacaceff12d430692f /lib/private
parent9774fb1573d30e79eb57f8956f64b13b52b7dee9 (diff)
perform file search in a single query
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/Files/Cache/Cache.php2
-rw-r--r--lib/private/Files/Cache/QuerySearchHelper.php16
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheWrapper.php2
-rw-r--r--lib/private/Files/Node/Folder.php71
4 files changed, 31 insertions, 60 deletions
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php
index 592e71b2b70..c2f426acd2d 100644
--- a/lib/private/Files/Cache/Cache.php
+++ b/lib/private/Files/Cache/Cache.php
@@ -803,7 +803,7 @@ class Cache implements ICache {
}
public function searchQuery(ISearchQuery $searchQuery) {
- return $this->querySearchHelper->searchInCaches($searchQuery, [$this]);
+ return current($this->querySearchHelper->searchInCaches($searchQuery, [$this]));
}
/**
diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php
index 6bf3835df6c..64a888f492c 100644
--- a/lib/private/Files/Cache/QuerySearchHelper.php
+++ b/lib/private/Files/Cache/QuerySearchHelper.php
@@ -29,6 +29,7 @@ use OC\Files\Search\SearchBinaryOperator;
use OC\SystemConfig;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICache;
+use OCP\Files\Cache\ICacheEntry;
use OCP\Files\IMimeTypeLoader;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison;
@@ -254,9 +255,10 @@ class QuerySearchHelper {
}
/**
+ * @template T of array-key
* @param ISearchQuery $searchQuery
- * @param ICache[] $caches
- * @return CacheEntry[]
+ * @param array<T, ICache> $caches
+ * @return array<T, ICacheEntry[]>
*/
public function searchInCaches(ISearchQuery $searchQuery, array $caches): array {
// search in multiple caches at once by creating one query in the following format
@@ -297,9 +299,9 @@ class QuerySearchHelper {
$query->andWhere($searchExpr);
}
- $storageFilters = array_map(function (ICache $cache) {
+ $storageFilters = array_values(array_map(function (ICache $cache) {
return $cache->getQueryFilterForStorage();
- }, $caches);
+ }, $caches));
$query->andWhere($this->searchOperatorToDBExpr($builder, new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, $storageFilters)));
if ($searchQuery->limitToHome() && ($this instanceof HomeCache)) {
@@ -325,12 +327,12 @@ class QuerySearchHelper {
$result->closeCursor();
// loop trough all caches for each result to see if the result matches that storage
- $results = [];
+ $results = array_fill_keys(array_keys($caches), []);
foreach ($rawEntries as $rawEntry) {
- foreach ($caches as $cache) {
+ foreach ($caches as $cacheKey => $cache) {
$entry = $cache->getCacheEntryFromSearchResult($rawEntry);
if ($entry) {
- $results[] = $entry;
+ $results[$cacheKey][] = $entry;
}
}
}
diff --git a/lib/private/Files/Cache/Wrapper/CacheWrapper.php b/lib/private/Files/Cache/Wrapper/CacheWrapper.php
index 70f05103865..e25282942b2 100644
--- a/lib/private/Files/Cache/Wrapper/CacheWrapper.php
+++ b/lib/private/Files/Cache/Wrapper/CacheWrapper.php
@@ -226,7 +226,7 @@ class CacheWrapper extends Cache {
}
public function searchQuery(ISearchQuery $searchQuery) {
- return $this->querySearchHelper->searchInCaches($searchQuery, [$this]);
+ return current($this->querySearchHelper->searchInCaches($searchQuery, [$this]));
}
/**
diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php
index 7198c576fd9..82515feba03 100644
--- a/lib/private/Files/Node/Folder.php
+++ b/lib/private/Files/Node/Folder.php
@@ -30,6 +30,10 @@
*/
namespace OC\Files\Node;
+use OC\DB\QueryBuilder\Literal;
+use OC\Files\Cache\QuerySearchHelper;
+use OC\Files\Search\SearchBinaryOperator;
+use OC\Files\Cache\Wrapper\CacheJail;
use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchOrder;
@@ -252,69 +256,34 @@ class Folder extends Node implements \OCP\Files\Folder {
$mount = $this->root->getMount($this->path);
$storage = $mount->getStorage();
$internalPath = $mount->getInternalPath($this->path);
- $internalPath = rtrim($internalPath, '/');
- if ($internalPath !== '') {
- $internalPath = $internalPath . '/';
- }
-
- $subQueryLimit = $query->getLimit() > 0 ? $query->getLimit() + $query->getOffset() : 0;
- $rootQuery = new SearchQuery(
- new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
- new SearchComparison(ISearchComparison::COMPARE_LIKE, 'path', $internalPath . '%'),
- $query->getSearchOperation(),
- ]),
- $subQueryLimit,
- 0,
- $query->getOrder(),
- $query->getUser()
- );
-
- $files = [];
- $cache = $storage->getCache('');
-
- $results = $cache->searchQuery($rootQuery);
- foreach ($results as $result) {
- $files[] = $this->cacheEntryToFileInfo($mount, '', $internalPath, $result);
- }
+ $caches = ['' => new CacheJail($storage->getCache(''), $internalPath)];
+ /** @var array{IMountPoint, string}[] $infoParams */
+ $infoParams = [
+ '' => [$mount, '']
+ ];
if (!$limitToHome) {
$mounts = $this->root->getMountsIn($this->path);
foreach ($mounts as $mount) {
- $subQuery = new SearchQuery(
- $query->getSearchOperation(),
- $subQueryLimit,
- 0,
- $query->getOrder(),
- $query->getUser()
- );
-
$storage = $mount->getStorage();
if ($storage) {
- $cache = $storage->getCache('');
-
$relativeMountPoint = ltrim(substr($mount->getMountPoint(), $rootLength), '/');
- $results = $cache->searchQuery($subQuery);
- foreach ($results as $result) {
- $files[] = $this->cacheEntryToFileInfo($mount, $relativeMountPoint, '', $result);
- }
+ $caches[$relativeMountPoint] = $storage->getCache('');
+ $infoParams[$relativeMountPoint] = [$mount, ''];
}
}
}
- $order = $query->getOrder();
- if ($order) {
- usort($files, function (FileInfo $a, FileInfo $b) use ($order) {
- foreach ($order as $orderField) {
- $cmp = $orderField->sortFileInfo($a, $b);
- if ($cmp !== 0) {
- return $cmp;
- }
- }
- return 0;
- });
- }
- $files = array_values(array_slice($files, $query->getOffset(), $query->getLimit() > 0 ? $query->getLimit() : null));
+ /** @var QuerySearchHelper $searchHelper */
+ $searchHelper = \OC::$server->get(QuerySearchHelper::class);
+ $resultsPerCache = $searchHelper->searchInCaches($query, $caches);
+ $files = array_merge(...array_map(function(array $results, $relativeMountPoint) use ($infoParams) {
+ $params = $infoParams[$relativeMountPoint];
+ return array_map(function(ICacheEntry $result) use ($relativeMountPoint, $params) {
+ return $this->cacheEntryToFileInfo($params[0], $relativeMountPoint, $params[1], $result);
+ }, $results);
+ }, array_values($resultsPerCache), array_keys($resultsPerCache)));
return array_map(function (FileInfo $file) {
return $this->createNode($file->getPath(), $file);