]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/statbag.cc
add OpenSSL exception to PowerDNS, Netherlabs, van Dijk and Hubert copyrights
[thirdparty/pdns.git] / pdns / statbag.cc
CommitLineData
12c86877
BH
1/*
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002 PowerDNS.COM BV
4
5 This program is free software; you can redistribute it and/or modify
22dc646a
BH
6 it under the terms of the GNU General Public License version 2
7 as published by the Free Software Foundation
f782fe38
MH
8
9 Additionally, the license of this program contains a special
10 exception which allows to distribute the program in binary form when
11 it is linked against OpenSSL.
12c86877
BH
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
06bd9ccf 20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12c86877 21*/
896e5153
BH
22
23#include "utility.hh"
12c86877 24#include "statbag.hh"
5c409fa2 25#include "pdnsexception.hh"
12c86877
BH
26#include <iostream>
27#include <sstream>
28#include <algorithm>
29#include "arguments.hh"
30#include "lock.hh"
31
10f4eea8 32#include "namespaces.hh"
12c86877
BH
33
34StatBag::StatBag()
35{
36 d_doRings=false;
37 pthread_mutex_init(&d_lock,0);
38}
39
40
41
42/** this NEEDS TO HAVE THE LOCK held already! */
43void StatBag::exists(const string &key)
44{
45 if(!d_stats.count(key))
46 {
47 unlock(); // it's the details that count
3f81d239 48 throw PDNSException("Trying to deposit into unknown StatBag key '"+key+"'");
12c86877
BH
49 }
50}
51
52string StatBag::directory()
53{
54 string dir;
55 ostringstream o;
56 lock();
dee7ba5a 57 for(map<string, unsigned int *>::const_iterator i=d_stats.begin();
12c86877
BH
58 i!=d_stats.end();
59 i++)
60 {
61 o<<i->first<<"="<<*(i->second)<<",";
62 }
63 unlock();
64 dir=o.str();
65 return dir;
66}
67
68
69vector<string>StatBag::getEntries()
70{
71 vector<string> ret;
72 lock();
dee7ba5a 73 for(map<string, unsigned int *>::const_iterator i=d_stats.begin();
12c86877
BH
74 i!=d_stats.end();
75 i++)
76 ret.push_back(i->first);
77
78 unlock();
79 return ret;
80
81}
82
83string StatBag::getDescrip(const string &item)
84{
85 lock();
86 string tmp=d_keyDescrips[item];
87 unlock();
88 return tmp;
89}
90
91void StatBag::declare(const string &key, const string &descrip)
92{
93 lock();
dee7ba5a 94 unsigned int *i=new unsigned int(0);
12c86877
BH
95 d_stats[key]=i;
96 d_keyDescrips[key]=descrip;
97 unlock();
98}
99
100
101
bb3c3f50 102void StatBag::set(const string &key, unsigned int value)
12c86877
BH
103{
104 lock();
105 exists(key);
106 *d_stats[key]=value;
107
108 unlock();
109}
110
bb3c3f50 111unsigned int StatBag::read(const string &key)
12c86877
BH
112{
113 lock();
114
115 if(!d_stats.count(key))
116 {
117 unlock();
118 return 0;
119 }
120
bb3c3f50 121 unsigned int tmp=*d_stats[key];
12c86877
BH
122
123 unlock();
124 return tmp;
12c86877
BH
125}
126
bb3c3f50 127unsigned int StatBag::readZero(const string &key)
12c86877
BH
128{
129 lock();
130
131
132 if(!d_stats.count(key))
133 {
134 unlock();
135 return 0;
136 }
137
138
bb3c3f50 139 unsigned int tmp=*d_stats[key];
12c86877
BH
140 d_stats[key]=0;
141
142 unlock();
143
144 return tmp;
145}
146
147
148string StatBag::getValueStr(const string &key)
149{
150 ostringstream o;
151 o<<read(key);
152 return o.str();
153}
154
155string StatBag::getValueStrZero(const string &key)
156{
157 ostringstream o;
158 o<<readZero(key);
159 return o.str();
160}
161
dee7ba5a 162unsigned int *StatBag::getPointer(const string &key)
12c86877
BH
163{
164 exists(key);
165 return d_stats[key];
166}
167
168StatBag::~StatBag()
169{
dee7ba5a 170 for(map<string,unsigned int *>::const_iterator i=d_stats.begin();
12c86877
BH
171 i!=d_stats.end();
172 i++)
173 {
174 delete i->second;
175 }
176
177}
178
bb3c3f50 179StatRing::StatRing(unsigned int size)
12c86877
BH
180{
181 d_size=size;
182 d_items.resize(d_size);
183 d_lock=0;
184 d_pos=0;
185 d_lock=new pthread_mutex_t;
186 pthread_mutex_init(d_lock, 0);
187}
188
bb3c3f50 189void StatRing::resize(unsigned int newsize)
12c86877
BH
190{
191 if(d_size==newsize)
192 return;
193 Lock l(d_lock);
194
12c86877 195 // this is the hard part, shrink
975bee12
KM
196 if(newsize<d_size) {
197 unsigned int startpos=0;
198 if (d_pos>newsize)
199 startpos=d_pos-newsize;
200
201 vector<string>newring;
202 for(unsigned int i=startpos;i<d_pos;++i) {
203 newring.push_back(d_items[i%d_size]);
204 }
12c86877 205
975bee12
KM
206 d_items=newring;
207 d_size=newring.size();
208 d_pos=min(d_pos,newsize);
12c86877 209 }
12c86877 210
975bee12
KM
211 if(newsize>d_size) {
212 d_size=newsize;
213 d_items.resize(d_size);
214 }
12c86877 215}
975bee12 216
12c86877
BH
217StatRing::~StatRing()
218{
219 // do not clean up d_lock, it is shared
220}
221
222void StatRing::setHelp(const string &str)
223{
224 d_help=str;
225}
226
227string StatRing::getHelp()
228{
229 return d_help;
230}
231
232static bool popisort(const pair<string,int> &a, const pair<string,int> &b)
233{
234 return (a.second > b.second);
235}
236
bb3c3f50 237vector<pair<string,unsigned int> >StatRing::get() const
12c86877
BH
238{
239 Lock l(d_lock);
bb3c3f50 240 map<string,unsigned int> res;
12c86877
BH
241 for(vector<string>::const_iterator i=d_items.begin();i!=d_items.end();++i) {
242 if(!i->empty())
243 res[*i]++;
244 }
245
bb3c3f50
BH
246 vector<pair<string,unsigned int> > tmp;
247 for(map<string,unsigned int>::const_iterator i=res.begin();i!=res.end();++i)
12c86877
BH
248 tmp.push_back(*i);
249
250 sort(tmp.begin(),tmp.end(),popisort);
251
252 return tmp;
253}
254
255void StatBag::declareRing(const string &name, const string &help, unsigned int size)
256{
257 d_rings[name]=StatRing(size);
258 d_rings[name].setHelp(help);
259}
260
bb3c3f50 261vector<pair<string, unsigned int> > StatBag::getRing(const string &name)
12c86877
BH
262{
263 return d_rings[name].get();
264}
265
266void StatRing::reset()
267{
268 Lock l(d_lock);
269 for(vector<string>::iterator i=d_items.begin();i!=d_items.end();++i) {
270 if(!i->empty())
271 *i="";
272 }
273}
274
275void StatBag::resetRing(const string &name)
276{
277 d_rings[name].reset();
278}
279
bb3c3f50 280void StatBag::resizeRing(const string &name, unsigned int newsize)
12c86877
BH
281{
282 d_rings[name].resize(newsize);
283}
284
285
bb3c3f50 286unsigned int StatBag::getRingSize(const string &name)
12c86877
BH
287{
288 return d_rings[name].getSize();
289}
290
291
292string StatBag::getRingTitle(const string &name)
293{
294 return d_rings[name].getHelp();
295}
296
297vector<string>StatBag::listRings()
298{
299 vector<string> ret;
300 for(map<string,StatRing>::const_iterator i=d_rings.begin();i!=d_rings.end();++i)
301 ret.push_back(i->first);
302 return ret;
303}
304
305