Add (' 1asdf ');
* $obj->getqueuelength ();
* $obj->read (11);
* $obj->get (8); * * Class memcachequeue{public static $client; The Memcache client connects to the public $access; Whether the queue can update private $currentSide; Current rotation of the queue face: A/b private $lastSide; Previous rotation of the queue face: A/b private $sideAHead; A team first value private $sideATail; A team tail value private $sideBHead; B Face Team first value private $sideBTail; B-Team tail value private $currentHead; Current team first value private $currentTail; Current team tail value private $lastHead; The first value of the team is private $lastTail; The tail value of the team is private $expire; Expiration time, seconds, 1~2592000, that is 30 days, 0 for never expire private $sleepTime; Wait for unlock time, microsecond private $queueName; Queue name, unique value private $retryNum; Number of retries, = 10 * Theoretical concurrency number const MAXNUM = 2000; (single) Maximum number of queues, recommended cap 10K const Head_key = ' _lkkqueuehead_ '; Queue First Kye const Tail_key = ' _lkkqueuetail_ '; Queue tail KEY Const Valu_key = ' _lkkqueuevalu_ '; Queue value KEY Const Lock_key = ' _lkkqueuelock_ '; Queue lock KEY Const Side_key = ' _lkkqueueside_ ';
Rotation key/* constructor * @param [Config] array memcache server parameter * @param [queuename] string queue name * @param [expire] string expiration * @return NULL */Public function __construct ($queueName = ', $expire
= ', $config = ') {if (empty ($config)) {self:: $client = memcache_pconnect (' localhost ', 11211); }elseif (Is_array ($config)) {//array (' host ' => ' 127.0.0.1 ', ' Port ' => ' 11211 ') Self:: $client = Memcache_pconnec
T ($config [' Host '], $config [' Port ']);
}elseif (is_string ($config)) {//"127.0.0.1:11211" $tmp = Explode (': ', $config); $conf [' host '] = isset ($tmp [0])?
$tmp [0]: ' 127.0.0.1 '; $conf [' port '] = Isset ($tmp [1])?
$tmp [1]: ' 11211 ';
Self:: $client = Memcache_pconnect ($conf [' Host '], $conf [' Port ']);
if (!self:: $client) return false;
Ignore_user_abort (TRUE);///When the customer disconnects, allow the execution of Set_time_limit (0);//Cancel script execution delay upper bound $this->access = false;
$this->sleeptime = 1000; $expire = (Empty ($expire) && $expire!=0)?
3600: (int) $expire;
$this->expire = $expire;
$this->queuename = $queueName;
$this->retrynum = 10000;
$side = Memcache_add (self:: $client, $queueName. Self::side_key, ' A ', false, $expire);
$this->getheadntail ($queueName);
if (!isset ($this->sideahead) empty ($this->sideahead)) $this->sideahead = 0;
if (!isset ($this->sideatail) empty ($this->sideatail)) $this->sideatail = 0;
if (!isset ($this->sidebhead) empty ($this->sidebhead)) $this->sidebhead = 0; if (!isset ($this->sidebhEAD) Empty ($this->sidebhead)) $this->sidebhead = 0; * * * Get queue value * @param [queuename] string queue name * @return NULL/Private Function Gethea
Dntail ($queueName) {$this->sideahead = (int) memcache_get (self:: $client, $queueName. ' A '. Self::head_key);
$this->sideatail = (int) memcache_get (self:: $client, $queueName. ' A '. Self::tail_key);
$this->sidebhead = (int) memcache_get (self:: $client, $queueName. ' B '. Self::head_key);
$this->sidebtail = (int) memcache_get (self:: $client, $queueName. ' B '. Self::tail_key); * * * Get the current rotation of the queue face * @return string queue face name/Public function getcurrentside () {$currentSi
De = Memcache_get (self:: $client, $this->queuename. Self::side_key);
if ($currentSide = = ' a ') {$this->currentside = ' a ';
$this->lastside = ' B ';
$this->currenthead = $this->sideahead; $this->currenttail = $this->sideatail;
$this->lasthead = $this->sidebhead;
$this->lasttail = $this->sidebtail;
}else{$this->currentside = ' B ';
$this->lastside = ' A ';
$this->currenthead = $this->sidebhead;
$this->currenttail = $this->sidebtail;
$this->lasthead = $this->sideahead;
$this->lasttail = $this->sideatail;
return $this->currentside; * * * Queue plus Lock * @return Boolean/Private Function Getlock () {if ($this->access = = False
{While!memcache_add (self:: $client, $this->queuename. Self::lock_key, 1, False, $this->expire)) {
Usleep ($this->sleeptime);
@ $i + +;
if ($i > $this->retrynum) {//try to wait n times return false;
Break }
}
return $this->access = true;
return false; * * * Queue unlock * @return NULL */Private Function UnLock () {Memcache_delete (self:: $client, $t
His->queuename. Self::lock_key);
$this->access = false;
* * * Add Data * @param the value to store @return Boolean/Public Function add ($data) {
$result = false;
if (! $this->getlock ()) {return $result;
$this->getheadntail ($this->queuename);
$this->getcurrentside ();
if ($this->isfull ()) {$this->unlock ();
return false; } if ($this->currenttail < Self::maxnum) {$value _key = $this->queuename. $this->currentsid E. Self::valu_key.
$this->currenttail;
if (Memcache_add (self:: $client, $value _key, $data, False, $this->expire)) {$this->changetail (); $result =True
}else{//the current queue is full, replace the rotation face $this->unlock ();
$this->changecurrentside ();
return $this->add ($data);
} $this->unlock ();
return $result; * * * Remove data * @param [length] int data lengths * @return Array/Public function get ($length =
0) {if (!is_numeric ($length)) return false;
if (empty ($length)) $length = Self::maxnum * 2;//default Read all if (! $this->getlock ()) return false;
if ($this->isempty ()) {$this->unlock ();
return false;
$keyArray = $this->getkeyarray ($length);
$lastKey = $keyArray [' Lastkey '];
$currentKey = $keyArray [' Currentkey '];
$keys = $keyArray [' Keys '];
$this->changehead ($this->lastside, $lastKey);
$this->changehead ($this->currentside, $currentKey);
$data = @memcache_get (self:: $client, $keys); foreach$keys as $v) {//Remove @memcache_delete after removal (self:: $client, $v, 0);
} $this->unlock ();
return $data; * * * Read data * @param [length] int data @return array/Public function read ($length
=0) {if (!is_numeric ($length)) return false;
if (empty ($length)) $length = Self::maxnum * 2;//reads all $keyArray = $this->getkeyarray ($length) by default;
$data = @memcache_get (self:: $client, $keyArray [' Keys ']);
return $data; * * * Gets the length of the queue a key array * @param [length] int Queue Length * @return array */Private function ge
Tkeyarray ($length) {$result = array (' Keys ' =>array (), ' Lastkey ' =>array (), ' Currentkey ' =>array ());
$this->getheadntail ($this->queuename);
$this->getcurrentside ();
if (empty ($length)) return $result;
First take the key $i = $result [' lastkey '] = 0; for ($i =0; $i < $length; $i + +) {$result[' lastkey ' = $this->lasthead + $i;
if ($result [' Lastkey '] >= $this->lasttail) break; $result [' keys '] = $this->queuename $this->lastside. Self::valu_key.
$result [' Lastkey '];
}//Then take the key $j = $length-$i;
$k = $result [' currentkey '] = 0;
For ($k =0 $k < $j; $k + +) {$result [' currentkey '] = $this->currenthead + $k;
if ($result [' Currentkey '] >= $this->currenttail) break; $result [' keys '] = $this->queuename $this->currentside. Self::valu_key.
$result [' Currentkey '];
return $result; * * * Update the value of the end of the current rotation queue * @return NULL/Private Function Changetail () {$tail _key = $this-&G T;queuename. $this->currentside.
Self::tail_key;
Memcache_add (self:: $client, $tail _key, 0,false, $this->expire);//if not, insert; false; Memcache_increment (self:: $client, $tail _key, 1);//Queue tail +1 $v = MemcachE_get (self:: $client, $tail _key) +1;
Memcache_set (self:: $client, $tail _key, $v, False, $this->expire); * * * UPDATE queue First value * @param [side] string the face to update * @param the value of the first [headvalue] int queue * @retur
N NULL */Private Function Changehead ($side, $headValue) {if ($headValue < 1) return false; $head _key = $this->queuename. $side.
Self::head_key; $tail _key = $this->queuename. $side.
Self::tail_key;
$sideTail = Memcache_get (self:: $client, $tail _key);
if ($headValue < $sideTail) {Memcache_set (self:: $client, $head _key, $headValue +1,false, $this->expire);
}elseif ($headValue >= $sideTail) {$this->resetside ($side); }/* * Reset the queue face, set the head of the queue, team tail value to 0 * @param [side] string to reset the face * @return NULL/Priva
Te function Resetside ($side) {$head _key = $this->queuename. $side. Self::head_key; $tail _key = $this->queuename. $side.
Self::tail_key;
Memcache_set (self:: $client, $head _key,0,false, $this->expire);
Memcache_set (self:: $client, $tail _key,0,false, $this->expire); * * * Change current rotation queue face * @return string/Private Function Changecurrentside () {$currentSide =
Memcache_get (self:: $client, $this->queuename. Self::side_key); if ($currentSide = = ' A ') {Memcache_set (self:: $client, $this->queuename. Self::side_key, ' B ', false, $this->
expire);
$this->currentside = ' B ';
}else{Memcache_set (self:: $client, $this->queuename. Self::side_key, ' A ', false, $this->expire);
$this->currentside = ' A ';
return $this->currentside;
* * * Check whether the current queue is full * @return Boolean/Public Function Isfull () {$result = false; if ($this->sideatail = = Self::maxnum && $this->sidebtail = = self::maxnum) {$resUlt = true;
return $result;
* * * Check whether the current queue is empty * @return Boolean/Public Function IsEmpty () {$result = true;
if ($this->sideatail > 0 $this->sidebtail > 0) {$result = false;
return $result; * * * Get the length of the current queue * The length is theoretical length, some elements are lost due to expiration, the true length is less than or equal to the length * @return int/Public Function getq
Ueuelength () {$this->getheadntail ($this->queuename);
$this->getcurrentside ();
$sideALength = $this->sideatail-$this->sideahead;
$sideBLength = $this->sidebtail-$this->sidebhead;
$result = $sideALength + $sideBLength;
return $result;
* * * Empty current queue data, retain only Head_key, Tail_key, Side_key three KEY * @return Boolean/Public Function clear () {
if (! $this->getlock ()) return false; for ($i =0; $i
queuename. ' A ' Self::valu_key $i, 0); @memcache_delete (self:: $client, $this->queuename. Self::valu_key. $i, 0); } $this->unlock (); $this->resetside (' A '); $this->resetside (' B '); return true; * * * Clears all memcache cache data * @return NULL/Public Function Memflush () {Memcache_flush (self :: $client); } }