|
- /**
- * Copyright 2020 Huawei Technologies Co., Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- #ifndef DATASET_CYCLIC_ARRAY_H
- #define DATASET_CYCLIC_ARRAY_H
-
- #include <memory>
- #include <algorithm>
- #include <cstring>
- #include <type_traits>
- #include "dataset/core/constants.h"
-
- namespace mindspore {
- namespace dataset {
-
- /// \class CyclicArray "include/cyclic_array.h
- /// \brief This is a container with a contiguous memory layout that pnly keeps N last entries,
- /// when the number of entries exceeds the capacity
- /// Must be preallocated
- template <typename T>
- class CyclicArray {
- public:
- using value_type = T;
- class Iterator {
- // Add operator[] and make fully compliant with random access iterator
- // and add a const iterator
- // add resize(), empty()
- public:
- using iterator_category = std::random_access_iterator_tag;
- using value_type = CyclicArray::value_type;
- using difference_type = std::ptrdiff_t;
- using pointer = CyclicArray::value_type *;
- using reference = CyclicArray::value_type &;
-
- Iterator() = default;
-
- Iterator(dsize_t idx, pointer ptr, dsize_t capacity, dsize_t head)
- : cur_idx_(idx), ptr_(ptr), capacity_(capacity), head_(head) {}
-
- Iterator(const Iterator &rhs) = default;
-
- ~Iterator() = default;
-
- Iterator &operator++() {
- cur_idx_ = (cur_idx_ + 1) % (capacity_ + 1);
- return *this;
- }
-
- Iterator operator++(int) {
- Iterator tmp(*this);
- cur_idx_ = (cur_idx_ + 1) % (capacity_ + 1);
- return tmp;
- }
-
- Iterator &operator--() {
- cur_idx_ = (cur_idx_ + capacity_) % (capacity_ + 1);
- return *this;
- }
-
- Iterator operator--(int) {
- Iterator tmp(*this);
- cur_idx_ = (cur_idx_ + capacity_) % (capacity_ + 1);
- return tmp;
- }
-
- Iterator operator+(dsize_t x) { return Iterator((cur_idx_ + x) % (capacity_ + 1), ptr_, capacity_, head_); }
-
- Iterator operator-(dsize_t x) {
- return Iterator((cur_idx_ + (capacity_ + 1 - x)) % (capacity_ + 1), ptr_, capacity_, head_);
- }
-
- bool operator<(const Iterator &rhs) {
- return (head_ + cur_idx_) % (capacity_ + 1) < (rhs.head_ + rhs.cur_idx_) % (capacity_ + 1);
- }
-
- bool operator>(const Iterator &rhs) {
- return (head_ + cur_idx_) % (capacity_ + 1) > (rhs.head_ + rhs.cur_idx_) % (capacity_ + 1);
- }
-
- bool operator>=(const Iterator &rhs) {
- return (head_ + cur_idx_) % (capacity_ + 1) >= (rhs.head_ + rhs.cur_idx_) % (capacity_ + 1);
- }
-
- bool operator<=(const Iterator &rhs) {
- return (head_ + cur_idx_) % (capacity_ + 1) <= (rhs.head_ + rhs.cur_idx_) % (capacity_ + 1);
- }
-
- difference_type operator-(const Iterator &rhs) {
- return (cur_idx_ - rhs.cur_idx_ + capacity_ + 1) % (capacity_ + 1);
- }
-
- reference operator*() { return ptr_[cur_idx_]; }
-
- pointer operator->() { return &(ptr_[cur_idx_]); }
-
- bool operator==(const Iterator &rhs) { return cur_idx_ == rhs.cur_idx_; }
-
- bool operator!=(const Iterator &rhs) { return cur_idx_ != rhs.cur_idx_; }
-
- private:
- dsize_t cur_idx_;
- pointer ptr_;
- dsize_t capacity_;
- dsize_t head_;
- };
-
- /// \brief Default constructor
- CyclicArray() : buf_(nullptr), head_(0), tail_(0), size_(0), capacity_(0) {}
-
- /// \brief Constructor
- /// \param[in] capacity
- explicit CyclicArray(dsize_t capacity)
- : buf_(std::make_unique<T[]>(capacity + 1)), head_(0), tail_(0), size_(0), capacity_(capacity) {}
-
- CyclicArray(const CyclicArray<T> &rhs)
- : buf_(std::make_unique<T[]>(rhs.capacity_ + 1)),
- head_(rhs.head_),
- tail_(rhs.tail_),
- size_(rhs.size_),
- capacity_(rhs.capacity_) {
- std::copy(rhs.begin(), rhs.end(), begin());
- }
-
- CyclicArray(CyclicArray &&rhs) = default;
-
- ~CyclicArray() = default;
-
- /// \brief Iterator begin()
- Iterator begin() { return Iterator(head_, buf_.get(), capacity_, head_); }
-
- /// \brief Iterator end()
- Iterator end() { return Iterator(tail_, buf_.get(), capacity_, head_); }
-
- // not really const.
- Iterator begin() const { return Iterator(head_, buf_.get(), capacity_, head_); }
-
- Iterator end() const { return Iterator(tail_, buf_.get(), capacity_, head_); }
-
- /// \brief clear the array. Does not deallocate memory, capacity remains the same
- void clear() {
- head_ = 0;
- tail_ = 0;
- size_ = 0;
- }
-
- /// \brief returns current size
- dsize_t size() { return size_; }
-
- /// \brief returns capacity
- dsize_t capacity() { return capacity_; }
-
- /// \brief pushes a value
- /// \param[in] val value
- void push_back(T val) {
- buf_[tail_] = val;
- if (size_ >= capacity_) {
- (tail_ != capacity_) ? tail_++ : tail_ = 0;
- (head_ != capacity_) ? head_++ : head_ = 0;
- } else {
- tail_++;
- size_++;
- }
- }
-
- /// \brief returns const reference to an element of the array
- /// \param[in] idx index of the element
- /// \param[out] const T& reference to an element of the array
- const T &operator[](dsize_t idx) const { return buf_[(head_ + idx) % (capacity_ + 1)]; }
-
- /// \brief returns non-const reference to an element of the array
- /// \param[in] idx index of the element
- /// \param[out] T& reference to an element of the array
- T &operator[](dsize_t idx) { return buf_[(head_ + idx) % (capacity_ + 1)]; }
-
- private:
- std::unique_ptr<T[]> buf_;
- dsize_t head_;
- dsize_t tail_;
- dsize_t size_;
- dsize_t capacity_;
- };
- } // namespace dataset
- } // namespace mindspore
- #endif // DATASET_CYCLIC_ARRAY_H
|