summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlandos <bugs-github@antipoul.fr>2022-11-05 23:03:58 +0100
committerSimon L <szaimen@e.mail.de>2023-04-17 16:29:13 +0200
commit3440387f0f800cb4ee7380d59f65ccd64a265148 (patch)
treea7907188d53fb20d03be98f047bd7f6c799aeba8
parent384a1d34a8d9daf0b03e0a43e033f3389f5fe28d (diff)
downloadnextcloud-server-3440387f0f800cb4ee7380d59f65ccd64a265148.tar.gz
nextcloud-server-3440387f0f800cb4ee7380d59f65ccd64a265148.zip
gather code from small and max preview
use directory listing in both functions to gain 25% speed on run where every preview already exist. Signed-off-by: Glandos <bugs-github@antipoul.fr>
-rw-r--r--lib/private/Preview/Generator.php126
1 files changed, 36 insertions, 90 deletions
diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php
index a0b955ae2b7..10a02d15fa1 100644
--- a/lib/private/Preview/Generator.php
+++ b/lib/private/Preview/Generator.php
@@ -137,6 +137,8 @@ class Generator {
}
$previewFolder = $this->getPreviewFolder($file);
+ // List every existing preview first instead of trying to find them one by one
+ $previewFiles = $previewFolder->getDirectoryListing();
$previewVersion = '';
if ($file instanceof IVersionedPreviewFile) {
@@ -150,7 +152,7 @@ class Generator {
&& preg_match(Imaginary::supportedMimeTypes(), $mimeType)
&& $this->config->getSystemValueString('preview_imaginary_url', 'invalid') !== 'invalid') {
$crop = $specifications[0]['crop'] ?? false;
- $preview = $this->getSmallImagePreview($previewFolder, $file, $mimeType, $previewVersion, $crop);
+ $preview = $this->getSmallImagePreview($previewFolder, $previewFiles, $file, $mimeType, $previewVersion, $crop);
if ($preview->getSize() === 0) {
$preview->delete();
@@ -161,7 +163,7 @@ class Generator {
}
// Get the max preview and infer the max preview sizes from that
- $maxPreview = $this->getMaxPreview($previewFolder, $file, $mimeType, $previewVersion);
+ $maxPreview = $this->getMaxPreview($previewFolder, $previewFiles, $file, $mimeType, $previewVersion);
$maxPreviewImage = null; // only load the image when we need it
if ($maxPreview->getSize() === 0) {
$maxPreview->delete();
@@ -171,8 +173,6 @@ class Generator {
[$maxWidth, $maxHeight] = $this->getPreviewSize($maxPreview, $previewVersion);
$preview = null;
- // List every existing preview first instead of trying to find them one by one
- $previewFiles = $previewFolder->getDirectoryListing();
foreach ($specifications as $specification) {
$width = $specification['width'] ?? -1;
@@ -236,76 +236,20 @@ class Generator {
/**
* Generate a small image straight away without generating a max preview first
* Preview generated is 256x256
+ *
+ * @param ISimpleFile[] $previewFiles
*
* @throws NotFoundException
*/
- private function getSmallImagePreview(ISimpleFolder $previewFolder, File $file, string $mimeType, string $prefix, bool $crop): ISimpleFile {
- $nodes = $previewFolder->getDirectoryListing();
-
- foreach ($nodes as $node) {
- $name = $node->getName();
- if (($prefix === '' || str_starts_with($name, $prefix))) {
- // Prefix match
- if (str_starts_with($name, $prefix . '256-256-crop') && $crop) {
- // Cropped image
- return $node;
- }
-
- if (str_starts_with($name, $prefix . '256-256.') && !$crop) {
- // Uncropped image
- return $node;
- }
- }
- }
-
- $previewProviders = $this->previewManager->getProviders();
- foreach ($previewProviders as $supportedMimeType => $providers) {
- // Filter out providers that does not support this mime
- if (!preg_match($supportedMimeType, $mimeType)) {
- continue;
- }
-
- foreach ($providers as $providerClosure) {
- $provider = $this->helper->getProvider($providerClosure);
- if (!($provider instanceof IProviderV2)) {
- continue;
- }
-
- if (!$provider->isAvailable($file)) {
- continue;
- }
-
- $preview = $this->helper->getThumbnail($provider, $file, 256, 256, $crop);
-
- if (!($preview instanceof IImage)) {
- continue;
- }
+ private function getSmallImagePreview(ISimpleFolder $previewFolder, array $previewFiles, File $file, string $mimeType, string $prefix, bool $crop): ISimpleFile {
+ $width = 256;
+ $height = 256;
- // Try to get the extension.
- try {
- $ext = $this->getExtention($preview->dataMimeType());
- } catch (\InvalidArgumentException $e) {
- // Just continue to the next iteration if this preview doesn't have a valid mimetype
- continue;
- }
-
- $path = $this->generatePath(256, 256, $crop, $preview->dataMimeType(), $prefix);
- try {
- $file = $previewFolder->newFile($path);
- if ($preview instanceof IStreamImage) {
- $file->putContent($preview->resource());
- } else {
- $file->putContent($preview->data());
- }
- } catch (NotPermittedException $e) {
- throw new NotFoundException();
- }
-
- return $file;
- }
+ try {
+ return $this->getCachedPreview($previewFiles, $width, $height, $crop, $mimeType, $prefix);
+ } catch (NotFoundException) {
+ return $this->generateProviderPreview($previewFolder, $file, $width, $height, $crop, false, $mimeType, $prefix);
}
-
- throw new NotFoundException('No provider successfully handled the preview generation');
}
/**
@@ -402,22 +346,30 @@ class Generator {
/**
* @param ISimpleFolder $previewFolder
+ * @param ISimpleFile[] $previewFiles
* @param File $file
* @param string $mimeType
* @param string $prefix
* @return ISimpleFile
* @throws NotFoundException
*/
- private function getMaxPreview(ISimpleFolder $previewFolder, File $file, $mimeType, $prefix) {
- $nodes = $previewFolder->getDirectoryListing();
-
- foreach ($nodes as $node) {
+ private function getMaxPreview(ISimpleFolder $previewFolder, array $previewFiles, File $file, $mimeType, $prefix) {
+ // We don't know the max preview size, so we can't use getCachedPreview.
+ // It might have been generated with a higher resolution than the current value.
+ foreach ($previewFiles as $node) {
$name = $node->getName();
if (($prefix === '' || strpos($name, $prefix) === 0) && strpos($name, 'max')) {
return $node;
}
}
+ $maxWidth = $this->config->getSystemValueInt('preview_max_x', 4096);
+ $maxHeight = $this->config->getSystemValueInt('preview_max_y', 4096);
+
+ return $this->generateProviderPreview($previewFolder, $file, $maxWidth, $maxHeight, false, true, $mimeType, $prefix);
+ }
+
+ private function generateProviderPreview(ISimpleFolder $previewFolder, File $file, int $width, int $height, bool $crop, bool $max, string $mimeType, string $prefix) {
$previewProviders = $this->previewManager->getProviders();
foreach ($previewProviders as $supportedMimeType => $providers) {
// Filter out providers that does not support this mime
@@ -435,13 +387,10 @@ class Generator {
continue;
}
- $maxWidth = $this->config->getSystemValueInt('preview_max_x', 4096);
- $maxHeight = $this->config->getSystemValueInt('preview_max_y', 4096);
-
$previewConcurrency = $this->getNumConcurrentPreviews('preview_concurrency_new');
$sem = self::guardWithSemaphore(self::SEMAPHORE_ID_NEW, $previewConcurrency);
try {
- $preview = $this->helper->getThumbnail($provider, $file, $maxWidth, $maxHeight);
+ $preview = $this->helper->getThumbnail($provider, $file, $width, $height);
} finally {
self::unguardWithSemaphore($sem);
}
@@ -450,15 +399,7 @@ class Generator {
continue;
}
- // Try to get the extention.
- try {
- $ext = $this->getExtention($preview->dataMimeType());
- } catch (\InvalidArgumentException $e) {
- // Just continue to the next iteration if this preview doesn't have a valid mimetype
- continue;
- }
-
- $path = $prefix . (string)$preview->width() . '-' . (string)$preview->height() . '-max.' . $ext;
+ $path = $this->generatePath($preview->width(), $preview->height(), $crop, $max, $preview->dataMimeType(), $prefix);
try {
$file = $previewFolder->newFile($path);
if ($preview instanceof IStreamImage) {
@@ -474,7 +415,7 @@ class Generator {
}
}
- throw new NotFoundException();
+ throw new NotFoundException('No provider successfully handled the preview generation');
}
/**
@@ -491,15 +432,19 @@ class Generator {
* @param int $width
* @param int $height
* @param bool $crop
+ * @param bool $max
* @param string $mimeType
* @param string $prefix
* @return string
*/
- private function generatePath($width, $height, $crop, $mimeType, $prefix) {
+ private function generatePath($width, $height, $crop, $max, $mimeType, $prefix) {
$path = $prefix . (string)$width . '-' . (string)$height;
if ($crop) {
$path .= '-crop';
}
+ if ($max) {
+ $path .= '-max';
+ }
$ext = $this->getExtention($mimeType);
$path .= '.' . $ext;
@@ -641,7 +586,8 @@ class Generator {
self::unguardWithSemaphore($sem);
}
- $path = $this->generatePath($width, $height, $crop, $preview->dataMimeType(), $prefix);
+
+ $path = $this->generatePath($width, $height, $crop, false, $preview->dataMimeType(), $prefix);
try {
$file = $previewFolder->newFile($path);
$file->putContent($preview->data());
@@ -664,7 +610,7 @@ class Generator {
* @throws NotFoundException
*/
private function getCachedPreview($files, $width, $height, $crop, $mimeType, $prefix) {
- $path = $this->generatePath($width, $height, $crop, $mimeType, $prefix);
+ $path = $this->generatePath($width, $height, $crop, false, $mimeType, $prefix);
foreach ($files as $file) {
if ($file->getName() === $path) {
return $file;