Initial commit of Admission Control xAPP and E2AP/X2AP definitions
[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   if (shift < 0){
56     // we do not update any events if they happened in the past
57     // by more than unit of window .. (1 second currently)
58     return false;
59   }
60
61   // Advance window if shift >= 1
62   if (shift >= 1){
63     leading_edge_ = current_edge;
64   }
65   
66   if (shift >= window_size_){
67     // gap between current time and leading edge
68     // exceeds window size. Clear everything ...
69     tail = 0;
70     head = window_size_ -1;
71     std::fill(sliding_window_.begin(), sliding_window_.end(), 0);
72     sliding_window_[head] = events ;
73     net_events = events;
74     return true;
75   }
76   
77   for(int i = 0; i < shift; i++){
78     // Advance tail & head by requisite amount, reducing net event rate ..
79     net_events -= sliding_window_[tail];
80     sliding_window_[tail] = 0;
81     tail += 1;
82     if (tail >= window_size_){
83       tail = 0;
84     }
85     
86     head += 1;
87     if (head >= window_size_){
88       head = 0;
89     }
90   }
91
92   sliding_window_[head] += events;
93   net_events += events;
94
95   //std::cout <<net_events << "," << window_size_ << "," << shift << std::endl;  
96   return true;
97 }
98
99 // modifies window size. resets all parameters 
100 bool sliding_window::resize_window(unsigned int window_size){
101   if (window_size < MIN_WINDOW_SIZE || window_size > MAX_WINDOW_SIZE){
102     std::stringstream ss;
103     ss << "Error ::" << __FILE__ << ","<< __LINE__ << " window size must be in [ " << MIN_WINDOW_SIZE << "," << MAX_WINDOW_SIZE << "]"  << std::endl;
104     error_string = ss.str();
105     return false;
106   }
107   
108   window_size_ = window_size;
109   sliding_window_.clear();
110   sliding_window_.resize(window_size_);
111   net_events = 0;
112   head = window_size_ -1;
113   tail = 0;
114   leading_edge_ = std::chrono::steady_clock::now();
115   return true;
116 }
117
118 std::string  sliding_window::display_window(void){
119   std::stringstream ss;
120   for(unsigned int i = 0; i < sliding_window_.size(); i++){
121     if (i == head){
122       ss <<"[H] ";
123     }
124     if (i == tail){
125       ss <<"[T] ";
126     }
127     
128     ss <<sliding_window_[i] <<",";
129   }
130   ss <<" [Events] = " << net_events << std::endl;
131
132   return ss.str();
133 }
134
135 void sliding_window::clear(void){
136   
137   resize_window(window_size_);
138 }
139
140   
141