From 91b31bfb15a5695da187deaa0dc9122c617a8f93 Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Wed, 27 Sep 2023 18:36:45 +0200 Subject: [PATCH] fix(dav): Reduce CalDAV backend memory footprint fetchAll inflates memory. Fetching in a loop allows GC to run earlier and more often. Signed-off-by: Christoph Wurst --- apps/dav/lib/CalDAV/CalDavBackend.php | 64 ++++++++++++++------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 5f2fe7e5dce..249dbca9f71 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -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(); -- 2.39.5