Skip to content
This repository has been archived by the owner on Nov 25, 2020. It is now read-only.

Commit

Permalink
Wrappers must declare isSeekable() to enable listing optimizations in…
Browse files Browse the repository at this point in the history
… fsAccessDriver.
  • Loading branch information
cdujeu committed Dec 29, 2015
1 parent 86c2fb0 commit c3f0f34
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 9 deletions.
20 changes: 20 additions & 0 deletions core/src/core/classes/class.AJXP_MetaStreamWrapper.php
Expand Up @@ -185,6 +185,17 @@ public static function isRemote()
throw new Exception("Do not call this method directly, but AJXP_MetaStreamWrapper::wrapperIsRemote() instead");
}

/**
* Describe whether the current wrapper operates on a remote server or not.
* @static
* @return boolean
* @throws Exception
*/
public static function isSeekable()
{
throw new Exception("Do not call this method directly, but AJXP_MetaStreamWrapper::wrapperIsSeekable() instead");
}

/**
* @param string $url
* @return boolean
Expand All @@ -194,6 +205,15 @@ public static function wrapperIsRemote($url){
return call_user_func(array(self::actualRepositoryWrapperClass($repositoryId), "isRemote"));
}

/**
* @param string $url
* @return boolean
*/
public static function wrapperIsSeekable($url){
$repositoryId = parse_url($url, PHP_URL_HOST);
return call_user_func(array(self::actualRepositoryWrapperClass($repositoryId), "isSeekable"));
}

public static function nodesUseSameWrappers($url1, $url2){
$w1 = self::actualRepositoryWrapperClass(parse_url($url1, PHP_URL_HOST));
$w2 = self::actualRepositoryWrapperClass(parse_url($url2, PHP_URL_HOST));
Expand Down
8 changes: 8 additions & 0 deletions core/src/core/classes/interface.AjxpWrapper.php
Expand Up @@ -60,6 +60,14 @@ public static function changeMode($path, $chmodValue);
*/
public static function isRemote();

/**
* Describe whether the current wrapper can rewind a stream or not.
* @static
* @abstract
* @return boolean
*/
public static function isSeekable();

/**
*
*
Expand Down
10 changes: 10 additions & 0 deletions core/src/plugins/access.dropbox/class.dropboxWrapper.php
Expand Up @@ -288,4 +288,14 @@ public function stream_open($path, $mode, $options, &$opened_path)
self::$crtHandle = fopen(self::$crtTmpFile, $mode);
return true;
}

/**
* Describe whether the current wrapper can rewind a stream or not.
* @static
* @return boolean
*/
public static function isSeekable()
{
return true;
}
}
49 changes: 41 additions & 8 deletions core/src/plugins/access.fs/class.fsAccessDriver.php
Expand Up @@ -943,7 +943,17 @@ public function switchAction($action, $httpVars, $fileVars)
break;
}

$countFiles = $this->countFiles($path, !$lsOptions["f"]);
$streamIsSeekable = AJXP_MetaStreamWrapper::wrapperIsSeekable($path);

$sharedHandle = null;
if($streamIsSeekable){
$handle = opendir($path);
$sharedHandle = $handle;
}
$countFiles = $this->countFiles($path, !$lsOptions["f"], false, $sharedHandle);
if(isSet($sharedHandle)){
rewind($handle);
}
if(isSet($crt_nodes)){
$crt_nodes += $countFiles;
}
Expand Down Expand Up @@ -981,28 +991,43 @@ public function switchAction($action, $httpVars, $fileVars)
"currentOrderDir"=> isSet($orderDirection)?$orderDirection:$defaultDirection
);
}
$foldersCounts = $this->countFiles($path, TRUE, false, $sharedHandle);
if(isSet($sharedHandle)) {
rewind($sharedHandle);
}
AJXP_XMLWriter::renderPaginationData(
$countFiles,
$crtPage,
$totalPages,
$this->countFiles($path, TRUE),
$foldersCounts,
$remoteOptions
);
if (!$lsOptions["f"]) {
AJXP_XMLWriter::close();
if(isSet($sharedHandle)) {
closedir($sharedHandle);
}
break;
}
}

