From 783888ed66c88cb9defb9da91b7d72982d65609f Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Mon, 16 Oct 2023 17:44:59 -0700 Subject: [PATCH] perf: make geoNameFolder lazy This class gets injected in DAV and the folder is fetched without ever being used, causing some useless queries, even for completely unrelated DAV requests. Signed-off-by: Varun Patil --- lib/Service/ReverseGeoCoderService.php | 33 ++++++++++++++++---------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/Service/ReverseGeoCoderService.php b/lib/Service/ReverseGeoCoderService.php index a92969259..1511f5496 100644 --- a/lib/Service/ReverseGeoCoderService.php +++ b/lib/Service/ReverseGeoCoderService.php @@ -38,20 +38,15 @@ use OCP\Http\Client\IClientService; class ReverseGeoCoderService { - private ISimpleFolder $geoNameFolder; + private ?ISimpleFolder $geoNameFolderCache = null; private ?NearestSearch $fsSearcher = null; /** @var array */ private ?array $citiesMapping = null; public function __construct( - IAppData $appData, + private IAppData $appData, private IClientService $clientService, ) { - try { - $this->geoNameFolder = $appData->getFolder("geonames"); - } catch (NotFoundException $ex) { - $this->geoNameFolder = $appData->newFolder("geonames"); - } } public function getPlaceForCoordinates(float $latitude, float $longitude): string { @@ -60,6 +55,18 @@ public function getPlaceForCoordinates(float $latitude, float $longitude): strin return $this->getPlaceNameForPlaceId($result[0]->getId()); } + private function geoNameFolder(): ISimpleFolder { + if ($this->geoNameFolderCache === null) { + try { + $this->geoNameFolderCache = $this->appData->getFolder("geonames"); + } catch (NotFoundException $ex) { + $this->geoNameFolderCache = $this->appData->newFolder("geonames"); + } + } + + return $this->geoNameFolderCache; + } + private function getPlaceNameForPlaceId(int $placeId): string { if ($this->citiesMapping === null) { $this->downloadCities1000(); @@ -74,7 +81,7 @@ private function getPlaceNameForPlaceId(int $placeId): string { } private function downloadCities1000(bool $force = false): void { - if ($this->geoNameFolder->fileExists('cities1000.csv') && !$force) { + if ($this->geoNameFolder()->fileExists('cities1000.csv') && !$force) { return; } @@ -94,7 +101,7 @@ private function downloadCities1000(bool $force = false): void { $cities1000TxtSteam = $zip->getStream('cities1000.txt'); // Dump the txt file info into a smaller csv file. - $destinationStream = $this->geoNameFolder->newFile('cities1000.csv')->write(); + $destinationStream = $this->geoNameFolder()->newFile('cities1000.csv')->write(); while (($fields = fgetcsv($cities1000TxtSteam, 0, " ")) !== false) { $result = fputcsv( @@ -116,7 +123,7 @@ private function downloadCities1000(bool $force = false): void { } private function loadCities1000(): array { - $csvStream = $this->geoNameFolder->getFile('cities1000.csv')->read(); + $csvStream = $this->geoNameFolder()->getFile('cities1000.csv')->read(); $cities = []; while (($fields = fgetcsv($csvStream)) !== false) { @@ -132,7 +139,7 @@ private function loadCities1000(): array { } public function buildKDTree($force = false): void { - if ($this->geoNameFolder->fileExists('cities1000.bin') && !$force) { + if ($this->geoNameFolder()->fileExists('cities1000.bin') && !$force) { return; } @@ -150,7 +157,7 @@ public function buildKDTree($force = false): void { $kdTreeTmpFileName = tempnam(sys_get_temp_dir(), "nextcloud_photos_"); $persister->convert($tree, $kdTreeTmpFileName); $kdTreeString = file_get_contents($kdTreeTmpFileName); - $this->geoNameFolder->newFile('cities1000.bin', $kdTreeString); + $this->geoNameFolder()->newFile('cities1000.bin', $kdTreeString); } private function loadKdTree(): void { @@ -159,7 +166,7 @@ private function loadKdTree(): void { } $this->buildKDTree(); - $kdTreeFileContent = $this->geoNameFolder->getFile("cities1000.bin")->getContent(); + $kdTreeFileContent = $this->geoNameFolder()->getFile("cities1000.bin")->getContent(); $kdTreeTmpFileName = tempnam(sys_get_temp_dir(), "nextcloud_photos_"); file_put_contents($kdTreeTmpFileName, $kdTreeFileContent); $fsTree = new FSKDTree($kdTreeTmpFileName, new ItemFactory());