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.8 % 116 96
Test Date: 2026-08-04 10:52:23 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              : #ifndef CIRCULAR_QUEUE_H
      11              : #define CIRCULAR_QUEUE_H
      12              : 
      13              : #include "queue.h"
      14              : #include <vector>
      15              : namespace Hccl {
      16              : 
      17              : template <typename T> class CircularQueue : public QueueWithSize<T> {
      18              : private:
      19              :     std::vector<T> elems_;
      20              :     size_t         head_;
      21              :     size_t         tail_;
      22              :     size_t         capacity_;
      23              : 
      24              : public:
      25              :     class Iterator : public Queue<T>::Iterator {
      26              :     private:
      27              :         const CircularQueue *queue_{nullptr};
      28              : 
      29              :     protected:
      30         4172 :         void check() override
      31              :         {
      32         4172 :             if (queue_ == nullptr) {
      33            0 :                 THROW<InternalException>(StringFormat("CircularQueue::Iterator queue_ is nullptr"));
      34              :             }
      35         4172 :             if ((this->it_) == (queue_->elems_.begin() + queue_->tail_)) {
      36            9 :                 this->it_ = queue_->elems_.end();
      37            9 :                 return;
      38              :             }
      39              : 
      40         4163 :             if (queue_->size_ == 0) {
      41            0 :                 THROW<InternalException>(StringFormat("CircularQueue::Iterator queue_ is empty"));
      42              :             }
      43         4163 :             size_t now = this->it_ - queue_->elems_.begin();
      44         4163 :             if ((queue_->head_ < queue_->tail_) && !(queue_->head_ <= now && now < queue_->tail_)) {
      45            0 :                 THROW<InternalException>(StringFormat("CircularQueue<T>::Iterator out of range"));
      46              :             }
      47         4163 :             const size_t start_point = 0;
      48         4163 :             if ((queue_->tail_ <= queue_->head_)
      49         4095 :                 && !((start_point <= now && now < queue_->tail_)
      50          487 :                      || (queue_->head_ <= now && now < queue_->capacity_))) {
      51            0 :                 THROW<InternalException>(StringFormat("CircularQueue<T>::Iterator out of range"));
      52              :             }
      53              :         }
      54              : 
      55              :     public:
      56         4253 :         Iterator(typename std::vector<T>::const_iterator it, const CircularQueue *queue) : Queue<T>::Iterator(it), queue_(queue)
      57              :         {
      58         4253 :             if (queue_ == nullptr) {
      59            0 :                 THROW<InternalException>(StringFormat("CircularQueue::Iterator queue_ is nullptr"));
      60              :             }
      61         4253 :             if ((this->it_) == (queue_->elems_.begin() + queue_->tail_)) {
      62         2082 :                 this->it_ = queue_->elems_.end();
      63              :             }
      64         4253 :         }
      65              : 
      66         8351 :         ~Iterator() override = default;
      67              : 
      68            6 :         typename Queue<T>::Iterator &operator++() override
      69              :         {
      70            6 :             (this->it_) = ((this->it_) - queue_->elems_.begin() + 1) % queue_->capacity_ + queue_->elems_.begin();
      71            6 :             check();
      72            6 :             return *this;
      73              :         }
      74              : 
      75         2050 :         typename Queue<T>::Iterator operator++(int) override
      76              :         {
      77         2050 :             Iterator temp = *this;
      78         2050 :             (this->it_)   = ((this->it_) - queue_->elems_.begin() + 1) % queue_->capacity_ + queue_->elems_.begin();
      79         2050 :             check();
      80         4100 :             return temp;
      81         2050 :         }
      82              : 
      83           68 :         typename Queue<T>::Iterator &operator--() override
      84              :         {
      85           68 :             if (this->it_  == queue_->elems_.begin() + queue_->head_) {
      86            0 :                 THROW<InternalException>(StringFormat("CircularQueue<T>::Iterator out of range"));
      87              :             }
      88           68 :             if (this->it_  == this->queue_->elems_.end()) {
      89            0 :                 (this->it_) = queue_->elems_.begin() + queue_->tail_;
      90              :             }
      91           68 :             (this->it_) = ((this->it_) - queue_->elems_.begin() - 1 + queue_->capacity_) % queue_->capacity_
      92          136 :                           + queue_->elems_.begin();
      93           68 :             check();
      94           68 :             return *this;
      95              :         }
      96              : 
      97         2048 :         typename Queue<T>::Iterator operator--(int) override
      98              :         {
      99         2048 :             if (this->it_  == queue_->elems_.begin() + queue_->head_) {
     100            0 :                 THROW<InternalException>(StringFormat("CircularQueue<T>::Iterator out of range"));
     101              :             }
     102         2048 :             Iterator temp = *this;
     103         2048 :             if (this->it_  == this->queue_->elems_.end()) {
     104            1 :                 (this->it_) = queue_->elems_.begin() + queue_->tail_;
     105              :             }
     106         2048 :             (this->it_)   = ((this->it_) - queue_->elems_.begin() - 1 + queue_->capacity_) % queue_->capacity_
     107         4096 :                           + queue_->elems_.begin();
     108         2048 :             check();
     109         4096 :             return temp;
     110         2048 :         }
     111              :     };
     112              : 
     113           38 :     explicit CircularQueue(size_t capacity)
     114           76 :         : elems_(capacity + 1), head_(0), tail_(0), capacity_(capacity + 1)
     115              :     {
     116           38 :         if (capacity_ == 0) {
     117            0 :             THROW<InternalException>(StringFormat("CircularQueue capacity cannot be zero"));
     118              :         }
     119           38 :     }
     120              :     
     121           74 :     ~CircularQueue() override
     122              :     {
     123          110 :         HCCL_INFO("[CircularQueue]Destroy");
     124          112 :     }
     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
     170              :     {
     171        10144 :         return this->size_ == Capacity();
     172              :     }
     173              : 
     174        20250 :     size_t Capacity() const override
     175              :     {
     176        20250 :         return capacity_ - 1;
     177              :     }
     178              : 
     179           13 :     std::shared_ptr<typename Queue<T>::Iterator> Find(std::function<bool(const T &)> cond) override
     180              :     {
     181           13 :         size_t i     = head_;
     182           13 :         size_t count = 0;
     183          166 :         while (count < this->size_) {
     184          163 :             if (cond(elems_[i])) {
     185           10 :                 return std::make_shared<Iterator>(elems_.begin() + i, this);
     186              :             }
     187          153 :             i = (i + 1) % capacity_;
     188          153 :             count++;
     189              :         }
     190            3 :         return std::make_shared<Iterator>(elems_.begin() + tail_, this);
     191              :     }
     192              : 
     193         2151 :     std::shared_ptr<typename Queue<T>::Iterator> Begin() const override
     194              :     {
     195         2151 :         if (this->IsEmpty()) {
     196            6 :             HCCL_WARNING("[CircularQueue][Begin] Queue is empty!");
     197            2 :             return std::make_shared<Iterator>(elems_.begin() + tail_, this);
     198              :         }
     199         2149 :         return std::make_shared<Iterator>(elems_.begin() + head_, this);
     200              :     }
     201              : 
     202           13 :     std::shared_ptr<typename Queue<T>::Iterator> Tail() const override
     203              :     {
     204           13 :         if (this->IsEmpty()) {
     205            3 :             HCCL_WARNING("[CircularQueue][Tail] Queue is empty!");
     206            1 :             return std::make_shared<Iterator>(elems_.begin() + tail_, this);
     207              :         }
     208           12 :         return std::make_shared<Iterator>(elems_.begin() + (tail_ - 1 + capacity_) % capacity_, this);
     209              :     }
     210              : 
     211         2076 :     std::shared_ptr<typename Queue<T>::Iterator> End() const override
     212              :     {
     213         2076 :         return std::make_shared<Iterator>(elems_.begin() + tail_, this);
     214              :     }
     215              : };
     216              : 
     217              : } // namespace Hccl
     218              : #endif // CIRCULAR_QUEUE_H
        

Generated by: LCOV version 2.0-1