Electroneum
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 
42 namespace epee
43 {
44 namespace 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  {
60  CRITICAL_REGION_LOCAL(m_lock);
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  {
73  CRITICAL_REGION_LOCAL(m_lock);
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  {
84  CRITICAL_REGION_LOCAL(m_lock);
85 //#ifndef DEBUG_STUB
86  push(vl);
87 //#endif
88 
89  return get_avg();
90  }
91 
92  double get_avg()
93  {
94  CRITICAL_REGION_LOCAL(m_lock);
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 }
const char * res
Definition: hmac_keccak.cpp:41
const uint32_t T[512]
void randomize_list(tlist &t_list)
Definition: math_helper.h:219
uint64_t get_tick_count()
void push(const value_type &vl)
Definition: math_helper.h:71
#define CRITICAL_REGION_END()
Definition: syncobj.h:233
mdb_size_t count(MDB_cursor *cur)
void rand(size_t N, uint8_t *bytes)
Definition: crypto.h:209
#define CRITICAL_REGION_BEGIN(x)
Definition: syncobj.h:229
unsigned __int64 uint64_t
Definition: stdint.h:136
#define CRITICAL_REGION_LOCAL(x)
Definition: syncobj.h:228
bool chick(size_t count)
Definition: math_helper.h:180
double update(const value_type &vl)
Definition: math_helper.h:82
bool do_call(functor_t functr)
Definition: math_helper.h:263