$cursor = 0;
$handle = opendir($path);
if(isSet($sharedHandle)){
$handle = $sharedHandle;
}else{
$handle = opendir($path);
}
if (!$handle) {
throw new AJXP_Exception("Cannot open dir ".$nonPatchedPath);
}
$nodes = array();
while(strlen($file = readdir($handle))>0){
$nodes[] = $file;
}
closedir($handle);
$fullList = array("d" => array(), "z" => array(), "f" => array());

$nodes = scandir($path);
//$nodes = scandir($path);
$nodes = $this->orderNodes($nodes, $nonPatchedPath, $orderField, $orderDirection);

foreach ($nodes as $nodeName) {
Expand Down Expand Up @@ -1523,14 +1548,20 @@ public function readFile($filePathOrData, $headerType="plain", $localName="", $d
}
}

public function countFiles($dirName, $foldersOnly = false, $nonEmptyCheckOnly = false)
public function countFiles($dirName, $foldersOnly = false, $nonEmptyCheckOnly = false, $dirHANDLE = null)
{
$handle=@opendir($dirName);
if(is_resource($dirHANDLE)){
$handle = $dirHANDLE;
}else{
$handle=@opendir($dirName);
}
if ($handle === false) {
throw new Exception("Error while trying to open directory ".$dirName);
}
if ($foldersOnly && !AJXP_MetaStreamWrapper::wrapperIsRemote($dirName)) {
closedir($handle);
if($dirHANDLE == null || !is_resource($dirHANDLE)){
closedir($handle);
}
$path = AJXP_MetaStreamWrapper::getRealFSReference($dirName, true);
$dirs = glob($path."/*", GLOB_ONLYDIR|GLOB_NOSORT);
if($dirs === false) return 0;
Expand All @@ -1546,7 +1577,9 @@ public function countFiles($dirName, $foldersOnly = false, $nonEmptyCheckOnly =
if($nonEmptyCheckOnly) break;
}
}
closedir($handle);
if($dirHANDLE == null || !is_resource($dirHANDLE)){
closedir($handle);
}
return $count;
}

Expand Down
5 changes: 5 additions & 0 deletions core/src/plugins/access.fs/class.fsAccessWrapper.php
Expand Up @@ -246,6 +246,11 @@ public static function isRemote()
return false;
}

public static function isSeekable()
{
return true;
}

public static function copyFileInStream($path, $stream)
{
$fp = fopen(self::getRealFSReference($path), "rb");
Expand Down
10 changes: 9 additions & 1 deletion core/src/plugins/access.imap/class.imapAccessWrapper.php
Expand Up @@ -522,5 +522,13 @@ public function stream_flush()
}



/**
* Describe whether the current wrapper can rewind a stream or not.
* @static
* @return boolean
*/
public static function isSeekable()
{
return false;
}
}
Expand Up @@ -285,4 +285,13 @@ protected function createHttpClient()
}


/**
* Describe whether the current wrapper can rewind a stream or not.
* @static
* @return boolean
*/
public static function isSeekable()
{
return false;
}
}
5 changes: 5 additions & 0 deletions core/src/plugins/access.sftp/class.sftpAccessWrapper.php
Expand Up @@ -253,6 +253,11 @@ public static function isRemote()
return true;
}

public static function isSeekable()
{
return false;
}

/**
* Override parent function, testing feof() does not seem to work.
* We may have performance problems on big files here.
Expand Down
Expand Up @@ -39,6 +39,11 @@ public static function isRemote()
return true;
}

public static function isSeekable()
{
return false;
}

/**
* Initialize the stream from the given path.
*/
Expand Down
5 changes: 5 additions & 0 deletions core/src/plugins/access.swift/class.swiftAccessWrapper.php
Expand Up @@ -237,6 +237,11 @@ public static function isRemote()
return true;
}

public static function isSeekable()
{
return false;
}

public static function copyFileInStream($path, $stream)
{
$fp = fopen($path, "r", null, self::$cloudContext);
Expand Down
5 changes: 5 additions & 0 deletions core/src/plugins/access.webdav/class.webdavAccessWrapper.php
Expand Up @@ -207,6 +207,11 @@ public static function isRemote()
return true;
}

public static function isSeekable()
{
return true;
}

public static function copyFileInStream($path, $stream)
{
$fp = fopen(self::getRealFSReference($path), "rb");
Expand Down

0 comments on commit c3f0f34

Please sign in to comment.