用memcache实现简单的先进先出队列

来源:互联网 发布:医疗器械注册 软件 编辑:程序博客网 时间:2024/06/05 09:58

本代码根据前辈的代码简化修改而成

class memcacheQueue{public $client;//memcache客户端连接private $expire;//过期时间,秒,1~2592000,即30天内private $sleepTime;//等待解锁时间,微秒private $queueName;//队列名称,唯一值const HEAD_KEY='_QueueHead_';//队列首keyconst TAIL_KEY='_QueueTail_';//队列尾keyconst VALUE_KEY='_QueueValue_';//队列值keyconst LOCK_KEY='_QueueLock_';//队列锁key/** *构造函数 *@param string $queueName 队列名称 *@param int $expire 过期时间 *@param $client memcache连接对象 */ public function __construct($queueName='',$memcacheClient){        $this->client=$memcacheClient;//新浪云memcache初始化$expire=empty($expire)?3600*24:intval($expire)+1;$this->expire=$expire;$this->queueName=$queueName;$this->sleepTime=100;$this->head_key = $this->queueName . self::HEAD_KEY;$this->tail_key = $this->queueName . self::TAIL_KEY;$this->lock_key = $this->queueName . self::LOCK_KEY;$this->_initSetHeadNTail(); } private function _initSetHeadNTail(){//当前队列首的数值$currentHead=memcache_get($this->client,$this->head_key);if($currentHead===false) memcache_set($this->client,$this->head_key,0);//初始话队尾数值$currentTail=memcache_get($this->client,$this->tail_key);if($currentTail===false) memcache_set($this->client,$this->tail_key,0); }  /**     * 当添加元素时,改变队列尾的数值  * @param int $step 步长值     * @param bool $reverse 是否反向     * @return null     */ private function _changeTail($step=1, $reverse =false){ $currentTail=memcache_get($this->client,$this->tail_key);  if(!$reverse){   $currentTail += $step;  }else{   $currentTail -= $step;  }  memcache_set($this->client, $this.queueName.$this->tail_key,$currentTail,false); }  /**     * 队列是否为空     * @return bool     */ public function _isEmpty(){     $currentHead=memcache_get($this->client,$this->head_key);     $currentTail=memcache_get($this->client,$this->tail_key);  return (bool)($currentHead === $currentTail); } private function _getLock(){while(!memcache_add($this->client,$this->lock_key,1,false,5)){sleep($this->sleepTime);@$i++;if($i>5){return false;break;}}return true; } private function _unLock(){  memcache_delete($this->client, $this->lock_key, 0); } /**     * 获取当前队列的长度     * 该长度为理论长度,某些元素由于过期失效而丢失,真实长度<=该长度     * @return int     */ public function getQueueLength(){  $this->_initSetHeadNTail();  $currentHead=memcache_get($this->client,$this->head_key);  $currentTail=memcache_get($this->client,$this->tail_key);  return intval($currentTail - $currentHead); }  /**     * 添加队列数据     * @param void $data 要添加的数据     * @return bool     */ public function add($data){  if(!$this->_getLock()) return false;  $currentTail=memcache_get($this->client,$this->tail_key);  $value_key = $this->queueName . self::VALUE_KEY . strval($currentTail +1);  $result[0] = memcache_set($this->client, $value_key, $data, 0, $this->expire);  if($result[0]){   memcache_set($this->client,$this->tail_key,$currentTail+1);   $result[1]=$value_key;  }  $this->_unLock();  return $result; }  /**     * 取出队列数据     * @param int $length 要取出的长度(反向读取使用负数)     * @return array     */ public function get(){  if(!$this->_getLock()) return false;      if($this->_isEmpty()){         $this->_unLock();   return false;  }    $currentHead=memcache_get($this->client,$this->head_key);  $currentHead+=1;  memcache_set($this->client,$this->head_key,$currentHead);  $this->_unLock();//设置完队列长度后就可以解锁了  $valueKey=$this->queueName.self::VALUE_KEY.$currentHead;  $result=memcache_get($this->client,$valueKey);   memcache_delete($this->client, $valueKey, 0);          return $result; } /** *重置队列值过期时间 */ public function resetValueExpireTime($key,$value){memcache_set($this->client,$key,$value,0,$this->expire); }/*  * 清除所有memcache缓存数据  */ public function memFlush(){  memcache_flush($this->client); } public function getQueueName(){return $this->queueName; } public function getExpire(){return $this->expire;  }}


0 0
原创粉丝点击