]> git.ipfire.org Git - thirdparty/squid.git/blame - src/cache_diff.cc
- Updated dependent list for cache_diff
[thirdparty/squid.git] / src / cache_diff.cc
CommitLineData
8667b856 1/*
94faad3e 2 * $Id: cache_diff.cc,v 1.2 1998/03/29 20:18:46 rousskov Exp $
8667b856 3 *
4 * AUTHOR: Alex Rousskov
5 *
6 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
7 * --------------------------------------------------------
8 *
9 * Squid is the result of efforts by numerous individuals from the
10 * Internet community. Development is led by Duane Wessels of the
11 * National Laboratory for Applied Network Research and funded by
12 * the National Science Foundation.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30/*
31 * Computes the difference between the contents of two caches
32 * using swap logs
33 * Reports the percentage of common files and other stats
34 */
35
36#include "squid.h"
37
38typedef struct {
39 const char *name;
40 hash_table *hash;
41 int count; /* #currently cached entries */
42 int scanned_count; /* #scanned entries */
43 int bad_add_count; /* #duplicate adds */
44 int bad_del_count; /* #dels with no prior add */
45} CacheIndex;
46
47
48typedef struct _CacheEntry {
49 const cache_key *key;
50 struct _CacheEntry *next;
51 storeSwapLogData s;
52} CacheEntry;
53
54
55/* copied from url.c */
56const char *RequestMethodStr[] =
57{
58 "NONE",
59 "GET",
60 "POST",
61 "PUT",
62 "HEAD",
63 "CONNECT",
64 "TRACE",
65 "PURGE"
66};
67
68
69static int cacheIndexScan(CacheIndex *idx, const char *fname, FILE *file);
70
71
72static CacheEntry *
73cacheEntryCreate(const storeSwapLogData *s)
74{
75 CacheEntry *e = xcalloc(1, sizeof(CacheEntry));
76 assert(s);
77 e->s = *s;
78 e->key = &e->s.key[0];
79 return e;
80}
81
82static void
83cacheEntryDestroy(CacheEntry *e)
84{
85 assert(e);
86 xfree(e);
87}
88
89static CacheIndex *
90cacheIndexCreate(const char *name)
91{
92 CacheIndex *idx;
93 if (!name || !strlen(name))
94 return NULL;
95
96 idx = xcalloc(1, sizeof(CacheIndex));
97 idx->name = name;
98 idx->hash = hash_create(storeKeyHashCmp, 2e6, storeKeyHashHash);
99
100 return idx;
101}
102
103static void
104cacheIndexDestroy(CacheIndex *idx)
105{
106 hash_link *hashr = NULL;
107 if (idx) {
108 /* destroy hash list contents */
109 for (hashr = hash_first(idx->hash); hashr; hashr = hash_next(idx->hash)) {
110 hash_remove_link(idx->hash, hashr);
111 cacheEntryDestroy((CacheEntry*)hashr);
112 }
113 /* destroy the hash table itself */
114 hashFreeMemory(idx->hash);
115 xfree(idx);
116 }
117}
118
119static int
120cacheIndexAddLog(CacheIndex *idx, const char *fname)
121{
122 FILE *file;
123 int scanned_count = 0;
124 assert(idx);
125 assert(fname && strlen(fname));
126
127 file = fopen(fname, "r");
128 if (!file) {
129 fprintf(stderr, "cannot open %s: %s\n", fname, strerror(errno));
130 return 0;
131 }
132
133 scanned_count = cacheIndexScan(idx, fname, file);
134
135 fclose(file);
136 return scanned_count;
137}
138
139static void
140cacheIndexInitReport(CacheIndex *idx)
141{
142 assert(idx);
143 fprintf(stderr, "%s: bad swap_add: %d\n",
144 idx->name, idx->bad_add_count);
145 fprintf(stderr, "%s: bad swap_del: %d\n",
146 idx->name, idx->bad_del_count);
147 fprintf(stderr, "%s: scanned lines: %d\n",
148 idx->name, idx->scanned_count);
149}
150
151static int
152cacheIndexScan(CacheIndex *idx, const char *fname, FILE *file)
153{
154 int count = 0;
155 storeSwapLogData s;
156 fprintf(stderr, "%s scanning\n", fname);
157 while (fread(&s, sizeof(s), 1, file) == 1) {
158 count++;
159 idx->scanned_count++;
160 /* if (s.op <= SWAP_LOG_NOP || s.op >= SWAP_LOG_MAX)
161 continue; */
162 if (s.op == SWAP_LOG_ADD) {
163 CacheEntry *olde = (CacheEntry *) hash_lookup(idx->hash, s.key);
164 if (olde) {
165 idx->bad_add_count++;
166 } else {
167 CacheEntry *e = cacheEntryCreate(&s);
168 hash_join(idx->hash, (hash_link*) e);
169 idx->count++;
170 }
171 } else
172 if (s.op == SWAP_LOG_DEL) {
173 CacheEntry *olde = (CacheEntry *) hash_lookup(idx->hash, s.key);
174 if (!olde)
175 idx->bad_del_count++;
176 else {
94faad3e 177 hash_remove_link(idx->hash, (hash_link*) olde);
8667b856 178 }
179 } else {
180 fprintf(stderr, "%s:%d: unknown swap log action\n", fname, count);
181 exit(-3);
182 }
183 }
184 fprintf(stderr, "%s:%d: scanned (size: %d bytes)\n",
185 fname, count, count*sizeof(CacheEntry));
186 return count;
187}
188
189static void
190cacheIndexCmpReport(CacheIndex *idx, int shared_count)
191{
192 assert(idx && shared_count <= idx->count);
193
194 printf("%s:\t %7d %7.2f%% + %7.2f%%\n",
195 idx->name,
196 idx->count,
197 xpercent(idx->count-shared_count, idx->count),
198 xpercent(shared_count, idx->count));
199}
200
201static void
202cacheIndexCmp(CacheIndex *idx1, CacheIndex *idx2)
203{
204 int shared_count = 0;
205 hash_link *hashr = NULL;
206 CacheIndex *small_idx = idx1;
207 CacheIndex *large_idx = idx2;
208 assert(idx1 && idx2);
209
210 /* check our guess */
211 if (idx1->count > idx2->count) {
212 small_idx = idx2;
213 large_idx = idx1;
214 }
215 /* find shared_count */
216 for (hashr = hash_first(small_idx->hash); hashr; hashr = hash_next(small_idx->hash)) {
217 if (hash_lookup(large_idx->hash, hashr->key))
218 shared_count++;
219 }
220
221 cacheIndexCmpReport(idx1, shared_count);
222 cacheIndexCmpReport(idx2, shared_count);
223}
224
225
226static int
227usage(const char *prg_name)
228{
229 fprintf(stderr, "usage: %s <label1>: <swap_state>... <label2>: <swap_state>...\n",
230 prg_name);
231 return -1;
232}
233
234int
235main(int argc, char *argv[])
236{
237 CacheIndex *CacheIdx[2];
238 CacheIndex *idx = NULL;
239 int idxCount = 0;
240 int i;
241
242 if (argc < 5)
243 return usage(argv[0]);
244
245 for (i = 1; i < argc; ++i) {
246 const int len = strlen(argv[i]);
247 if (!len)
248 return usage(argv[0]);
249 if (argv[i][len-1] == ':') {
250 idxCount++;
251 if (len < 2 || idxCount > 2)
252 return usage(argv[0]);
253 idx = cacheIndexCreate(argv[i]);
254 CacheIdx[idxCount-1] = idx;
255 } else {
256 if (!idx)
257 return usage(argv[0]);
258 cacheIndexAddLog(idx, argv[i]);
259 }
260 }
261
262 if (idxCount != 2)
263 return usage(argv[0]);
264
265 cacheIndexInitReport(CacheIdx[0]);
266 cacheIndexInitReport(CacheIdx[1]);
267
268 cacheIndexCmp(CacheIdx[0], CacheIdx[1]);
269
270 cacheIndexDestroy(CacheIdx[0]);
271 cacheIndexDestroy(CacheIdx[1]);
272
273 return 1;
274}