]>
git.saurik.com Git - apple/network_cmds.git/blob - unbound/util/timehist.c
dbf5b98417c26d42fcd039657cd738434918bee9
2 * util/timehist.c - make histogram of time values.
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
6 * This software is open source.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 * This file contains functions to make a histogram of time values.
46 #include <sys/types.h>
47 #include "util/timehist.h"
50 /** special timestwo operation for time values in histogram setup */
52 timestwo(struct timeval
* v
)
55 if(v
->tv_sec
== 0 && v
->tv_usec
== 0) {
61 if(v
->tv_usec
== 1024*1024) {
62 /* nice values and easy to compute */
69 /** do setup exponentially */
71 dosetup(struct timehist
* hist
)
75 memset(&last
, 0, sizeof(last
));
76 for(i
=0; i
<hist
->num
; i
++) {
77 hist
->buckets
[i
].lower
= last
;
79 hist
->buckets
[i
].upper
= last
;
80 hist
->buckets
[i
].count
= 0;
84 struct timehist
* timehist_setup(void)
86 struct timehist
* hist
= (struct timehist
*)calloc(1,
87 sizeof(struct timehist
));
90 hist
->num
= NUM_BUCKETS_HIST
;
91 hist
->buckets
= (struct th_buck
*)calloc(hist
->num
,
92 sizeof(struct th_buck
));
97 /* setup the buckets */
102 void timehist_delete(struct timehist
* hist
)
110 void timehist_clear(struct timehist
* hist
)
113 for(i
=0; i
<hist
->num
; i
++)
114 hist
->buckets
[i
].count
= 0;
117 /** histogram compare of time values */
119 timeval_smaller(const struct timeval
* x
, const struct timeval
* y
)
122 if(x
->tv_sec
< y
->tv_sec
)
124 else if(x
->tv_sec
== y
->tv_sec
) {
125 if(x
->tv_usec
<= y
->tv_usec
)
134 void timehist_insert(struct timehist
* hist
, struct timeval
* tv
)
137 for(i
=0; i
<hist
->num
; i
++) {
138 if(timeval_smaller(tv
, &hist
->buckets
[i
].upper
)) {
139 hist
->buckets
[i
].count
++;
143 /* dump in last bucket */
144 hist
->buckets
[hist
->num
-1].count
++;
147 void timehist_print(struct timehist
* hist
)
151 for(i
=0; i
<hist
->num
; i
++) {
152 if(hist
->buckets
[i
].count
!= 0) {
153 printf("%4d.%6.6d %4d.%6.6d %u\n",
154 (int)hist
->buckets
[i
].lower
.tv_sec
,
155 (int)hist
->buckets
[i
].lower
.tv_usec
,
156 (int)hist
->buckets
[i
].upper
.tv_sec
,
157 (int)hist
->buckets
[i
].upper
.tv_usec
,
158 (unsigned)hist
->buckets
[i
].count
);
164 void timehist_log(struct timehist
* hist
, const char* name
)
168 log_info("[25%%]=%g median[50%%]=%g [75%%]=%g",
169 timehist_quartile(hist
, 0.25),
170 timehist_quartile(hist
, 0.50),
171 timehist_quartile(hist
, 0.75));
172 /* 0000.000000 0000.000000 0 */
173 log_info("lower(secs) upper(secs) %s", name
);
174 for(i
=0; i
<hist
->num
; i
++) {
175 if(hist
->buckets
[i
].count
!= 0) {
176 log_info("%4d.%6.6d %4d.%6.6d %u",
177 (int)hist
->buckets
[i
].lower
.tv_sec
,
178 (int)hist
->buckets
[i
].lower
.tv_usec
,
179 (int)hist
->buckets
[i
].upper
.tv_sec
,
180 (int)hist
->buckets
[i
].upper
.tv_usec
,
181 (unsigned)hist
->buckets
[i
].count
);
187 /** total number in histogram */
189 timehist_count(struct timehist
* hist
)
192 for(i
=0; i
<hist
->num
; i
++)
193 res
+= hist
->buckets
[i
].count
;
198 timehist_quartile(struct timehist
* hist
, double q
)
200 double lookfor
, passed
, res
;
201 double low
= 0, up
= 0;
203 if(!hist
|| hist
->num
== 0)
205 /* look for i'th element, interpolated */
206 lookfor
= (double)timehist_count(hist
);
208 return 0.; /* not enough elements for a good estimate */
212 while(i
+1 < hist
->num
&&
213 passed
+(double)hist
->buckets
[i
].count
< lookfor
) {
214 passed
+= (double)hist
->buckets
[i
++].count
;
216 /* got the right bucket */
218 low
= (double)hist
->buckets
[i
].lower
.tv_sec
+
219 (double)hist
->buckets
[i
].lower
.tv_usec
/1000000.;
220 up
= (double)hist
->buckets
[i
].upper
.tv_sec
+
221 (double)hist
->buckets
[i
].upper
.tv_usec
/1000000.;
223 res
= (lookfor
- passed
)*(up
-low
)/((double)hist
->buckets
[i
].count
);
228 timehist_export(struct timehist
* hist
, size_t* array
, size_t sz
)
235 array
[i
] = hist
->buckets
[i
].count
;
239 timehist_import(struct timehist
* hist
, size_t* array
, size_t sz
)
246 hist
->buckets
[i
].count
= array
[i
];