Php self-implemented memcached queue class _ PHP Tutorial

Source: Internet
Author: User
Php implements the memcached queue class by itself. Php implements the memcached queue class add (1 asdf); * $ obj-getQueueLength (); * $ obj-read (11); * $ obj-get (8 ); * classmemcacheQueue {publicstatic $ client; the memcache client connects to the pu php and implements the memcached queue class.

 Add ('1asdf '); * $ obj-> getQueueLength (); * $ obj-> read (11); * $ obj-> get (8 ); */class memcacheQueue {public static $ client; // The memcache client connects to public $ access; // whether the queue can update private $ currentSide; // the current rotating queue plane: a/B private $ lastSide; // The queue surface of the previous rotation: A/B private $ sideAHead; // The first line value of A is private $ sideATail; // the end value of Team A is private $ sideBHead; // The first value of Team B is private $ sideBTail; // The end value of Team B is private $ currentHead; // The first value of the current team is private $ currentTail; // The Current Private $ lastHead; // first private $ lastTail; // last private $ expire; // expiration time, seconds, 1 ~ 2592000, that is, within 30 days; 0 is private $ sleepTime that never expires; // waiting for unlock time, microsecond private $ queueName; // queue name, unique value private $ retryNum; // Number of retries, = 10 * theoretical concurrency const MAXNUM = 2000; // (single-sided) maximum number of queues. we recommend that you set the maximum value to 10 K const HEAD_KEY = '_ lkqueuehead _'; // queue header kye const TAIL_KEY = '_ lkqueuetail _'; // queue end key const VALU_KEY = '_ lkqueuevalu _'; // queue value key const LOCK_KEY = '_ lkqueuelock _'; // queue lock key const SIDE_KEY = '_ lkqueueside _'; // rotation key/** constructor * @ para M [config] array memcache server parameter * @ param [queueName] string queue name * @ param [expire] string expiration time * @ 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' => '000000') self: $ client = memcache_pconnect ($ config ['host'], $ config ['port']);} elsei F (is_string ($ config) {// "127.0.0.1: 11211" $ tmp = explode (':', $ config ); $ conf ['host'] = isset ($ tmp [0])? $ Tmp [0]: '192. 0.0.1 '; $ conf ['port'] = isset ($ tmp [1])? $ Tmp [1]: '000000'; self: $ client = memcache_pconnect ($ conf ['host'], $ conf ['port']);} if (! Self: $ client) return false; ignore_user_abort (TRUE); // when the customer disconnects, set_time_limit (0) can be continued ); // cancel the maximum latency of script execution $ 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 the first and end values of a queue * @ param [queueName] string queue name * @ return NULL */private function getHeadNTail ($ 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: $ clie Nt, $ queueName. 'B '. self: HEAD_KEY); $ this-> sideBTail = (int) memcache_get (self: $ client, $ queueName. 'B '. self: TAIL_KEY);}/** get the current rotating queue surface * @ return string queue surface name */public function getCurrentSide () {$ currentSide = memcache_get (self :: $ client, $ this-> queueName. self: SIDE_KEY); if ($ currentSide = 'a') {$ this-> currentSide = 'a'; $ this-> lastSide = 'B '; $ this-> currentHead = $ this-> sideAHead; $ this-> c UrrentTail = $ 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 lock * @ return boolean */private function getLock () {I F ($ 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 for N times return false; break;} return $ this-> access = true;} return false ;} /** unLock the queue * @ return NULL */private function unLock () {memcache_delete (self: $ client, $ this-> queueName. self: LOCK_KEY); $ this-> access = false;}/** add data * @ param [data] Value to be stored * @ 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-> currentSide. 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. change the rotation plane $ this-> unLock (); $ this-> changeCurrentSide (); return $ this-> add ($ data );} $ this-> unLock (); return $ result ;} /** retrieve data * @ param [length] int data length * @ return array */public function get ($ length = 0) {if (! Is_numeric ($ length) return false; if (empty ($ length) $ length = self: MAXNUM * 2; // 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) {// delete @ me after removal Mcache_delete (self: $ client, $ v, 0) ;}$ this-> unLock (); return $ data ;} /** read data * @ param [length] int data length * @ return array */public function read ($ length = 0) {if (! Is_numeric ($ length) return false; if (empty ($ length) $ length = self: MAXNUM * 2; // read all $ keyArray = $ this-> getKeyArray ($ length) by default; $ data = @ memcache_get (self: $ client, $ keyArray ['keys']); return $ data;}/** get the key array of a queue segment length * @ param [length] int queue length * @ return array */private function getKeyArray ($ length) {$ result = array ('keys' => array (), 'lastkey' => array (), 'currentkey' => array (); $ this-> getHeadNTa Il ($ this-> queueName); $ this-> getCurrentSide (); if (empty ($ length) return $ result; // first take the previous 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'];} // Obtain the current 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 at the end of the current rotation plane queue * @ return NULL */private function changeTail () {$ tail_key = $ this-> queueName. $ this-> currentSide. self: TAIL_KEY; memcache_add (self: $ c Lient, $ tail_key, 0, false, $ this-> expire); // If not, insert; if yes, 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 The first value of the queue * @ param [side] string the surface to be updated * @ param [headValue] int the first value of the queue * @ return NULL */private function changeHead ($ side, $ headValue) {if ($ headValue <1) return fal Se; $ 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 surface to set the frontend and backend values of the queue to 0 * @ param [side] string to be reset * @ return NULL */Private 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 the current rotating queue surface * @ return string */private function changeCurrentSide () {$ currentSide = memcache_get (self :: $ client, $ this-> queue Name. 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 ($ t His-> 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 * this length is the theoretical length, and some elements are lost due to expiration failure, the actual length is less than or equal to this length * @ return int */public function getQueueLength () {$ this-> getHeadNTail ($ thi S-> queueName); $ this-> getCurrentSide (); $ sideALength = $ this-> sideATail-$ this-> sideAHead; $ sideBLength = $ this-> sideBTail-$ this-> sideBHead; $ result = $ sideALength + $ sideBLength; return $ result;}/** Clear data in the current queue, only the HEAD_KEY, TAIL_KEY, and SIDE_KEY Keys * @ 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. 'B '. self: VALU_KEY. $ I, 0) ;}$ this-> unLock (); $ this-> resetSide ('A'); $ this-> resetSide ('B '); return true;}/** Clear all memcache cached data * @ return NULL */public function memFlush () {memcache_flush (self ::$ client );}}
 


Revoke add (1 asdf); * $ obj-getQueueLength (); * $ obj-read (11); * $ obj-get (8 ); */class memcacheQueue {public static $ client; // connect the memcache client to pu...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.