PHP Memcache class sharing (Memcache queue) _php instance

Source: Internet
Author: User

memcacheQueue.class.php

Copy Code code as follows:

<?php
/**
* PHP Memcache Queue class
* @author lkk/lianq.net
* @version 0.3
* @ Modification Instructions:
* 1. Abandoned the previous AB rotation idea, using a similar array of constructs, rewrite this class.
* 2. Queue default advanced first out, but added reverse read function.
* 3. Thank netizens Foxhunter for their valuable opinions.
* @example:
* $obj = new Memcachequeue (' Duilie ');
* $obj->add (' 1asdf ');
* $obj->getqueuelength ();
* $obj->read (10);
* $obj->get (8);
*/
Class memcachequeue{
public static $client; Memcache Client Connections
Public $access; Whether the queue can be updated
Private $expire; Expiration time, seconds, 1~2592000, i.e. within 30 days
Private $sleepTime; Wait for unlock time, microsecond
Private $queueName; Queue name, unique value
Private $retryNum; Number of retries, = 10 * Theoretical concurrency
Public $currentHead; Current team first value
Public $currentTail; Current team Tail value

Const MAXNUM = 20000; Maximum number of queues, recommended Upper 10K
Const Head_key = ' _lkkqueuehead_ '; Queue Head Kye
Const Tail_key = ' _lkkqueuetail_ '; Queue Tail Key
Const Valu_key = ' _lkkqueuevalu_ '; Queue Value Key
Const Lock_key = ' _lkkqueuelock_ '; Queue Lock key

/**
* Constructor
* @param string $queueName queue name
* @param int $expire Expiration Time
* @param array $config memcache configuration
*
* @return <type>
*/
Public function __construct ($queueName = ', $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);///When customer disconnects, allow continued execution
Set_time_limit (0)//Cancel script execution delay limit

$this->access = false;
$this->sleeptime = 1000;
$expire = Empty ($expire)? 3600:intval ($expire) +1;
$this->expire = $expire;
$this->queuename = $queueName;
$this->retrynum = 1000;

$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 ();
}

/**
* Initialize the queue to set the End-to-end value
*/
Private Function _initsetheadntail () {
The number at the beginning of the current queue
$this->currenthead = Memcache_get (self:: $client, $this->head_key);
if ($this->currenthead = false) $this->currenthead = 0;

numeric value at the end of the current queue
$this->currenttail = Memcache_get (self:: $client, $this->tail_key);
if ($this->currenttail = false) $this->currenttail = 0;
}

/**
* When the element is taken out, change the number of the head of the queue
* @param int $step Step value
*/
Private Function _changehead ($step =1) {
$this->currenthead + + $step;
Memcache_set (self:: $client, $this->head_key, $this->currenthead,false, $this->expire);
}

/**
* Change the value at the end of the queue when adding elements
* @param int $step Step value
* @param bool $reverse is reverse
* @return NULL
*/
Private Function _changetail ($step =1, $reverse =false) {
if (! $reverse) {
$this->currenttail + + $step;
}else{
$this->currenttail-= $step;
}

Memcache_set (self:: $client, $this->tail_key, $this->currenttail,false, $this->expire);
}

/**
* Whether the queue is empty
* @return BOOL
*/
Private Function _isempty () {
Return (BOOL) ($this->currenthead = = $this->currenttail);
}

/**
* Whether the queue is full
* @return BOOL
*/
Private Function _isfull () {
$len = $this->currenttail-$this->currenthead;
Return (bool) ($len = = Self::maxnum);
}

/**
* Queue Lock
*/
Private Function _getlock () {
if ($this->access = = False) {
while (!memcache_add (self:: $client, $this->lock_key, 1, False, $this->expire)) {
Usleep ($this->sleeptime);
@ $i + +;
if ($i > $this->retrynum) {//try to wait n times
return false;
Break
}
}

$this->_initsetheadntail ();
return $this->access = true;
}

return $this->access;
}

/**
* Queue unlock
*/
Private Function _unlock () {
Memcache_delete (self:: $client, $this->lock_key, 0);
$this->access = false;
}

/**
* Get the length of the current queue
* This length is theoretical length, some elements are lost due to expiration, true length <= that length
* @return int
*/
Public Function Getqueuelength () {
$this->_initsetheadntail ();
Return Intval ($this->currenttail-$this->currenthead);
}

/**
* Add Queue data
* @param void $data The data to be added
* @return BOOL
*/
Public function Add ($data) {
if (! $this->_getlock ()) return false;

if ($this->_isfull ()) {
$this->_unlock ();
return false;
}

$value _key = $this->queuename. Self::valu_key. Strval ($this->currenttail + 1);
$result = Memcache_set (self:: $client, $value _key, $data, memcache_compressed, $this->expire);
if ($result) {
$this->_changetail ();
}

$this->_unlock ();
return $result;
}

/**
* Read queue data
* @param int $length The length to be read (negative read used in reverse)
* @return Array
*/
Public function read ($length =0) {
if (!is_numeric ($length)) return false;
$this->_initsetheadntail ();

if ($this->_isempty ()) {
return false;
}

if (empty ($length)) $length = self::maxnum;//Default All
$KEYARR = Array ();
if ($length >0) {//forward read (from Queue head to queue end)
$tmpMin = $this->currenthead;
$tmpMax = $tmpMin + $length;
for ($i = $tmpMin; $i <= $tmpMax; $i + +) {
$KEYARR [] = $this->queuename. Self::valu_key. $i;
}
}else{//backward read (from queue end to queue head)
$tmpMax = $this->currenttail;
$tmpMin = $tmpMax + $length;
for ($i = $tmpMax; $i > $tmpMin; $i-) {
$KEYARR [] = $this->queuename. Self::valu_key. $i;
}
}

$result = @memcache_get (self:: $client, $KEYARR);

return $result;
}

/**
* Remove Queue data
* @param the length of the int $length to be taken out (negative reading is used)
* @return Array
*/
Public function Get ($length =0) {
if (!is_numeric ($length)) return false;
if (! $this->_getlock ()) return false;

if ($this->_isempty ()) {
$this->_unlock ();
return false;
}

if (empty ($length)) $length = self::maxnum;//Default All
$length = Intval ($length);
$KEYARR = Array ();
if ($length >0) {//forward read (from Queue head to queue end)
$tmpMin = $this->currenthead;
$tmpMax = $tmpMin + $length;
for ($i = $tmpMin; $i <= $tmpMax; $i + +) {
$KEYARR [] = $this->queuename. Self::valu_key. $i;
}
$this->_changehead ($length);
}else{//backward read (from queue end to queue head)
$tmpMax = $this->currenttail;
$tmpMin = $tmpMax + $length;
for ($i = $tmpMax; $i > $tmpMin; $i-) {
$KEYARR [] = $this->queuename. Self::valu_key. $i;
}
$this->_changetail (ABS ($length), true);
}
$result = @memcache_get (self:: $client, $KEYARR);

foreach ($keyArr as $v) {//Removed after removal
@memcache_delete (self:: $client, $v, 0);
}

$this->_unlock ();

return $result;
}

/**
* Empty Queue
*/
Public Function Clear () {
if (! $this->_getlock ()) return false;

if ($this->_isempty ()) {
$this->_unlock ();
return false;
}

$tmpMin = $this->currenthead--;
$tmpMax = $this->currenttail++;

for ($i = $tmpMin; $i <= $tmpMax; $i + +) {
$tmpKey = $this->queuename. Self::valu_key. $i;
@memcache_delete (self:: $client, $tmpKey, 0);
}

$this->currenttail = $this->currenthead = 0;
Memcache_set (self:: $client, $this->head_key, $this->currenthead,false, $this->expire);
Memcache_set (self:: $client, $this->tail_key, $this->currenttail,false, $this->expire);

$this->_unlock ();
}

/*
* Clear all Memcache cache data
*/
Public Function Memflush () {
Memcache_flush (self:: $client);
}

}//end class

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.