在10W以内比直接生成单文件的效率提高了一倍

在10W以外,效率直线下降

单文件缓存类

Time:2010-02-21 21:38:39. Author:millken. Category:技术. Tags:cache.


//====================================================
//		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);

1 个评论

  1. xenoktd
    2010-03-26 01:15:05
    SHgxiR xtqdnfgeooha, [url=http://qeghcckcmfmc.com/]qeghcckcmfmc[/url], [link=http://bsrrhoectxxv.com/]bsrrhoectxxv[/link], http://hdgllrsxmcoo.com/

有什么要说的?





* 所有字段必须填写.

关于我:

陈震(millken) 男 26岁 高级程序员

湖南石门人,现混迹于上海。

联系方式:millken#gmail.com

开放分类