LCOV - code coverage report
Current view: top level - legacy/ascend950/framework/dfx/common - circular_queue.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 82.1 % 112 92
Test Date: 2026-08-18 17:47:01 Functions: 90.5 % 21 19

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #ifndef CIRCULAR_QUEUE_H
      12              : #define CIRCULAR_QUEUE_H
      13              : 
      14              : #include "queue.h"
      15              : #include <vector>
      16              : namespace Hccl {
      17              : 
      18              : template <typename T>
      19              : class CircularQueue : public QueueWithSize<T> {
      20              : private:
      21              :     std::vector<T> elems_;
      22              :     size_t head_;
      23              :     size_t tail_;
      24              :     size_t capacity_;
      25              : 
      26              : public:
      27              :     class Iterator : public Queue<T>::Iterator {
      28              :     private:
      29              :         const CircularQueue* queue_{nullptr};
      30              : 
      31              :     protected:
      32         4172 :         void check() override
      33              :         {
      34         4172 :             if (queue_ == nullptr) {
      35            0 :                 THROW<InternalException>(StringFormat("CircularQueue::Iterator queue_ is nullptr"));
      36              :             }
      37         4172 :             if ((this->it_) == (queue_->elems_.begin() + queue_->tail_)) {
      38            9 :                 this->it_ = queue_->elems_.end();
      39            9 :                 return;
      40              :             }
      41              : 
      42         4163 :             if (queue_->size_ == 0) {
      43            0 :                 THROW<InternalException>(StringFormat("CircularQueue::Iterator queue_ is empty"));
      44              :             }
      45         4163 :             size_t now = this->it_ - queue_->elems_.begin();
      46         4163 :             if ((queue_->head_ < queue_->tail_) && !(queue_->head_ <= now && now < queue_->tail_)) {
      47            0 :                 THROW<InternalException>(StringFormat("CircularQueue<T>::Iterator out of range"));
      48              :             }
      49         4163 :             const size_t start_point = 0;
      50         4163 :             if ((queue_->tail_ <= queue_->head_)
      51         4095 :                 && !(
      52         4095 :                     (start_point <= now && now < queue_->tail_) || (queue_->head_ <= now && now < queue_->capacity_))) {
      53            0 :                 THROW<InternalException>(StringFormat("CircularQueue<T>::Iterator out of range"));
      54              :             }
      55              :         }
      56              : 
      57              :     public:
      58         4253 :         Iterator(typename std::vector<T>::const_iterator it, const CircularQueue* queue)
      59              :             : Queue<T>::Iterator(it),
      60         4253 :               queue_(queue)
      61              :         {
      62         4253 :             if (queue_ == nullptr) {
      63            0 :                 THROW<InternalException>(StringFormat("CircularQueue::Iterator queue_ is nullptr"));
      64              :             }
      65         4253 :             if ((this->it_) == (queue_->elems_.begin() + queue_->tail_)) {
      66         2082 :                 this->it_ = queue_->elems_.end();
      67              :             }
      68         4253 :         }
      69              : 
      70         8351 :         ~Iterator() override = default;
      71              : 
      72            6 :         typename Queue<T>::Iterator& operator++() override
      73              :         {
      74            6 :             (this->it_) = ((this->it_) - queue_->elems_.begin() + 1) % queue_->capacity_ + queue_->elems_.begin();
      75            6 :             check();
      76            6 :             return *this;
      77              :         }
      78              : 
      79         2050 :         typename Queue<T>::Iterator operator++(int) override
      80              :         {
      81         2050 :             Iterator temp = *this;
      82         2050 :             (this->it_) = ((this->it_) - queue_->elems_.begin() + 1) % queue_->capacity_ + queue_->elems_.begin();
      83         2050 :             check();
      84         4100 :             return temp;
      85         2050 :         }
      86              : 
      87           68 :         typename Queue<T>::Iterator& operator--() override
      88              :         {
      89           68 :             if (this->it_ == queue_->elems_.begin() + queue_->head_) {
      90            0 :                 THROW<InternalException>(StringFormat("CircularQueue<T>::Iterator out of range"));
      91              :             }
      92           68 :             if (this->it_ == this->queue_->elems_.end()) {
      93            0 :                 (this->it_) = queue_->elems_.begin() + queue_->tail_;
      94              :             }
      95           68 :             (this->it_) = ((this->it_) - queue_->elems_.begin() - 1 + queue_->capacity_) % queue_->capacity_
      96          136 :                           + queue_->elems_.begin();
      97           68 :             check();
      98           68 :             return *this;
      99              :         }
     100              : 
     101         2048 :         typename Queue<T>::Iterator operator--(int) override
     102              :         {
     103         2048 :             if (this->it_ == queue_->elems_.begin() + queue_->head_) {
     104            0 :                 THROW<InternalException>(StringFormat("CircularQueue<T>::Iterator out of range"));
     105              :             }
     106         2048 :             Iterator temp = *this;
     107         2048 :             if (this->it_ == this->queue_->elems_.end()) {
     108            1 :                 (this->it_) = queue_->elems_.begin() + queue_->tail_;
     109              :             }
     110         2048 :             (this->it_) = ((this->it_) - queue_->elems_.begin() - 1 + queue_->capacity_) % queue_->capacity_
     111         4096 :                           + queue_->elems_.begin();
     112         2048 :             check();
     113         4096 :             return temp;
     114         2048 :         }
     115              :     };
     116              : 
     117           78 :     explicit CircularQueue(size_t capacity) : elems_(capacity + 1), head_(0), tail_(0), capacity_(capacity + 1)
     118              :     {
     119           39 :         if (capacity_ == 0) {
     120            0 :             THROW<InternalException>(StringFormat("CircularQueue capacity cannot be zero"));
     121              :         }
     122           39 :     }
     123              : 
     124          187 :     ~CircularQueue() override { HCCL_INFO("[CircularQueue]Destroy"); }
     125              : 
     126           38 :     void Append(T&& value) override
     127              :     {
     128           38 :         if (IsFull()) {
     129            0 :             head_ = (head_ + 1) % capacity_;
     130            0 :             this->size_--;
     131              :         }
     132           38 :         elems_[tail_] = std::move(value);
     133           38 :         tail_ = (tail_ + 1) % capacity_;
     134           38 :         this->size_++;
     135           38 :     }
     136              : 
     137        10106 :     T& GetAndUpdate() override
     138              :     {
     139        10106 :         if (IsFull()) {
     140         7952 :             head_ = (head_ + 1) % capacity_;
     141         7952 :             this->size_--;
     142              :         }
     143        10106 :         auto curTail = tail_;
     144        10106 :         tail_ = (tail_ + 1) % capacity_;
     145        10106 :         this->size_++;
     146        10106 :         return elems_[curTail];
     147              :     }
     148              : 
     149            1 :     void PopFront() override
     150              :     {
     151            1 :         if (this->IsEmpty()) {
     152            0 :             THROW<InternalException>(StringFormat("CircularQueue<T>::PopFront Queue is empty!"));
     153              :         }
     154            1 :         head_ = (head_ + 1) % capacity_;
     155            1 :         this->size_--;
     156            1 :     }
     157              : 
     158            0 :     void Traverse(std::function<void(const T&)> action) override
     159              :     {
     160            0 :         size_t i = head_;
     161            0 :         size_t count = 0;
     162            0 :         while (count < this->size_) {
     163            0 :             action(elems_[i]);
     164            0 :             i = (i + 1) % capacity_;
     165            0 :             count++;
     166              :         }
     167            0 :     }
     168              : 
     169        10144 :     bool IsFull() const override { return this->size_ == Capacity(); }
     170              : 
     171        20250 :     size_t Capacity() const override { return capacity_ - 1; }
     172              : 
     173           13 :     std::shared_ptr<typename Queue<T>::Iterator> Find(std::function<bool(const T&)> cond) override
     174              :     {
     175           13 :         size_t i = head_;
     176           13 :         size_t count = 0;
     177          164 :         while (count < this->size_) {
     178          161 :             if (cond(elems_[i])) {
     179           10 :                 return std::make_shared<Iterator>(elems_.begin() + i, this);
     180              :             }
     181          151 :             i = (i + 1) % capacity_;
     182          151 :             count++;
     183              :         }
     184            3 :         return std::make_shared<Iterator>(elems_.begin() + tail_, this);
     185              :     }
     186              : 
     187         2151 :     std::shared_ptr<typename Queue<T>::Iterator> Begin() const override
     188              :     {
     189         2151 :         if (this->IsEmpty()) {
     190            6 :             HCCL_WARNING("[CircularQueue][Begin] Queue is empty!");
     191            2 :             return std::make_shared<Iterator>(elems_.begin() + tail_, this);
     192              :         }
     193         2149 :         return std::make_shared<Iterator>(elems_.begin() + head_, this);
     194              :     }
     195              : 
     196           13 :     std::shared_ptr<typename Queue<T>::Iterator> Tail() const override
     197              :     {
     198           13 :         if (this->IsEmpty()) {
     199            3 :             HCCL_WARNING("[CircularQueue][Tail] Queue is empty!");
     200            1 :             return std::make_shared<Iterator>(elems_.begin() + tail_, this);
     201              :         }
     202           12 :         return std::make_shared<Iterator>(elems_.begin() + (tail_ - 1 + capacity_) % capacity_, this);
     203              :     }
     204              : 
     205         2076 :     std::shared_ptr<typename Queue<T>::Iterator> End() const override
     206              :     {
     207         2076 :         return std::make_shared<Iterator>(elems_.begin() + tail_, this);
     208              :     }
     209              : };
     210              : 
     211              : } // namespace Hccl
     212              : #endif // CIRCULAR_QUEUE_H
        

Generated by: LCOV version 2.0-1