]> source.dussan.org Git - nextcloud-server.git/commitdiff
fix(dav): Reduce CalDAV backend memory footprint 40665/head
authorChristoph Wurst <christoph@winzerhof-wurst.at>
Wed, 27 Sep 2023 16:36:45 +0000 (18:36 +0200)
committerChristoph Wurst <christoph@winzerhof-wurst.at>
Thu, 2 Nov 2023 10:12:34 +0000 (11:12 +0100)
fetchAll inflates memory. Fetching in a loop allows GC to run earlier
and more often.

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
apps/dav/lib/CalDAV/CalDavBackend.php

index 5f2fe7e5dcead00942916b7140d62aa5251fde67..249dbca9f71f7d37cc5b19fbf5fc13603dec4d91 100644 (file)
@@ -281,14 +281,15 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                        ->where($qb->expr()->isNotNull('deleted_at'))
                        ->andWhere($qb->expr()->lt('deleted_at', $qb->createNamedParameter($deletedBefore)));
                $result = $qb->executeQuery();
-               $raw = $result->fetchAll();
-               $result->closeCursor();
-               return array_map(function ($row) {
-                       return [
+               $calendars = [];
+               while (($row = $result->fetch()) !== false) {
+                       $calendars[] = [
                                'id' => (int) $row['id'],
                                'deleted_at' => (int) $row['deleted_at'],
                        ];
-               }, $raw);
+               }
+               $result->closeCursor();
+               return $calendars;
        }
 
        /**
@@ -1011,7 +1012,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                $stmt = $query->executeQuery();
 
                $result = [];
-               foreach ($stmt->fetchAll() as $row) {
+               while (($row = $stmt->fetch()) !== false) {
                        $result[] = [
                                'id' => $row['id'],
                                'uri' => $row['uri'],
@@ -1038,7 +1039,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                $stmt = $query->executeQuery();
 
                $result = [];
-               foreach ($stmt->fetchAll() as $row) {
+               while (($row = $stmt->fetch()) !== false) {
                        $result[] = [
                                'id' => $row['id'],
                                'uri' => $row['uri'],
@@ -1925,13 +1926,15 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                }
 
                $result = $outerQuery->executeQuery();
-               $calendarObjects = array_filter($result->fetchAll(), function (array $row) use ($options) {
+               $calendarObjects = [];
+               while (($row = $result->fetch()) !== false) {
                        $start = $options['timerange']['start'] ?? null;
                        $end = $options['timerange']['end'] ?? null;
 
                        if ($start === null || !($start instanceof DateTimeInterface) || $end === null || !($end instanceof DateTimeInterface)) {
                                // No filter required
-                               return true;
+                               $calendarObjects[] = $row;
+                               continue;
                        }
 
                        $isValid = $this->validateFilterForObject($row, [
@@ -1956,8 +1959,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                                // Put the stream back to the beginning so it can be read another time
                                rewind($row['calendardata']);
                        }
-                       return $isValid;
-               });
+                       if ($isValid) {
+                               $calendarObjects[] = $row;
+                       }
+               }
                $result->closeCursor();
 
                return array_map(function ($o) use ($options) {
@@ -2157,11 +2162,11 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                        }
 
                        $result = $calendarObjectIdQuery->executeQuery();
-                       $matches = $result->fetchAll();
+                       $matches = [];
+                       while (($row = $result->fetch()) !== false) {
+                               $matches[] = (int) $row['objectid'];
+                       }
                        $result->closeCursor();
-                       $matches = array_map(static function (array $match):int {
-                               return (int) $match['objectid'];
-                       }, $matches);
 
                        $query = $this->db->getQueryBuilder();
                        $query->select('calendardata', 'uri', 'calendarid', 'calendartype')
@@ -2169,16 +2174,16 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                                ->where($query->expr()->in('id', $query->createNamedParameter($matches, IQueryBuilder::PARAM_INT_ARRAY)));
 
                        $result = $query->executeQuery();
-                       $calendarObjects = $result->fetchAll();
-                       $result->closeCursor();
-
-                       return array_map(function (array $array): array {
+                       $calendarObjects = [];
+                       while (($array = $result->fetch()) !== false) {
                                $array['calendarid'] = (int)$array['calendarid'];
                                $array['calendartype'] = (int)$array['calendartype'];
                                $array['calendardata'] = $this->readBlob($array['calendardata']);
 
-                               return $array;
-                       }, $calendarObjects);
+                               $calendarObjects[] = $array;
+                       }
+                       $result->closeCursor();
+                       return $calendarObjects;
                }, $this->db);
        }
 
@@ -2656,9 +2661,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                                ->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
                                ->executeQuery();
 
-               $result = [];
-               foreach ($stmt->fetchAll() as $row) {
-                       $result[] = [
+               $results = [];
+               while (($row = $stmt->fetch()) !== false) {
+                       $results[] = [
                                'calendardata' => $row['calendardata'],
                                'uri' => $row['uri'],
                                'lastmodified' => $row['lastmodified'],
@@ -2668,7 +2673,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                }
                $stmt->closeCursor();
 
-               return $result;
+               return $results;
        }
 
        /**
@@ -3046,14 +3051,13 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                                ->where($query->expr()->eq('uri', $query->createNamedParameter(BirthdayService::BIRTHDAY_CALENDAR_URI)))
                                ->executeQuery();
 
-                       $ids = $result->fetchAll();
-                       $result->closeCursor();
-                       foreach ($ids as $id) {
+                       while (($row = $result->fetch()) !== false) {
                                $this->deleteCalendar(
-                                       $id['id'],
+                                       $row['id'],
                                        true // No data to keep in the trashbin, if the user re-enables then we regenerate
                                );
                        }
+                       $result->closeCursor();
                }, $this->db);
        }
 
@@ -3070,7 +3074,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                        $stmt = $query->executeQuery();
 
                        $uris = [];
-                       foreach ($stmt->fetchAll() as $row) {
+                       while (($row = $stmt->fetch()) !== false) {
                                $uris[] = $row['uri'];
                        }
                        $stmt->closeCursor();