php 数组实现简单队列

<?php
class Que {
  //队列最大值
  protected $m = 10;
  //头指针
  protected $h = 0;
  //尾脂针
  protected $t = 0;
  //是否安全
  protected $isSave = false;

  function __construct($isSave = false)
  {
      $this->isSave = $isSave;
      $this->arr = array_fill(0, $this->m, null);
  }

  /**
   * $n >= -100
   * 满返回-999
   * 不满返回入队列后队列元素的数目
   * 
   */

  function in($n){
      if($this->isSave){
        static::lock('in');
      }

      if($n < -100){
        throw new \Exception("数据异常", 1);
      }
      
      if( !$this->canIn() ){
        return -999;
      }


      $this->t = $this->newInOffset();
      $this->arr[$this->t] = $n;

      return $this->getLength();
  }

  /**
   * 空返回-999
   * 非空返回出队列的值
   */
  function out(){
    if($this->isSave){
      static::lock('out');
    }

    if(!$this->canOut()){
        return -999;
    }
    
    $n = $this->arr[$this->h];
    unset($this->arr[$this->h]);
    $this->arr[$this->h] = null;
    $this->h = $this->newOutOffest();
    return $n;
  }

  /**
   *获取数组长度
   */
  function getLength(){
    if($this->isEmpty()) return 0;
    if($this->t < $this->h){
      $l = $this->m - $this->h + $this->t;
    }else{
      $l = $this->t - $this->h;
    }
    return $l + 1;
  }

  /**
   * 判断数组是否为空数组
   */
  function isEmpty(){
    return $this->h == $this->t && is_null($this->arr[$this->h]);
  }

  /**
   *获取入队后的尾指诊偏移量
   */
  function newInOffset(){
      if( $this->isEmpty() ){//是否是空队列
          return $this->t;
      }

      return ($this->t + 1) % $this->m;
  }

  /**
   *判断出队后头指诊的偏移量
   */
  function newOutOffest(){
    if(!$this->isEmpty() && $this->h == $this->t){
        return $this->h;
    }

    return ($this->h + 1) % $this->m;
  }

  /**
   *能否入队
   */
  function canIn(){
    return is_null($this->arr[$this->newInOffset()]);
  }

  /**
   *能否出队
   */
  function canOut(){
    return !is_null($this->arr[$this->h]);
  }

  /**
   *获取队列内容
   */
  function getQueList(){
    return $this->arr;
  }

  /**
   *加锁
   */
  public static function lock($name, $ex = 60)
  {
      if ($res = Redis::setnx($name, '1', 'NX')) {
          Redis::expire($name, $ex);

          register_shutdown_function(function () use ($name) {
              Que::unlock($name);
          });
      } else {
          throw new \Exception('执行中,请稍等');
      }
  }

  /**
   * 解锁
   */
  public static function unlock($name)
  {
      Redis::del($name);
  }
}

/**
$q = new Que;
for($i = 0; $i < 20; $i++){
    $r = $q->in($i);
    var_dump($r);
    if($i % 3 == 0){
      var_dump("out : ".$q->out());
    }
}

for($i = 0; $i < 20; $i++){
  var_dump("out : ".$q->out());
}
**/


此条目发表在php, php函数集, php小程序, 基础分类目录。将固定链接加入收藏夹。