From ce10f8b8c42ab67a1bf523a31e72cdcf13a98900 Mon Sep 17 00:00:00 2001
From: Roeland Jago Douma <roeland@famdouma.nl>
Date: Wed, 31 Oct 2018 13:40:41 +0100
Subject: [PATCH] Only generate previews in powers of 4 and set min

Before we'd round up all preview request to their nearest power of two.
This resulted still in a lot of possible images. Generating a lot of
server load and taking up a lot of space.

This moves it to previews to be powers of 4: 64, 256, 1024 and 4096
Also the first two powers are always skipped (4, 16) as it doesn't make
sense to generate previews for that.

We cache preview pretty agressively and I feel this is a better
tradeoff.

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
---
 lib/private/Preview/Generator.php   | 18 +++++++++++-------
 tests/lib/Preview/GeneratorTest.php | 22 ++++++++++++++--------
 2 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php
index 86579e3480b..1f7decf2b79 100644
--- a/lib/private/Preview/Generator.php
+++ b/lib/private/Preview/Generator.php
@@ -298,19 +298,23 @@ class Generator {
 
 		if ($height !== $maxHeight && $width !== $maxWidth) {
 			/*
-			 * Scale to the nearest power of two
+			 * Scale to the nearest power of four
 			 */
-			$pow2height = 2 ** ceil(log($height) / log(2));
-			$pow2width = 2 ** ceil(log($width) / log(2));
+			$pow4height = 4 ** ceil(log($height) / log(4));
+			$pow4width = 4 ** ceil(log($width) / log(4));
 
-			$ratioH = $height / $pow2height;
-			$ratioW = $width / $pow2width;
+			// Minimum size is 64
+			$pow4height = max($pow4height, 64);
+			$pow4width = max($pow4width, 64);
+
+			$ratioH = $height / $pow4height;
+			$ratioW = $width / $pow4width;
 
 			if ($ratioH < $ratioW) {
-				$width = $pow2width;
+				$width = $pow4width;
 				$height /= $ratioW;
 			} else {
-				$height = $pow2height;
+				$height = $pow4height;
 				$width /= $ratioH;
 			}
 		}
diff --git a/tests/lib/Preview/GeneratorTest.php b/tests/lib/Preview/GeneratorTest.php
index 64786fa9fe8..565b526b659 100644
--- a/tests/lib/Preview/GeneratorTest.php
+++ b/tests/lib/Preview/GeneratorTest.php
@@ -104,7 +104,7 @@ class GeneratorTest extends \Test\TestCase {
 		$previewFile = $this->createMock(ISimpleFile::class);
 
 		$previewFolder->method('getFile')
-			->with($this->equalTo('128-128.png'))
+			->with($this->equalTo('256-256.png'))
 			->willReturn($previewFile);
 
 		$this->eventDispatcher->expects($this->once())
@@ -212,7 +212,7 @@ class GeneratorTest extends \Test\TestCase {
 			->will($this->returnCallback(function($filename) use ($maxPreview, $previewFile) {
 				if ($filename === '2048-2048-max.png') {
 					return $maxPreview;
-				} else if ($filename === '128-128.png') {
+				} else if ($filename === '256-256.png') {
 					return $previewFile;
 				}
 				$this->fail('Unexpected file');
@@ -223,7 +223,7 @@ class GeneratorTest extends \Test\TestCase {
 			->with($this->equalTo('my data'));
 
 		$previewFolder->method('getFile')
-			->with($this->equalTo('128-128.png'))
+			->with($this->equalTo('256-256.png'))
 			->willThrowException(new NotFoundException());
 
 		$image = $this->createMock(IImage::class);
@@ -233,7 +233,7 @@ class GeneratorTest extends \Test\TestCase {
 
 		$image->expects($this->once())
 			->method('resize')
-			->with(128);
+			->with(256);
 		$image->method('data')
 			->willReturn('my resized data');
 		$image->method('valid')->willReturn(true);
@@ -328,8 +328,8 @@ class GeneratorTest extends \Test\TestCase {
 		return [
 			[1024, 2048, 512, 512, false, IPreview::MODE_FILL, 256, 512],
 			[1024, 2048, 512, 512, false, IPreview::MODE_COVER, 512, 1024],
-			[1024, 2048, 512, 512, true, IPreview::MODE_FILL, 512, 512],
-			[1024, 2048, 512, 512, true, IPreview::MODE_COVER, 512, 512],
+			[1024, 2048, 512, 512, true, IPreview::MODE_FILL, 1024, 1024],
+			[1024, 2048, 512, 512, true, IPreview::MODE_COVER, 1024, 1024],
 
 			[1024, 2048, -1, 512, false, IPreview::MODE_COVER, 256, 512],
 			[1024, 2048, 512, -1, false, IPreview::MODE_FILL, 512, 1024],
@@ -343,14 +343,20 @@ class GeneratorTest extends \Test\TestCase {
 
 			[2048, 1024, 512, 512, false, IPreview::MODE_FILL, 512, 256],
 			[2048, 1024, 512, 512, false, IPreview::MODE_COVER, 1024, 512],
-			[2048, 1024, 512, 512, true, IPreview::MODE_FILL, 512, 512],
-			[2048, 1024, 512, 512, true, IPreview::MODE_COVER, 512, 512],
+			[2048, 1024, 512, 512, true, IPreview::MODE_FILL, 1024, 1024],
+			[2048, 1024, 512, 512, true, IPreview::MODE_COVER, 1024, 1024],
 
 			[2048, 1024, -1, 512, false, IPreview::MODE_FILL, 1024, 512],
 			[2048, 1024, 512, -1, false, IPreview::MODE_COVER, 512, 256],
 
 			[2048, 1024, 4096, 1024, true, IPreview::MODE_FILL, 2048, 512],
 			[2048, 1024, 4096, 1024, true, IPreview::MODE_COVER, 2048, 512],
+
+			//Test minimum size
+			[2048, 1024, 32, 32, false, IPreview::MODE_FILL, 64, 32],
+			[2048, 1024, 32, 32, false, IPreview::MODE_COVER, 64, 32],
+			[2048, 1024, 32, 32, true, IPreview::MODE_FILL, 64, 64],
+			[2048, 1024, 32, 32, true, IPreview::MODE_COVER, 64, 64],
 		];
 	}
 
-- 
GitLab