Electroneum
Loading...
Searching...
No Matches
math_helper.h
Go to the documentation of this file.
1// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above copyright
9// notice, this list of conditions and the following disclaimer in the
10// documentation and/or other materials provided with the distribution.
11// * Neither the name of the Andrey N. Sabelnikov nor the
12// names of its contributors may be used to endorse or promote products
13// derived from this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
19// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25//
26
27
28
29
30#pragma once
31
32
33#include <list>
34#include <numeric>
35#include <boost/timer/timer.hpp>
36#include <boost/uuid/uuid.hpp>
37#include <boost/uuid/random_generator.hpp>
38
39#include "misc_os_dependent.h"
40#include "syncobj.h"
41
42namespace epee
43{
44namespace math_helper
45{
46
47 template<typename val, int default_base>
48 class average
49 {
50 public:
51
53 {
54 m_base = default_base;
55 m_last_avg_val = 0;
56 }
57
58 bool set_base()
59 {
61
62 m_base = default_base;
63 if(m_list.size() > m_base)
64 m_list.resize(m_base);
65
66 return true;
67 }
68
69 typedef val value_type;
70
71 void push(const value_type& vl)
72 {
74
75//#ifndef DEBUG_STUB
76 m_list.push_back(vl);
77 if(m_list.size() > m_base )
78 m_list.pop_front();
79//#endif
80 }
81
82 double update(const value_type& vl)
83 {
85//#ifndef DEBUG_STUB
86 push(vl);
87//#endif
88
89 return get_avg();
90 }
91
92 double get_avg()
93 {
95
96 value_type vl = std::accumulate(m_list.begin(), m_list.end(), value_type(0));
97 if(m_list.size())
98 return m_last_avg_val = (double)(vl/m_list.size());
99
100 return m_last_avg_val = (double)vl;
101 }
102
104 {
105 CRITICAL_REGION_LOCAL(m_lock);
106 if(m_list.size())
107 return m_list.back();
108
109 return 0;
110 }
111
112 private:
113 unsigned int m_base;
114 double m_last_avg_val;
115 std::list<value_type> m_list;
116 critical_section m_lock;
117 };
118
119
120#ifdef WINDOWS_PLATFORM
121
122 /************************************************************************/
123 /* */
124 /************************************************************************/
125 class timing_guard_base
126 {
127 public:
128 virtual ~timing_guard_base(){};
129 };
130
131 template<class T>
132 class timing_guard: public timing_guard_base
133 {
134 public:
135 timing_guard(T& avrg):m_avrg(avrg)
136 {
137 m_start_ticks = ::GetTickCount();
138 }
139
140 ~timing_guard()
141 {
142 m_avrg.push(::GetTickCount()-m_start_ticks);
143 }
144
145 private:
146 T& m_avrg;
147 DWORD m_start_ticks;
148 };
149
150 template<class t_timing>
151 timing_guard_base* create_timing_guard(t_timing& timing){return new timing_guard<t_timing>(timing);}
152
153#define BEGIN_TIMING_ZONE(timing_var) { boost::shared_ptr<math_helper::timing_guard_base> local_timing_guard_ptr(math_helper::create_timing_guard(timing_var));
154#define END_TIMING_ZONE() }
155#endif
156
157//#ifdef WINDOWS_PLATFORM_EX
158 template<uint64_t default_time_window>
159 class speed
160 {
161 public:
162
164 {
165 m_time_window = default_time_window;
166 m_last_speed_value = 0;
167 }
168 bool chick()
169 {
170#ifndef DEBUG_STUB
172 CRITICAL_REGION_BEGIN(m_lock);
173 m_chicks.push_back(ticks);
175 //flush(ticks);
176#endif
177 return true;
178 }
179
180 bool chick(size_t count)
181 {
182 for(size_t s = 0; s != count; s++)
183 chick();
184
185 return true;
186 }
187
188
189 size_t get_speed()
190 {
192 return m_last_speed_value = m_chicks.size();
193 }
194 private:
195
196 bool flush(uint64_t ticks)
197 {
198 CRITICAL_REGION_BEGIN(m_lock);
199 std::list<uint64_t>::iterator it = m_chicks.begin();
200 while(it != m_chicks.end())
201 {
202 if(*it + m_time_window < ticks)
203 m_chicks.erase(it++);
204 else
205 break;
206 }
208 return true;
209 }
210
211 std::list<uint64_t> m_chicks;
212 uint64_t m_time_window;
213 size_t m_last_speed_value;
214 critical_section m_lock;
215 };
216//#endif
217
218 template<class tlist>
219 void randomize_list(tlist& t_list)
220 {
221 for(typename tlist::iterator it = t_list.begin();it!=t_list.end();it++)
222 {
223 size_t offset = rand()%t_list.size();
224 typename tlist::iterator it_2 = t_list.begin();
225 for(size_t local_offset = 0;local_offset!=offset;local_offset++)
226 it_2++;
227 if(it_2 == it)
228 continue;
229 std::swap(*it_2, *it);
230 }
231
232 }
233 template<uint64_t scale, int default_interval, bool start_immediate = true>
235 {
236 uint64_t get_time() const
237 {
238#ifdef _WIN32
239 FILETIME fileTime;
240 GetSystemTimeAsFileTime(&fileTime);
241 unsigned __int64 present = 0;
242 present |= fileTime.dwHighDateTime;
243 present = present << 32;
244 present |= fileTime.dwLowDateTime;
245 present /= 10; // mic-sec
246 return present;
247#else
248 struct timeval tv;
249 gettimeofday(&tv, NULL);
250 return tv.tv_sec * 1000000 + tv.tv_usec;
251#endif
252 }
253
254 public:
255 once_a_time():m_interval(default_interval * scale)
256 {
257 m_last_worked_time = 0;
258 if(!start_immediate)
259 m_last_worked_time = get_time();
260 }
261
262 template<class functor_t>
263 bool do_call(functor_t functr)
264 {
265 uint64_t current_time = get_time();
266
267 if(current_time - m_last_worked_time > m_interval)
268 {
269 bool res = functr();
270 m_last_worked_time = get_time();
271 return res;
272 }
273 return true;
274 }
275
276 private:
277 uint64_t m_last_worked_time;
278 uint64_t m_interval;
279 };
280
281 template<int default_interval, bool start_immediate = true>
282 class once_a_time_seconds: public once_a_time<1000000, default_interval, start_immediate> {};
283 template<int default_interval, bool start_immediate = true>
284 class once_a_time_milliseconds: public once_a_time<1000, default_interval, start_immediate> {};
285}
286}
double update(const value_type &vl)
Definition math_helper.h:82
void push(const value_type &vl)
Definition math_helper.h:71
bool do_call(functor_t functr)
bool chick(size_t count)
const char * res
void randomize_list(tlist &t_list)
uint64_t get_tick_count()
unsigned __int64 uint64_t
Definition stdint.h:136
#define CRITICAL_REGION_LOCAL(x)
Definition syncobj.h:228
#define CRITICAL_REGION_END()
Definition syncobj.h:233
#define CRITICAL_REGION_BEGIN(x)
Definition syncobj.h:229
#define T(x)