1 /***************************************************************************
2 MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
3 2008 - Gilles Audemard, Laurent Simon
4 CryptoMiniSat -- Copyright (c) 2009 Mate Soos
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 ****************************************************************************/
24 
25 #ifndef BOUNDEDQUEUE_H
26 #define BOUNDEDQUEUE_H
27 
28 #include "constants.h"
29 #include "avgcalc.h"
30 #include <cassert>
31 #include <vector>
32 #include <cstring>
33 #include <sstream>
34 #include <iomanip>
35 
36 namespace CMSat {
37 using std::vector;
38 
39 template <class T, class T2 = uint64_t>
40 class bqueue {
41     //Only stores info for N elements
42     vector<T>  elems;
43     uint32_t first;
44     uint32_t last;
45     uint32_t maxsize; //max number of history elements
46     uint32_t queuesize; // Number of current elements (must be < maxsize !)
47     T2  sumofqueue;
48     #if defined(STATS_NEEDED) || defined(FINAL_PREDICTOR)
49     AvgCalc<T, T2> longTermAvg;
50     #endif
51 
52 public:
bqueue(void)53     bqueue(void) :
54         first(0)
55         , last(0)
56         , maxsize(0)
57         , queuesize(0)
58         , sumofqueue(0)
59     {}
60 
usedMem()61     size_t usedMem() const
62     {
63         return sizeof(size_t)*4 + elems.capacity()*sizeof(T) + sizeof(T2) + sizeof(AvgCalc<T,T2>);
64     }
65 
push(const T x)66     void push(const T x) {
67         if (queuesize == maxsize) {
68             // The queue is full, next value to enter will replace oldest one
69 
70             assert(last == first);
71             sumofqueue -= elems[last];
72 
73             last++;
74             if (last == maxsize)
75                 last = 0;
76 
77         } else {
78             queuesize++;
79         }
80 
81         sumofqueue += x;
82 
83         #if defined(STATS_NEEDED) || defined(FINAL_PREDICTOR)
84         longTermAvg.push(x);
85         #endif
86         elems[first] = x;
87 
88         first++;
89         if (first == maxsize)
90             first = 0;
91     }
92 
avg()93     double avg() const
94     {
95         if (queuesize == 0)
96             return 0;
97 
98         assert(isvalid());
99         return (double)sumofqueue/(double)queuesize;
100     }
101 
avg_nocheck()102     double avg_nocheck() const
103     {
104         if (queuesize == 0)
105             return 0;
106 
107         return (double)sumofqueue/(double)queuesize;
108     }
109 
110     #if defined(STATS_NEEDED) || defined(FINAL_PREDICTOR)
getLongtTerm()111     const AvgCalc<T,T2>& getLongtTerm() const
112     {
113         return longTermAvg;
114     }
115 
prev(int32_t p)116     T prev(int32_t p) const
117     {
118         if (p > (int32_t)queuesize)
119             return 0;
120 
121         uint32_t e;
122         if (first > 0) {
123             e = first-1;
124         } else {
125             e = maxsize-1;
126         }
127 
128         while(p-- > 0) {
129             if (e == 0) {
130                 e = maxsize-1;
131             } else {
132                 e--;
133             }
134         }
135         return elems[e];
136     }
137     #endif
138 
getAvgPrint(size_t prec,size_t w)139     std::string getAvgPrint(size_t prec, size_t w) const
140     {
141         std::stringstream ss;
142         if (isvalid()) {
143             ss
144             << std::fixed << std::setprecision(prec) << std::setw(w) << std::right
145             << avg();
146         } else {
147             ss << std::setw(5) << "?";
148         }
149 
150         return ss.str();
151     }
152 
isvalid()153     bool isvalid() const
154     {
155         return (queuesize == maxsize);
156     }
157 
clearAndResize(const size_t size)158     void clearAndResize(const size_t size)
159     {
160         clear();
161         elems.resize(size);
162         maxsize = size;
163     }
164 
clear()165     void clear()
166     {
167         first = 0;
168         last = 0;
169         queuesize = 0;
170         sumofqueue = 0;
171 
172         #if defined(STATS_NEEDED) || defined(FINAL_PREDICTOR)
173         longTermAvg.clear();
174         #endif
175     }
176 
get_size()177     size_t get_size() const
178     {
179         return queuesize;
180     }
181 
get_maxsize()182     size_t get_maxsize() const
183     {
184         return maxsize;
185     }
186 };
187 
188 } //end namespace
189 
190 #endif //BOUNDEDQUEUE_H
191