summaryrefslogtreecommitdiffstats
path: root/apps/dav/lib/Upload
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2016-09-08 11:50:04 +0200
committerRoeland Jago Douma <roeland@famdouma.nl>2016-09-13 09:29:02 +0200
commit1ab472b9ad29b77e67633c72ed950a99dfc639d1 (patch)
tree945a9f901acb69e2241460c4866e6575300e2ee3 /apps/dav/lib/Upload
parentfeb85981cd6815083ee095d4c91b6ce8fbdfd50e (diff)
downloadnextcloud-server-1ab472b9ad29b77e67633c72ed950a99dfc639d1.tar.gz
nextcloud-server-1ab472b9ad29b77e67633c72ed950a99dfc639d1.zip
Improve chunk upload AssemblyStream performance
Diffstat (limited to 'apps/dav/lib/Upload')
-rw-r--r--apps/dav/lib/Upload/AssemblyStream.php39
1 files changed, 31 insertions, 8 deletions
diff --git a/apps/dav/lib/Upload/AssemblyStream.php b/apps/dav/lib/Upload/AssemblyStream.php
index 5853adfa77b..3a18f91677d 100644
--- a/apps/dav/lib/Upload/AssemblyStream.php
+++ b/apps/dav/lib/Upload/AssemblyStream.php
@@ -50,6 +50,9 @@ class AssemblyStream implements \Icewind\Streams\File {
/** @var int */
private $size;
+ /** @var resource */
+ private $currentStream = null;
+
/**
* @param string $path
* @param string $mode
@@ -102,16 +105,36 @@ class AssemblyStream implements \Icewind\Streams\File {
* @return string
*/
public function stream_read($count) {
+ do {
+ if ($this->currentStream === null) {
+ list($node, $posInNode) = $this->getNodeForPosition($this->pos);
+ if (is_null($node)) {
+ // reached last node, no more data
+ return '';
+ }
+ $this->currentStream = $this->getStream($node);
+ fseek($this->currentStream, $posInNode);
+ }
- list($node, $posInNode) = $this->getNodeForPosition($this->pos);
- if (is_null($node)) {
- return null;
- }
- $stream = $this->getStream($node);
+ $data = fread($this->currentStream, $count);
+ // isset is faster than strlen
+ if (isset($data[$count - 1])) {
+ // we read the full count
+ $read = $count;
+ } else {
+ // reaching end of stream, which happens less often so strlen is ok
+ $read = strlen($data);
+ }
- fseek($stream, $posInNode);
- $data = fread($stream, $count);
- $read = strlen($data);
+ if (feof($this->currentStream)) {
+ fclose($this->currentStream);
+ $this->currentNode = null;
+ $this->currentStream = null;
+ }
+ // if no data read, try again with the next node because
+ // returning empty data can make the caller think there is no more
+ // data left to read
+ } while ($read === 0);
// update position
$this->pos += $read;