Merge pull request #21648 from owncloud/smb-statcache-cap
cap the number of entries we cache in smb's statcache
This commit is contained in:
commit
5565b19382
|
@ -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'));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue