/**
  * Insert items into queue
  * @param PriorityItem[] $items
  * @return mixed
  */
 public function enqueue(array $items)
 {
     //$t0   = the time that the next item currently in the queue will get expired (inf if nothing)
     //$best = the id corresponding to $t0 (0 if nothing)
     //$n    = the number of items in $items array that are going to get expired sooner than $t0
     $first = $this->redis->zrange($this->name, 0, 0, 'WITHSCORES');
     if (count($first)) {
         $t0 = array_values($first)[0];
         $best = array_keys($first)[0];
         $n = 0;
         foreach ($items as $item) {
             if ($item->score < $t0) {
                 $n++;
             }
         }
     } else {
         $t0 = INF;
         $best = 0;
         $n = count($items);
     }
     //zadd $items in the sorted set
     $this->queue->enqueue($items);
     //lpush $n flags into list "{$this->name}:$best" and make sure this list will expire soon
     if ($n) {
         $this->redis->lpush($this->name . ':' . $best, array_fill(0, $n, ''));
         $exp = $t0 != INF ? ceil($t0) : time() + 1;
         $this->redis->expireat($this->name . ':' . $best, $exp);
     }
 }
 public function test_pop_multiple_elements_at_once()
 {
     $now = microtime(true);
     $input = [new PriorityItem('first', $now - 9), new PriorityItem('second', $now - 8), new PriorityItem('third', $now - 10), new PriorityItem('duplicate', $now), new PriorityItem('duplicate', $now)];
     $this->queue->enqueue($input);
     $this->assertCount(5, $this->queue->dequeue(50));
 }