@@ -35,6 +35,7 @@ use Icewind\SMB\NativeServer; | |||
use Icewind\SMB\Server; | |||
use Icewind\Streams\CallbackWrapper; | |||
use Icewind\Streams\IteratorDirectory; | |||
use OC\Cache\CappedMemoryCache; | |||
use OC\Files\Filesystem; | |||
class SMB extends Common { | |||
@@ -48,10 +49,15 @@ class SMB extends Common { | |||
*/ | |||
protected $share; | |||
/** | |||
* @var string | |||
*/ | |||
protected $root; | |||
/** | |||
* @var \Icewind\SMB\FileInfo[] | |||
*/ | |||
protected $statCache = array(); | |||
protected $statCache; | |||
public function __construct($params) { | |||
if (isset($params['host']) && isset($params['user']) && isset($params['password']) && isset($params['share'])) { | |||
@@ -72,6 +78,7 @@ class SMB extends Common { | |||
} else { | |||
throw new \Exception('Invalid configuration'); | |||
} | |||
$this->statCache = new CappedMemoryCache(); | |||
} | |||
/** |
@@ -0,0 +1,87 @@ | |||
<?php | |||
/** | |||
* @author Robin Appelman <icewind@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OC\Cache; | |||
use OCP\ICache; | |||
/** | |||
* In-memory cache with a capacity limit to keep memory usage in check | |||
* | |||
* Uses a simple FIFO expiry mechanism | |||
*/ | |||
class CappedMemoryCache implements ICache, \ArrayAccess { | |||
private $capacity; | |||
private $cache = []; | |||
public function __construct($capacity = 512) { | |||
$this->capacity = $capacity; | |||
} | |||
public function hasKey($key) { | |||
return isset($this->cache[$key]); | |||
} | |||
public function get($key) { | |||
return isset($this->cache[$key]) ? $this->cache[$key] : null; | |||
} | |||
public function set($key, $value, $ttl = 0) { | |||
$this->cache[$key] = $value; | |||
$this->garbageCollect(); | |||
} | |||
public function remove($key) { | |||
unset($this->cache[$key]); | |||
return true; | |||
} | |||
public function clear($prefix = '') { | |||
$this->cache = []; | |||
return true; | |||
} | |||
public function offsetExists($offset) { | |||
return $this->hasKey($offset); | |||
} | |||
public function offsetGet($offset) { | |||
return $this->get($offset); | |||
} | |||
public function offsetSet($offset, $value) { | |||
$this->set($offset, $value); | |||
} | |||
public function offsetUnset($offset) { | |||
$this->remove($offset); | |||
} | |||
private function garbageCollect() { | |||
while (count($this->cache) > $this->capacity) { | |||
reset($this->cache); | |||
$key = key($this->cache); | |||
$this->remove($key); | |||
} | |||
} | |||
} |
@@ -8,7 +8,7 @@ | |||
abstract class Test_Cache extends \Test\TestCase { | |||
/** | |||
* @var \OC\Cache cache; | |||
* @var \OCP\ICache cache; | |||
*/ | |||
protected $instance; | |||
@@ -0,0 +1,67 @@ | |||
<?php | |||
/** | |||
* ownCloud | |||
* | |||
* @author Robin Appelman | |||
* @copyright 2016 Robin Appelman icewind@owncloud.com | |||
* | |||
* This library is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or any later version. | |||
* | |||
* This library is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public | |||
* License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
namespace Test\Cache; | |||
/** | |||
* Class FileCache | |||
* | |||
* @group DB | |||
* | |||
* @package Test\Cache | |||
*/ | |||
class CappedMemoryCache extends \Test_Cache { | |||
public function setUp() { | |||
parent::setUp(); | |||
$this->instance = new \OC\Cache\CappedMemoryCache(); | |||
} | |||
public function testSetOverCap() { | |||
$instance = new \OC\Cache\CappedMemoryCache(3); | |||
$instance->set('1', 'a'); | |||
$instance->set('2', 'b'); | |||
$instance->set('3', 'c'); | |||
$instance->set('4', 'd'); | |||
$instance->set('5', 'e'); | |||
$this->assertFalse($instance->hasKey('1')); | |||
$this->assertFalse($instance->hasKey('2')); | |||
$this->assertTrue($instance->hasKey('3')); | |||
$this->assertTrue($instance->hasKey('4')); | |||
$this->assertTrue($instance->hasKey('5')); | |||
} | |||
function testClear() { | |||
$value = 'ipsum lorum'; | |||
$this->instance->set('1_value1', $value); | |||
$this->instance->set('1_value2', $value); | |||
$this->instance->set('2_value1', $value); | |||
$this->instance->set('3_value1', $value); | |||
$this->assertTrue($this->instance->clear()); | |||
$this->assertFalse($this->instance->hasKey('1_value1')); | |||
$this->assertFalse($this->instance->hasKey('1_value2')); | |||
$this->assertFalse($this->instance->hasKey('2_value1')); | |||
$this->assertFalse($this->instance->hasKey('3_value1')); | |||
} | |||
} |