@@ -235,18 +235,8 @@ public function search($query) {
235235 $ query = $ this ->queryFromOperator (new SearchComparison (ISearchComparison::COMPARE_LIKE , 'name ' , '% ' . $ query . '% ' ));
236236 }
237237
238- // Limit+offset for queries with ordering
239- //
240- // Because we currently can't do ordering between the results from different storages in sql
241- // The only way to do ordering is requesting the $limit number of entries from all storages
242- // sorting them and returning the first $limit entries.
243- //
244- // For offset we have the same problem, we don't know how many entries from each storage should be skipped
245- // by a given $offset, so instead we query $offset + $limit from each storage and return entries $offset..($offset+$limit)
246- // after merging and sorting them.
247- //
248- // This is suboptimal but because limit and offset tend to be fairly small in real world use cases it should
249- // still be significantly better than disabling paging altogether
238+ // search is handled by a single query covering all caches that this folder contains
239+ // this is done by collect
250240
251241 $ limitToHome = $ query ->limitToHome ();
252242 if ($ limitToHome && count (explode ('/ ' , $ this ->path )) !== 3 ) {
@@ -258,11 +248,11 @@ public function search($query) {
258248 $ storage = $ mount ->getStorage ();
259249 $ internalPath = $ mount ->getInternalPath ($ this ->path );
260250
261- $ caches = [ '' => new CacheJail ( $ storage -> getCache ( '' ), $ internalPath )];
262- /** @var array{IMountPoint, string}[] $infoParams */
263- $ infoParams = [
264- '' => [ $ mount , '' ]
265- ];
251+ // collect all caches for this folder, indexed by their mountpoint relative to this folder
252+ // and save the mount which is needed later to construct the FileInfo objects
253+
254+ $ caches = [ '' => new CacheJail ( $ storage -> getCache ( '' ), $ internalPath )]; // a temporary CacheJail is used to handle filtering down the results to within this folder
255+ $ mountByMountPoint = [ '' => $ mount ];
266256
267257 if (!$ limitToHome ) {
268258 $ mounts = $ this ->root ->getMountsIn ($ this ->path );
@@ -271,18 +261,20 @@ public function search($query) {
271261 if ($ storage ) {
272262 $ relativeMountPoint = ltrim (substr ($ mount ->getMountPoint (), $ rootLength ), '/ ' );
273263 $ caches [$ relativeMountPoint ] = $ storage ->getCache ('' );
274- $ infoParams [$ relativeMountPoint ] = [ $ mount, '' ] ;
264+ $ mountByMountPoint [$ relativeMountPoint ] = $ mount ;
275265 }
276266 }
277267 }
278268
279269 /** @var QuerySearchHelper $searchHelper */
280270 $ searchHelper = \OC ::$ server ->get (QuerySearchHelper::class);
281271 $ resultsPerCache = $ searchHelper ->searchInCaches ($ query , $ caches );
282- $ files = array_merge (...array_map (function (array $ results , $ relativeMountPoint ) use ($ infoParams ) {
283- $ params = $ infoParams [$ relativeMountPoint ];
284- return array_map (function (ICacheEntry $ result ) use ($ relativeMountPoint , $ params ) {
285- return $ this ->cacheEntryToFileInfo ($ params [0 ], $ relativeMountPoint , $ params [1 ], $ result );
272+
273+ // loop trough all results per-cache, constructing the FileInfo object from the CacheEntry and merge them all
274+ $ files = array_merge (...array_map (function (array $ results , $ relativeMountPoint ) use ($ mountByMountPoint ) {
275+ $ mount = $ mountByMountPoint [$ relativeMountPoint ];
276+ return array_map (function (ICacheEntry $ result ) use ($ relativeMountPoint , $ mount ) {
277+ return $ this ->cacheEntryToFileInfo ($ mount , $ relativeMountPoint , $ result );
286278 }, $ results );
287279 }, array_values ($ resultsPerCache ), array_keys ($ resultsPerCache )));
288280
@@ -291,10 +283,9 @@ public function search($query) {
291283 }, $ files );
292284 }
293285
294- private function cacheEntryToFileInfo (IMountPoint $ mount , string $ appendRoot , string $ trimRoot , ICacheEntry $ cacheEntry ): FileInfo {
295- $ trimLength = strlen ($ trimRoot );
286+ private function cacheEntryToFileInfo (IMountPoint $ mount , string $ appendRoot , ICacheEntry $ cacheEntry ): FileInfo {
296287 $ cacheEntry ['internalPath ' ] = $ cacheEntry ['path ' ];
297- $ cacheEntry ['path ' ] = $ appendRoot . substr ( $ cacheEntry[ ' path ' ], $ trimLength );
288+ $ cacheEntry ['path ' ] = $ appendRoot . $ cacheEntry-> getPath ( );
298289 return new \OC \Files \FileInfo ($ this ->path . '/ ' . $ cacheEntry ['path ' ], $ mount ->getStorage (), $ cacheEntry ['internalPath ' ], $ cacheEntry , $ mount );
299290 }
300291
0 commit comments