This article illustrates the Memcache loop queue class implemented by PHP. Share to everyone for your reference. Specifically as follows:
This paper introduces the Memcache loop queue class implemented by PHP. I have not learned the data structure, because the business needs, so just bite the bullet to simulate! Refer to the PHP memcache queue code. In order for the queue to be available at any time, and not subject to a transboundary risk of int length (the single chain takes head to be added without dealing with the possibility of crossing over), so simply rewrite it into a ring queue. There may be bugs, forget to forgive!
<?php/** * php memcache Ring Queue class * Original Author Lkk/lianq.net * Modify Foxhunter * The pop and push in the queue that are reserved only for business needs, the modified expiration time is 0 that is permanent */class MQ
Ueue {public static $client; Private $expire; Expiration time, seconds, 1~2592000, that is, 30 days private $sleepTime; Wait for unlock time, microsecond private $queueName; Queue name, unique value private $retryNum; Number of attempts private $MAXNUM; Maximum queue capacity private $canRewrite; Whether you can override the switch, the full content from the beginning of the head to overwrite the original data private $HEAD; The next step to enter the position of the pointer private $TAIL; The next step to enter the position of the pointer private $LEN; Queue existing length Const Lock_key = ' _fox_mq_lock_ '; Lock storage labeled Const LENGTH_KEY = ' _fox_mq_length_ '; Queue current Length storage indicator const VALU_KEY = ' _fox_mq_val_ '; Queue key value Storage Indicator Const HEAD_KEY = ' _fox_mq_head_ '; The queue head pointer position is labeled const Tail_key = ' _fox_mq_tail_ '; Queue tail pointer Position/* constructor * for the same $queuename, the instantiation must guarantee that the constructor's parameter values are the same, otherwise pops and push will guide the queue order confusion/Public function __construct ($q Ueuename = ', $maxqueue = 1, $canRewrite = false, $expire = 0, $config = ') {if (empty ($config)) {self:: $client
= Memcache_pconnect (' 127.0.0.1 ', 11211); } elseif (Is_array ($config)) {//arrAy (' host ' => ' 127.0.0.1 ', ' Port ' => ' 11211 ') Self:: $client = Memcache_pconnect ($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); Allow Set_time_limit (0) to continue when the customer disconnects;
Cancels script execution delay upper bound $this->access = false;
$this->sleeptime = 1000; $expire = (Empty ($expire))?
0: (int) $expire + 1;
$this->expire = $expire;
$this->queuename = $queueName;
$this->retrynum = 20000; $this->maxnum = $maxqueue!= null?
$maxqueue: 1;
$this->canrewrite = $canRewrite;
$this->getheadandtail ();
if (!isset ($this->head) | | | empty ($this->head)) $this->head = 0; if (!isset ($this->tail) | | | empty ($this->tail)) $this->tail =0;
if (!isset ($this->len) | | | empty ($this->len)) $this->len = 0; //Get the end and end of the queue information and length private function Getheadandtail () {$this->head = (int) memcache_get (self:: $client, $this->qu Euename.
Self::head_key);
$this->tail = (int) memcache_get (self:: $client, $this->queuename. Self::tail_key);
$this->len = (int) memcache_get (self:: $client, $this->queuename. Self::length_key);
///Use Memcache_add atomicity to lock Private function lock () {if ($this->access = = False) {$i = 0; 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; //Update head pointer to next position private function Incrhead () {//$this->getheadandtail ();//Get the latest pointer information, because this method body is called in the lock, the method is called within its lock. Bank Note $this->head++; The head pointer moves down if ($this->head >= $this->maxnum) {$this->head = 0;//boundary value correction}; $this->len--;
The head movement is triggered by POPs, so the amount of if ($this->len < 0) {$this->len = 0;//boundary value correction} is equal to the quantity reduction; Memcache_set (self:: $client, $this->queuename. Self::head_key, $this->head, False, $this->expire); Update Memcache_set (self:: $client, $this->queuename. Self::length_key, $this->len, False, $this->expire); UPDATE}//update tail pointer, point to next position private function Incrtail () {//$this->getheadandtail ();//Get the latest pointer information, because this method body is called in the lock, its lock has been called This method, the bank notes $this->tail++;
The tail pointer moves down if ($this->tail >= $this->maxnum) {$this->tail = 0;//boundary value correction}; $this->len++;
The head movement is triggered by a push, so it amounts to an increase of if ($this->len >= $this->maxnum) {$this->len = $this->maxnum;//boundary value length correction
}
; Memcache_set (self:: $client, $this->queuename. Self::tail_key, $this->tail, False, $this->expire); Update Memcache_set (self:: $client, $this->queuename. Self::length_key, $this->len, False, $this->expire);
UPDATE}//unlock Private Function UnLock () {Memcache_delete (self:: $client, $this->queuename. Self::lock_key);
$this->access = false; //To determine if the full queue public Function Isfull () {//external direct call time because there is no lock so the value here is an approximate value, not very accurate, but the internal call because there is lock in front, so the trusted if ($this->canrew
rite) return false; return $this->len = = $this->maxnum?
True:false; }//Determine if the null public function IsEmpty () {//external direct call time because there is no lock so the value here is an approximate value, not very accurate, but the internal call because there is lock in front, so the trusted return $this->len = = 0?
True:false;
Public Function Getlen () {//external direct Call the value here is an approximate value because there is no lock, but the internal call is trusted return $this->len;
* * * Push value * @param mixed value * @return BOOL/Public function push ($data = ') {$result = false;
if (empty ($data)) return $result;
if (! $this->lock ()) {return $result; } $this->getheadandtail ();
Get the latest pointer information if ($this->isfull ()) {//full concept only if not overridden $this->unlock ();
return false; if (Memcache_set self:: $client, $this->QueueName. Self::valu_key. $this->tail, $data, memcache_compressed, $this->expire)) {//when pushed, the tail and head are found to coincide (at this point the pointer has not moved), and the right still has not been read by the header data, Then move the head pointer to avoid trailing pointers across head if ($this->tail = = $this->head && $this->len >= 1) {$this->incrhead
(); } $this->incrtail ();
Move tail pointer $result = TRUE;
} $this->unlock ();
return $result; * * * Pop a value * @param [length] int Queue Length * @return Array */Public function pop ($length = 0) {if!is_numeri
C ($length)) return false;
if (! $this->lock ()) return false;
$this->getheadandtail (); if (empty ($length)) $length = $this->len;
The default reads all if ($this->isempty ()) {$this->unlock ();
return false;
The///Get length is out of queue length to be corrected if ($length > $this->len) $length = $this->len;
$data = $this->popkeyarray ($length);
$this->unlock ();
return $data;
* * * Pop a segment length value * @param [length] int Queue Length * @return Array/Private function Popkeyarray ($length){$result = array ();
if (empty ($length)) return $result; for ($k = 0; $k < $length; $k + +) {$result [] = @memcache_get (self:: $client, $this->queuename Self::valu_key $
This->head);
@memcache_delete (self:: $client, $this->queuename self::valu_key. $this->head, 0); When the value is fetched, the head and tail are found to coincide (at which point the pointer has not moved) and there is no data on the right, that is, the last data in the queue is completely emptied, at which point the pointer stays local and the queue length becomes 0 if ($this->tail = = $this->head &
& $this->len <= 1) {$this->len = 0; Memcache_set (self:: $client, $this->queuename. Self::length_key, $this->len, False, $this->expire);
Update break;
else {$this->incrhead (),/////////////////////////////////////////// * * * Reset Queue * * @return NULL/Private Function reset ($all = False) {if ($all) {Memcache_delete (self:: $CL Ient, $this->queuename.
Self::head_key, 0);
Memcache_delete (self:: $client, $this->queuename. Self::tail_key, 0); Memcache_delete (self:: $client, $this; QueueName.
Self::length_key, 0);
else {$this->head = $this->tail = $this->len = 0;
Memcache_set (self:: $client, $this->queuename. Self::head_key, 0, False, $this->expire);
Memcache_set (self:: $client, $this->queuename. Self::tail_key, 0, False, $this->expire);
Memcache_set (self:: $client, $this->queuename. Self::length_key, 0, False, $this->expire);
} * * Clears all memcache cache data * @return NULL/Public Function Memflush () {Memcache_flush (self:: $client);
The public function clear ($all = False) {if (! $this->lock ()) is return false;
$this->getheadandtail ();
$Head = $this->head;
$Length = $this->len;
$curr = 0;
for ($i = 0; $i < $Length; $i + +) {$curr = $this-> $Head + $i;
if ($curr >= $this->maxnum) {$this->head = $curr = 0;
@memcache_delete (self:: $client, $this->queuename. Self::valu_key $curr, 0);
} $this->unlock ();
$this->reset ($all);
return true;
}}
I hope this article will help you with your PHP programming.