在10W以内比直接生成单文件的效率提高了一倍
在10W以外,效率直线下降
//====================================================
// FileName: mkcache.class.php
// Summary: 单文件缓存类
// Author: millken
// LastModifed:2009-10-23 9:51
// copyright (c)2009 millken@gmail.com
//====================================================
error_reporting(E_ALL);
set_time_limit(0);
class MKCACHE {
private $cachelist = array();
private $cachefile = 'data';
private $dbf = '.dbf';
private $index = '.index';
private $left = '.left';
private $handle;
public function __construct($cachefile='') {
$this->dbfile = file_exists($cachefile.$this->dbf)?$cachefile.$this->dbf : dirname(__FILE__).DIRECTORY_SEPARATOR.$this->cachefile.$this->dbf;
$this->indexfile = file_exists($cachefile.$this->index)?$cachefile.$this->index : dirname(__FILE__).DIRECTORY_SEPARATOR.$this->cachefile.$this->index;
$this->leftfile = file_exists($cachefile.$this->left)?$cachefile.$this->left : dirname(__FILE__).DIRECTORY_SEPARATOR.$this->cachefile.$this->left;
!file_exists($this->dbfile) && touch($this->dbfile);
!file_exists($this->indexfile) && touch($this->indexfile);
!file_exists($this->leftfile) && touch($this->leftfile);
}
public function set($key,$value,$expiry=600) {
if(strlen($key) == '' || strlen($value) == '')return false;
$this->del($key);
$content = serialize($value);
$conlen = strlen($content);
$unpos = $this->getleft($conlen);
$mode = 'r+b';
if($unpos == false)$unpos = $this->lastpos();
$array = array(
'key' => $key,
'offset' => $unpos,
'length' => $conlen,
'expiry' => time()+$expiry,
);
$this->writeindex($array);
$this->handle=fopen($this->dbfile, $mode);
if (flock($this->handle, LOCK_EX)) { // 进行排它型锁定
fseek($this->handle, $unpos, SEEK_SET);
//$content = gzcompress($content,9);
fwrite($this->handle, $content, $conlen);
flock($this->handle, LOCK_UN); // 释放锁定
fclose($this->handle);
return true;
} else {
return false;
}
}
public function get($key) {
$keyidx = $this->findkey($key);
if($keyidx == false)return false;
if(time() > $keyidx[3]) {
$this->del($key);
return false;
}
$content = file_get_contents($this->dbfile, false, null, $keyidx[1], $keyidx[2]+1);
if(strlen($content)>0)
return unserialize($content);
return false;
}
public function del($key) {
$keyidx = $this->findkey($key);
if($keyidx == false)return false;
$indexcontent = file_get_contents($this->indexfile);
$indexcontent = str_replace($keyidx[0],'',$indexcontent);
file_put_contents($this->indexfile,$indexcontent,LOCK_EX);
$leftcontent = "|$keyidx[1]:$keyidx[2]|";
file_put_contents($this->leftfile,$leftcontent,FILE_APPEND);
return true;
}
public function flush() {
unlink($this->dbfile);
unlink($this->indexfile);
unlink($this->leftfile);
}
private function findkey($key) {
$indexcontent = file_get_contents($this->indexfile);
$keypos = preg_match("~\|$key\:(\d+)\:(\d+):(\d+)\|~sx",$indexcontent,$keyidx);
unset($indexcontent);
if($keypos == 0 || empty($keyidx))return false;
return $keyidx;
}
private function lastpos() {
$this->handle = fopen($this->dbfile, 'r+');
fseek($this->handle, 0, SEEK_END);
$offset = ftell($this->handle);
fclose($this->handle);
return $offset;
}
private function writeindex($array) {
$content = "|{$array['key']}:{$array['offset']}:{$array['length']}:{$array['expiry']}|";
return file_put_contents($this->indexfile,$content,FILE_APPEND);
}
private function getleft($len) {
$leftcontent = file_get_contents($this->leftfile);
preg_match_all("~\|(\d+)\:(\d+)\|~sx", $leftcontent, $leftidx, PREG_SET_ORDER);
$arr = $arr1 = $arr2 = array();
foreach($leftidx as $l) {
$diff = $l[2] - $len;
if($diff < 0) {
continue;
}elseif($diff >0){
$arr1[] = $diff;
$arr2[] = $l;
}else{
return $l[1];
}
}
if(empty($arr1)) {
return false;
}else{
$axm = min($arr1);
$axk = array_flip($arr1);
$arr = $arr2[$axk[$axm]];
return $arr[1];
}
}
public function __destruct() {
unset($this->cachelist,$this->cachefile);
}
}
$content = file_get_contents('1.txt');
$st = microtime(true);
//http://222.66.83.226:44405/
$w = new MKCACHE();
//$tt = $w->del('key22');
//$tt = $w->set('key22',md5('ssss'),660);
$tt = $w->get('key11');
echo $tt;
//for($i=0;$i<20;$i++) {
// $k = 'key'.$i;
//$w->set($k,$content);
//}
$et = microtime(true) - $st;
echo printf("%.4f",$et);
2010-03-26 01:15:05