f278be4914ca7a23bc5507091e1deeec5c549b40
[ric-app/admin.git] / src / protector-plugin / sliding_window.cc
1 /*
2 ==================================================================================
3
4         Copyright (c) 2018-2019 AT&T Intellectual Property.
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 #include "sliding_window.hpp"
21
22
23 sliding_window::sliding_window(unsigned int window_size){
24
25   if (window_size < MIN_WINDOW_SIZE){
26     std::stringstream ss;
27     ss << "Error ::" << __FILE__ << ","<< __LINE__ << " window size must be >= " << MIN_WINDOW_SIZE << " Specified = " << window_size << std::endl;
28     error_string = ss.str();
29     throw std::logic_error(error_string);
30   }
31
32   if (window_size > MAX_WINDOW_SIZE){
33     std::stringstream ss;
34     ss << "Error ::" << __FILE__ << ","<< __LINE__ << " window size must be <= " << MAX_WINDOW_SIZE << " Specified = " << window_size << std::endl;
35     std::string error_string = ss.str();
36     throw std::logic_error(error_string);
37   }
38
39   window_size_ = window_size;
40   sliding_window_.resize(window_size_);
41   
42   head = window_size_ -1;
43   tail = 0;
44   net_events = 0;
45   leading_edge_ = std::chrono::steady_clock::now();
46 }
47
48 // expect to be called very frequently ....
49 bool  sliding_window::update_window(unsigned int events){
50   // get current time
51   auto current_edge = std::chrono::steady_clock::now();
52   
53   int shift = std::chrono::duration_cast<std::chrono::seconds>(current_edge - leading_edge_).count();
54
55
56   // Advance window if shift >= 1
57   if (shift >= 1){
58     leading_edge_ = current_edge;
59   }
60   
61   if (shift >= window_size_){
62     // gap between current time and leading edge
63     // exceeds window size. Clear everything ...
64     tail = 0;
65     head = window_size_ -1;
66     std::fill(sliding_window_.begin(), sliding_window_.end(), 0);
67     sliding_window_[head] = events ;
68     net_events = events;
69     return true;
70   }
71   
72   for(int i = 0; i < shift; i++){
73     // Advance tail & head by requisite amount, reducing net event rate ..
74     net_events -= sliding_window_[tail];
75     sliding_window_[tail] = 0;
76     tail += 1;
77     if (tail >= window_size_){
78       tail = 0;
79     }
80     
81     head += 1;
82     if (head >= window_size_){
83       head = 0;
84     }
85   }
86
87   sliding_window_[head] += events;
88   net_events += events;
89
90   //std::cout <<net_events << "," << window_size_ << "," << shift << std::endl;  
91   return true;
92 }
93
94 // modifies window size. resets all parameters 
95 bool sliding_window::resize_window(unsigned int window_size){
96   if (window_size < MIN_WINDOW_SIZE || window_size > MAX_WINDOW_SIZE){
97     std::stringstream ss;
98     ss << "Error ::" << __FILE__ << ","<< __LINE__ << " Illegal window size !  window size must be in [ " << MIN_WINDOW_SIZE << "," << MAX_WINDOW_SIZE << "]"  << std::endl;
99     error_string = ss.str();
100     return false;
101   }
102   
103   window_size_ = window_size;
104   sliding_window_.clear();
105   sliding_window_.resize(window_size_);
106   net_events = 0;
107   head = window_size_ -1;
108   tail = 0;
109   leading_edge_ = std::chrono::steady_clock::now();
110   return true;
111 }
112
113 std::string  sliding_window::display_window(void){
114   std::stringstream ss;
115   for(unsigned int i = 0; i < sliding_window_.size(); i++){
116     if (i == head){
117       ss <<"[H] ";
118     }
119     if (i == tail){
120       ss <<"[T] ";
121     }
122     
123     ss <<sliding_window_[i] <<",";
124   }
125   ss <<" [Events] = " << net_events << std::endl;
126
127   return ss.str();
128 }
129
130 void sliding_window::clear(void){
131   
132   resize_window(window_size_);
133 }
134
135   
136