Php memcache queue class-PHP source code

Source: Internet
Author: User
Php memcache queue class

MemcacheQueue. class. php
 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/Bprivate $ lastSide; // The queue surface of the previous rotation: A/Bprivate $ 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 current team's first value is private $ currentTail; // The current team's end value is private $ lastHead; // The first value of the previous team is p Rivate $ lastTail; // 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 constMAXNUM = 2000; // (single-sided) maximum number of queues. The maximum value is 10 kconsthead_key = '_ lkqueuehead _'; // queue header kyeconstTAIL_KEY = '_ lkqueuetail _'; // queue end keyconstVALU_KEY = '_ prop _'; // queue value keyconstLOCK_KEY = '_ lkqueuelock _'; // queue lock keyconstSIDE_KEY = '_ lkqueueside _'; // rotation surface key/** constructor * @ param [config] arraymemcache server parameter * @ par Am [queueName] string queue name * @ param [expire] string expiration time * @ returnNULL */public function _ construct ($ queueName = '', $ expire = '', $ config = '') {if (empty ($ config) {self: $ client = memcache_pconnect ('localhost', 11211);} elseif (is_array ($ config )) {// array ('host' => '2017. 0.0.1 ', 'port' => '000000') self: $ client = memcache_pconnect ($ config ['host'], $ config ['port']);} elseif (is_string ($ config) {// "127.0.0.1: 11211" $ tmp = ex Plode (':', $ 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 the queue * @ param [queueName] string queue name * @ returnNULL */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: $ client, $ queue Name. 'B '. self: HEAD_KEY); $ this-> sideBTail = (int) memcache_get (self: $ client, $ queueName. 'B '. self: TAIL_KEY);}/** get the current rotating queue surface * @ returnstring 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-> currentTail = $ this-> side ATail; $ 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 () {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 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 * @ returnbool Ean */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 and the rotation is changed Face $ this-> unLock (); $ this-> changeCurrentSide (); return $ this-> add ($ data) ;}$ this-> unLock (); return $ result;}/** retrieve data * @ param [length] int data length * @ returnarray */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 @ memcache_delete (self: $ Client, $ v, 0) ;}$ this-> unLock (); return $ data ;} /** read data * @ param [length] int data length * @ returnarray */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 * @ param [length] int queue length * @ returnarray */private function getKeyArray ($ length) {$ result = array ('keys' => array (), 'lastkey' => array (), 'currentkey' => array ()); $ this-> getHeadNTail ($ this-> queue Name); $ 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 * @ returnNULL */private function changeTail () {$ tail_key = $ this-> queueName. $ this-> currentSide. self: TAIL_KEY; memcache_add (self: $ client, $ tail_key, 0, false, $ this-> expir E); // Insert if no; false if Yes; // memcache_increment (self: $ client, $ tail_key, 1 ); // end of the queue + 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 * @ returnNULL */private function changeHead ($ side, $ headValue) {if ($ headValue <1) return false; $ head_key = $ this-> queueName. $ side. self: HEAD_K EY; $ 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, set the frontend and backend of the queue to 0 * @ param [side] string to reset the surface * @ returnNULL */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 * @ returnstring */private function changeCurrentSide () {$ currentSide = memcache_get (self: $ client, $ this-> queueName. self: SIDE_KEY); if ($ currentSide = 'a') {memcache_set (self: $ client, $ t His-> 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 * @ returnboolean */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 * @ returnboolean */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. some elements are lost due to expiration failure. the actual length is less than or equal to this length * @ returnint */public function getQueueLength () {$ this-> getHeadNTail ($ this-> queueName); $ this-> getCurrentSide (); $ sideALength = $ this-> sideATail-$ this-> sideAHead; $ sideBLength = $ thi S-> sideBTail-$ this-> sideBHead; $ result = $ sideALength + $ sideBLength; return $ result;}/** clear the data in the current queue, only the HEAD_KEY, TAIL_KEY, and SIDE_KEY Keys * @ returnboolean */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 * @ returnNULL */public function memFlush () {memcache_flush (self: $ client );}}
 

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.