1*89c4ff92SAndroid Build Coastguard Worker // 2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2021 Arm Ltd and Contributors. All rights reserved. 3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT 4*89c4ff92SAndroid Build Coastguard Worker // 5*89c4ff92SAndroid Build Coastguard Worker 6*89c4ff92SAndroid Build Coastguard Worker #pragma once 7*89c4ff92SAndroid Build Coastguard Worker 8*89c4ff92SAndroid Build Coastguard Worker template<class T> 9*89c4ff92SAndroid Build Coastguard Worker class SlidingWindow 10*89c4ff92SAndroid Build Coastguard Worker { 11*89c4ff92SAndroid Build Coastguard Worker protected: 12*89c4ff92SAndroid Build Coastguard Worker T* m_start = nullptr; 13*89c4ff92SAndroid Build Coastguard Worker size_t m_dataSize = 0; 14*89c4ff92SAndroid Build Coastguard Worker size_t m_size = 0; 15*89c4ff92SAndroid Build Coastguard Worker size_t m_stride = 0; 16*89c4ff92SAndroid Build Coastguard Worker size_t m_count = 0; 17*89c4ff92SAndroid Build Coastguard Worker public: 18*89c4ff92SAndroid Build Coastguard Worker 19*89c4ff92SAndroid Build Coastguard Worker /** 20*89c4ff92SAndroid Build Coastguard Worker * Creates the window slider through the given data. 21*89c4ff92SAndroid Build Coastguard Worker * 22*89c4ff92SAndroid Build Coastguard Worker * @param data pointer to the data to slide through. 23*89c4ff92SAndroid Build Coastguard Worker * @param dataSize size in T type elements wise. 24*89c4ff92SAndroid Build Coastguard Worker * @param windowSize sliding window size in T type wise elements. 25*89c4ff92SAndroid Build Coastguard Worker * @param stride stride size in T type wise elements. 26*89c4ff92SAndroid Build Coastguard Worker */ SlidingWindow(T * data,size_t dataSize,size_t windowSize,size_t stride)27*89c4ff92SAndroid Build Coastguard Worker SlidingWindow(T* data, size_t dataSize, 28*89c4ff92SAndroid Build Coastguard Worker size_t windowSize, size_t stride) 29*89c4ff92SAndroid Build Coastguard Worker { 30*89c4ff92SAndroid Build Coastguard Worker m_start = data; 31*89c4ff92SAndroid Build Coastguard Worker m_dataSize = dataSize; 32*89c4ff92SAndroid Build Coastguard Worker m_size = windowSize; 33*89c4ff92SAndroid Build Coastguard Worker m_stride = stride; 34*89c4ff92SAndroid Build Coastguard Worker } 35*89c4ff92SAndroid Build Coastguard Worker 36*89c4ff92SAndroid Build Coastguard Worker SlidingWindow() = default; 37*89c4ff92SAndroid Build Coastguard Worker 38*89c4ff92SAndroid Build Coastguard Worker ~SlidingWindow() = default; 39*89c4ff92SAndroid Build Coastguard Worker 40*89c4ff92SAndroid Build Coastguard Worker /** 41*89c4ff92SAndroid Build Coastguard Worker * Get the next data window. 42*89c4ff92SAndroid Build Coastguard Worker * @return pointer to the next window, if next window is not available nullptr is returned. 43*89c4ff92SAndroid Build Coastguard Worker */ Next()44*89c4ff92SAndroid Build Coastguard Worker virtual T* Next() 45*89c4ff92SAndroid Build Coastguard Worker { 46*89c4ff92SAndroid Build Coastguard Worker if (HasNext()) 47*89c4ff92SAndroid Build Coastguard Worker { 48*89c4ff92SAndroid Build Coastguard Worker m_count++; 49*89c4ff92SAndroid Build Coastguard Worker return m_start + Index() * m_stride; 50*89c4ff92SAndroid Build Coastguard Worker } 51*89c4ff92SAndroid Build Coastguard Worker else 52*89c4ff92SAndroid Build Coastguard Worker { 53*89c4ff92SAndroid Build Coastguard Worker return nullptr; 54*89c4ff92SAndroid Build Coastguard Worker } 55*89c4ff92SAndroid Build Coastguard Worker } 56*89c4ff92SAndroid Build Coastguard Worker 57*89c4ff92SAndroid Build Coastguard Worker /** 58*89c4ff92SAndroid Build Coastguard Worker * Checks if the next data portion is available. 59*89c4ff92SAndroid Build Coastguard Worker * @return true if next data portion is available 60*89c4ff92SAndroid Build Coastguard Worker */ HasNext()61*89c4ff92SAndroid Build Coastguard Worker bool HasNext() 62*89c4ff92SAndroid Build Coastguard Worker { 63*89c4ff92SAndroid Build Coastguard Worker return this->m_count < 1 + this->FractionalTotalStrides() && (this->NextWindowStartIndex() < this->m_dataSize); 64*89c4ff92SAndroid Build Coastguard Worker } 65*89c4ff92SAndroid Build Coastguard Worker 66*89c4ff92SAndroid Build Coastguard Worker /** 67*89c4ff92SAndroid Build Coastguard Worker * Resest the slider to the initial position. 68*89c4ff92SAndroid Build Coastguard Worker */ Reset()69*89c4ff92SAndroid Build Coastguard Worker virtual void Reset() 70*89c4ff92SAndroid Build Coastguard Worker { 71*89c4ff92SAndroid Build Coastguard Worker m_count = 0; 72*89c4ff92SAndroid Build Coastguard Worker } 73*89c4ff92SAndroid Build Coastguard Worker 74*89c4ff92SAndroid Build Coastguard Worker /** 75*89c4ff92SAndroid Build Coastguard Worker * Resest the slider to the initial position. 76*89c4ff92SAndroid Build Coastguard Worker */ GetWindowSize()77*89c4ff92SAndroid Build Coastguard Worker virtual size_t GetWindowSize() 78*89c4ff92SAndroid Build Coastguard Worker { 79*89c4ff92SAndroid Build Coastguard Worker return m_size; 80*89c4ff92SAndroid Build Coastguard Worker } 81*89c4ff92SAndroid Build Coastguard Worker 82*89c4ff92SAndroid Build Coastguard Worker /** 83*89c4ff92SAndroid Build Coastguard Worker * Resets the slider to the start of the new data. 84*89c4ff92SAndroid Build Coastguard Worker * New data size MUST be the same as the old one. 85*89c4ff92SAndroid Build Coastguard Worker * @param newStart pointer to the new data to slide through. 86*89c4ff92SAndroid Build Coastguard Worker */ Reset(T * newStart)87*89c4ff92SAndroid Build Coastguard Worker virtual void Reset(T* newStart) 88*89c4ff92SAndroid Build Coastguard Worker { 89*89c4ff92SAndroid Build Coastguard Worker m_start = newStart; 90*89c4ff92SAndroid Build Coastguard Worker Reset(); 91*89c4ff92SAndroid Build Coastguard Worker } 92*89c4ff92SAndroid Build Coastguard Worker 93*89c4ff92SAndroid Build Coastguard Worker /** 94*89c4ff92SAndroid Build Coastguard Worker * Gets current index of the sliding window. 95*89c4ff92SAndroid Build Coastguard Worker * @return current position of the sliding window in number of strides 96*89c4ff92SAndroid Build Coastguard Worker */ Index()97*89c4ff92SAndroid Build Coastguard Worker size_t Index() 98*89c4ff92SAndroid Build Coastguard Worker { 99*89c4ff92SAndroid Build Coastguard Worker return m_count == 0? 0: m_count - 1; 100*89c4ff92SAndroid Build Coastguard Worker } 101*89c4ff92SAndroid Build Coastguard Worker 102*89c4ff92SAndroid Build Coastguard Worker /** 103*89c4ff92SAndroid Build Coastguard Worker * Gets the index from the start of the data where the next window will begin. 104*89c4ff92SAndroid Build Coastguard Worker * While Index() returns the index of sliding window itself this function returns the index of the data 105*89c4ff92SAndroid Build Coastguard Worker * element itself. 106*89c4ff92SAndroid Build Coastguard Worker * @return Index from the start of the data where the next sliding window will begin. 107*89c4ff92SAndroid Build Coastguard Worker */ NextWindowStartIndex()108*89c4ff92SAndroid Build Coastguard Worker virtual size_t NextWindowStartIndex() 109*89c4ff92SAndroid Build Coastguard Worker { 110*89c4ff92SAndroid Build Coastguard Worker return m_count == 0? 0: ((m_count) * m_stride); 111*89c4ff92SAndroid Build Coastguard Worker } 112*89c4ff92SAndroid Build Coastguard Worker 113*89c4ff92SAndroid Build Coastguard Worker /** 114*89c4ff92SAndroid Build Coastguard Worker * Go to given sliding window index. 115*89c4ff92SAndroid Build Coastguard Worker * @param index new position of the sliding window. if index is invalid (greater than possible range of strides) 116*89c4ff92SAndroid Build Coastguard Worker * then next call to Next() will return nullptr. 117*89c4ff92SAndroid Build Coastguard Worker */ FastForward(size_t index)118*89c4ff92SAndroid Build Coastguard Worker void FastForward(size_t index) 119*89c4ff92SAndroid Build Coastguard Worker { 120*89c4ff92SAndroid Build Coastguard Worker m_count = index; 121*89c4ff92SAndroid Build Coastguard Worker } 122*89c4ff92SAndroid Build Coastguard Worker 123*89c4ff92SAndroid Build Coastguard Worker /** 124*89c4ff92SAndroid Build Coastguard Worker * Calculates whole number of times the window can stride through the given data. 125*89c4ff92SAndroid Build Coastguard Worker * @return maximum number of strides. 126*89c4ff92SAndroid Build Coastguard Worker */ TotalStrides()127*89c4ff92SAndroid Build Coastguard Worker size_t TotalStrides() 128*89c4ff92SAndroid Build Coastguard Worker { 129*89c4ff92SAndroid Build Coastguard Worker if (m_size > m_dataSize) 130*89c4ff92SAndroid Build Coastguard Worker { 131*89c4ff92SAndroid Build Coastguard Worker return 0; 132*89c4ff92SAndroid Build Coastguard Worker } 133*89c4ff92SAndroid Build Coastguard Worker return ((m_dataSize - m_size)/m_stride); 134*89c4ff92SAndroid Build Coastguard Worker } 135*89c4ff92SAndroid Build Coastguard Worker 136*89c4ff92SAndroid Build Coastguard Worker /** 137*89c4ff92SAndroid Build Coastguard Worker * Calculates number of times the window can stride through the given data. May not be a whole number. 138*89c4ff92SAndroid Build Coastguard Worker * @return Number of strides to cover all data. 139*89c4ff92SAndroid Build Coastguard Worker */ FractionalTotalStrides()140*89c4ff92SAndroid Build Coastguard Worker float FractionalTotalStrides() 141*89c4ff92SAndroid Build Coastguard Worker { 142*89c4ff92SAndroid Build Coastguard Worker if(this->m_size > this->m_dataSize) 143*89c4ff92SAndroid Build Coastguard Worker { 144*89c4ff92SAndroid Build Coastguard Worker return this->m_dataSize / this->m_size; 145*89c4ff92SAndroid Build Coastguard Worker } 146*89c4ff92SAndroid Build Coastguard Worker else 147*89c4ff92SAndroid Build Coastguard Worker { 148*89c4ff92SAndroid Build Coastguard Worker return ((this->m_dataSize - this->m_size)/ static_cast<float>(this->m_stride)); 149*89c4ff92SAndroid Build Coastguard Worker } 150*89c4ff92SAndroid Build Coastguard Worker 151*89c4ff92SAndroid Build Coastguard Worker } 152*89c4ff92SAndroid Build Coastguard Worker 153*89c4ff92SAndroid Build Coastguard Worker /** 154*89c4ff92SAndroid Build Coastguard Worker * Calculates the remaining data left to be processed 155*89c4ff92SAndroid Build Coastguard Worker * @return The remaining unprocessed data 156*89c4ff92SAndroid Build Coastguard Worker */ RemainingData()157*89c4ff92SAndroid Build Coastguard Worker int RemainingData() 158*89c4ff92SAndroid Build Coastguard Worker { 159*89c4ff92SAndroid Build Coastguard Worker return this->m_dataSize - this->NextWindowStartIndex(); 160*89c4ff92SAndroid Build Coastguard Worker } 161*89c4ff92SAndroid Build Coastguard Worker };