]> git.ipfire.org Git - thirdparty/squid.git/blame - src/cache_diff.cc
Cleanup a lot of whitespace crap, mostl of which introduced by astyle
[thirdparty/squid.git] / src / cache_diff.cc
CommitLineData
f740a279 1
8667b856 2/*
c3031d67 3 * $Id: cache_diff.cc,v 1.21 2007/11/15 16:47:35 wessels Exp $
8667b856 4 *
5 * AUTHOR: Alex Rousskov
6 *
2b6662ba 7 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 8 * ----------------------------------------------------------
8667b856 9 *
2b6662ba 10 * Squid is the result of efforts by numerous individuals from
11 * the Internet community; see the CONTRIBUTORS file for full
12 * details. Many organizations have provided support for Squid's
13 * development; see the SPONSORS file for full details. Squid is
14 * Copyrighted (C) 2001 by the Regents of the University of
15 * California; see the COPYRIGHT file for full details. Squid
16 * incorporates software developed and/or copyrighted by other
17 * sources; see the CREDITS file for full details.
8667b856 18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
cbdec147 31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 32 *
8667b856 33 */
34
35/*
36 * Computes the difference between the contents of two caches
37 * using swap logs
38 * Reports the percentage of common files and other stats
39 */
40
41#include "squid.h"
42
62e76326 43typedef struct
44{
8667b856 45 const char *name;
46 hash_table *hash;
1afe05c5 47 int count; /* #currently cached entries */
48 int scanned_count; /* #scanned entries */
49 int bad_add_count; /* #duplicate adds */
50 int bad_del_count; /* #dels with no prior add */
62e76326 51}
52
53CacheIndex;
8667b856 54
55
62e76326 56typedef struct _CacheEntry
57{
8667b856 58 const cache_key *key;
62e76326 59
8667b856 60 struct _CacheEntry *next;
51ee7c82 61 /* StoreSwapLogData s; */
c3031d67 62 unsigned char key_arr[SQUID_MD5_DIGEST_LENGTH];
62e76326 63}
64
65CacheEntry;
8667b856 66
67
68/* copied from url.c */
69const char *RequestMethodStr[] =
62e76326 70 {
71 "NONE",
72 "GET",
73 "POST",
74 "PUT",
75 "HEAD",
76 "CONNECT",
77 "TRACE",
78 "PURGE"
79 };
8667b856 80
81
1afe05c5 82static int cacheIndexScan(CacheIndex * idx, const char *fname, FILE * file);
8667b856 83
84
85static CacheEntry *
51ee7c82 86cacheEntryCreate(const StoreSwapLogData * s)
8667b856 87{
88 CacheEntry *e = xcalloc(1, sizeof(CacheEntry));
89 assert(s);
edc1d6da 90 /* e->s = *s; */
c3031d67 91 xmemcpy(e->key_arr, s->key, SQUID_MD5_DIGEST_LENGTH);
edc1d6da 92 e->key = &e->key_arr[0];
8667b856 93 return e;
94}
95
96static void
1afe05c5 97cacheEntryDestroy(CacheEntry * e)
8667b856 98{
99 assert(e);
100 xfree(e);
101}
102
103static CacheIndex *
104cacheIndexCreate(const char *name)
105{
106 CacheIndex *idx;
62e76326 107
8667b856 108 if (!name || !strlen(name))
62e76326 109 return NULL;
8667b856 110
111 idx = xcalloc(1, sizeof(CacheIndex));
62e76326 112
8667b856 113 idx->name = name;
62e76326 114
8667b856 115 idx->hash = hash_create(storeKeyHashCmp, 2e6, storeKeyHashHash);
116
117 return idx;
118}
119
120static void
1afe05c5 121cacheIndexDestroy(CacheIndex * idx)
8667b856 122{
123 hash_link *hashr = NULL;
62e76326 124
8667b856 125 if (idx) {
62e76326 126 /* destroy hash list contents */
127 hash_first(idx->hash);
128
129 while (hashr = hash_next(idx->hash)) {
130 hash_remove_link(idx->hash, hashr);
131 cacheEntryDestroy((CacheEntry *) hashr);
132 }
133
134 /* destroy the hash table itself */
135 hashFreeMemory(idx->hash);
136
137 xfree(idx);
8667b856 138 }
139}
140
141static int
1afe05c5 142cacheIndexAddLog(CacheIndex * idx, const char *fname)
8667b856 143{
144 FILE *file;
145 int scanned_count = 0;
146 assert(idx);
147 assert(fname && strlen(fname));
148
149 file = fopen(fname, "r");
62e76326 150
8667b856 151 if (!file) {
62e76326 152 fprintf(stderr, "cannot open %s: %s\n", fname, strerror(errno));
153 return 0;
8667b856 154 }
62e76326 155
ec4daaa5 156#ifdef _SQUID_WIN32_
c4aefe96 157 setmode(fileno(file), O_BINARY);
62e76326 158
c4aefe96 159#endif
62e76326 160
8667b856 161 scanned_count = cacheIndexScan(idx, fname, file);
162
163 fclose(file);
62e76326 164
8667b856 165 return scanned_count;
166}
167
168static void
1afe05c5 169cacheIndexInitReport(CacheIndex * idx)
8667b856 170{
171 assert(idx);
172 fprintf(stderr, "%s: bad swap_add: %d\n",
62e76326 173 idx->name, idx->bad_add_count);
1afe05c5 174 fprintf(stderr, "%s: bad swap_del: %d\n",
62e76326 175 idx->name, idx->bad_del_count);
1afe05c5 176 fprintf(stderr, "%s: scanned lines: %d\n",
62e76326 177 idx->name, idx->scanned_count);
8667b856 178}
179
180static int
1afe05c5 181cacheIndexScan(CacheIndex * idx, const char *fname, FILE * file)
8667b856 182{
183 int count = 0;
51ee7c82 184 StoreSwapLogData s;
8667b856 185 fprintf(stderr, "%s scanning\n", fname);
62e76326 186
8667b856 187 while (fread(&s, sizeof(s), 1, file) == 1) {
62e76326 188 count++;
189 idx->scanned_count++;
190 /* if (s.op <= SWAP_LOG_NOP || s.op >= SWAP_LOG_MAX)
191 * continue; */
192
193 if (s.op == SWAP_LOG_ADD) {
194 CacheEntry *olde = (CacheEntry *) hash_lookup(idx->hash, s.key);
195
196 if (olde) {
197 idx->bad_add_count++;
198 } else {
199 CacheEntry *e = cacheEntryCreate(&s);
200 hash_join(idx->hash, &e->hash);
201 idx->count++;
202 }
203 } else if (s.op == SWAP_LOG_DEL) {
204 CacheEntry *olde = (CacheEntry *) hash_lookup(idx->hash, s.key);
205
206 if (!olde)
207 idx->bad_del_count++;
208 else {
209 assert(idx->count);
210 hash_remove_link(idx->hash, (hash_link *) olde);
211 cacheEntryDestroy(olde);
212 idx->count--;
213 }
214 } else {
215 fprintf(stderr, "%s:%d: unknown swap log action\n", fname, count);
216 exit(-3);
217 }
8667b856 218 }
62e76326 219
1afe05c5 220 fprintf(stderr, "%s:%d: scanned (size: %d bytes)\n",
62e76326 221 fname, count, (int) (count * sizeof(CacheEntry)));
8667b856 222 return count;
223}
224
225static void
1afe05c5 226cacheIndexCmpReport(CacheIndex * idx, int shared_count)
8667b856 227{
228 assert(idx && shared_count <= idx->count);
229
f97c9706 230 printf("%s:\t %7d = %7d + %7d (%7.2f%% + %7.2f%%)\n",
62e76326 231 idx->name,
232 idx->count,
233 idx->count - shared_count,
234 shared_count,
235 xpercent(idx->count - shared_count, idx->count),
236 xpercent(shared_count, idx->count));
8667b856 237}
238
239static void
1afe05c5 240cacheIndexCmp(CacheIndex * idx1, CacheIndex * idx2)
8667b856 241{
242 int shared_count = 0;
681e7924 243 int hashed_count = 0;
8667b856 244 hash_link *hashr = NULL;
245 CacheIndex *small_idx = idx1;
246 CacheIndex *large_idx = idx2;
247 assert(idx1 && idx2);
248
249 /* check our guess */
62e76326 250
8667b856 251 if (idx1->count > idx2->count) {
62e76326 252 small_idx = idx2;
253 large_idx = idx1;
8667b856 254 }
62e76326 255
8667b856 256 /* find shared_count */
0f6bebac 257 hash_first(small_idx->hash);
62e76326 258
0f6bebac 259 for (hashr = hash_next(small_idx->hash)) {
62e76326 260 hashed_count++;
261
262 if (hash_lookup(large_idx->hash, hashr->key))
263 shared_count++;
8667b856 264 }
62e76326 265
681e7924 266 assert(hashed_count == small_idx->count);
8667b856 267
268 cacheIndexCmpReport(idx1, shared_count);
269 cacheIndexCmpReport(idx2, shared_count);
270}
271
272
273static int
274usage(const char *prg_name)
275{
276 fprintf(stderr, "usage: %s <label1>: <swap_state>... <label2>: <swap_state>...\n",
62e76326 277 prg_name);
8667b856 278 return -1;
279}
280
281int
282main(int argc, char *argv[])
283{
284 CacheIndex *CacheIdx[2];
285 CacheIndex *idx = NULL;
286 int idxCount = 0;
287 int i;
288
289 if (argc < 5)
62e76326 290 return usage(argv[0]);
8667b856 291
292 for (i = 1; i < argc; ++i) {
62e76326 293 const int len = strlen(argv[i]);
294
295 if (!len)
296 return usage(argv[0]);
297
298 if (argv[i][len - 1] == ':') {
299 idxCount++;
300
301 if (len < 2 || idxCount > 2)
302 return usage(argv[0]);
303
304 idx = cacheIndexCreate(argv[i]);
305
306 CacheIdx[idxCount - 1] = idx;
307 } else {
308 if (!idx)
309 return usage(argv[0]);
310
311 cacheIndexAddLog(idx, argv[i]);
312 }
8667b856 313 }
314
315 if (idxCount != 2)
62e76326 316 return usage(argv[0]);
8667b856 317
318 cacheIndexInitReport(CacheIdx[0]);
62e76326 319
8667b856 320 cacheIndexInitReport(CacheIdx[1]);
321
322 cacheIndexCmp(CacheIdx[0], CacheIdx[1]);
323
324 cacheIndexDestroy(CacheIdx[0]);
62e76326 325
8667b856 326 cacheIndexDestroy(CacheIdx[1]);
327
328 return 1;
329}