]> git.ipfire.org Git - thirdparty/squid.git/blame - src/test_cache_digest.cc
Initial revision.
[thirdparty/squid.git] / src / test_cache_digest.cc
CommitLineData
c411be12 1/*
2 * $Id: test_cache_digest.cc,v 1.1 1998/03/30 20:42:42 rousskov Exp $
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 * Test-suite for playing with cache digests
32 */
33
34#include "squid.h"
35
36typedef struct {
37 const char *name;
38 hash_table *hash;
39 CacheDigest *digest;
40 int count; /* #currently cached entries */
41 int scanned_count; /* #scanned entries */
42 int bad_add_count; /* #duplicate adds */
43 int bad_del_count; /* #dels with no prior add */
44} CacheIndex;
45
46
47typedef struct _CacheEntry {
48 const cache_key *key;
49 struct _CacheEntry *next;
50 /* storeSwapLogData s; */
51 unsigned char key_arr[MD5_DIGEST_CHARS];
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 cacheIndexScanCleanPrefix(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 xmemcpy(e->key_arr, s->key, MD5_DIGEST_CHARS);
79 e->key = &e->key_arr[0];
80 return e;
81}
82
83static void
84cacheEntryDestroy(CacheEntry *e)
85{
86 assert(e);
87 xfree(e);
88}
89
90static CacheIndex *
91cacheIndexCreate(const char *name)
92{
93 CacheIndex *idx;
94 if (!name || !strlen(name))
95 return NULL;
96
97 idx = xcalloc(1, sizeof(CacheIndex));
98 idx->name = name;
99 idx->hash = hash_create(storeKeyHashCmp, 2e6, storeKeyHashHash);
100
101 return idx;
102}
103
104static void
105cacheIndexDestroy(CacheIndex *idx)
106{
107 hash_link *hashr = NULL;
108 if (idx) {
109 /* destroy hash list contents */
110 for (hashr = hash_first(idx->hash); hashr; hashr = hash_next(idx->hash)) {
111 hash_remove_link(idx->hash, hashr);
112 cacheEntryDestroy((CacheEntry*)hashr);
113 }
114 /* destroy the hash table itself */
115 hashFreeMemory(idx->hash);
116 if (idx->digest)
117 cacheDigestDestroy(idx->digest);
118 xfree(idx);
119 }
120}
121
122/* makes digest based on currently hashed entries */
123static void
124cacheIndexInitDigest(CacheIndex *idx)
125{
126 hash_link *hashr = NULL;
127 struct timeval t_start, t_end;
128 assert(idx && !idx->digest);
129 fprintf(stderr, "%s: init-ing digest with %d entries\n", idx->name, idx->count);
130 idx->digest = cacheDigestCreate(idx->count); /* no "fat" */
131 gettimeofday(&t_start, NULL);
132 for (hashr = hash_first(idx->hash); hashr; hashr = hash_next(idx->hash)) {
133 cacheDigestAdd(idx->digest, hashr->key);
134 }
135 gettimeofday(&t_end, NULL);
136 assert(idx->digest->count == idx->count);
137 fprintf(stderr, "%s: init-ed digest with %d entries\n",
138 idx->name, idx->digest->count);
139 fprintf(stderr, "%s: init took: %f sec, %f sec/M\n",
140 idx->name,
141 tvSubDsec(t_start, t_end),
142 (double)1e6*tvSubDsec(t_start, t_end)/idx->count);
143}
144
145static int
146cacheIndexAddLog(CacheIndex *idx, const char *fname)
147{
148 FILE *file;
149 int scanned_count = 0;
150 assert(idx);
151 assert(fname && strlen(fname));
152
153 file = fopen(fname, "r");
154 if (!file) {
155 fprintf(stderr, "cannot open %s: %s\n", fname, strerror(errno));
156 return 0;
157 }
158 scanned_count = cacheIndexScanCleanPrefix(idx, fname, file);
159 fclose(file);
160 return scanned_count;
161}
162
163static void
164cacheIndexInitReport(CacheIndex *idx)
165{
166 assert(idx);
167 fprintf(stderr, "%s: bad swap_add: %d\n",
168 idx->name, idx->bad_add_count);
169 fprintf(stderr, "%s: bad swap_del: %d\n",
170 idx->name, idx->bad_del_count);
171 fprintf(stderr, "%s: scanned lines: %d\n",
172 idx->name, idx->scanned_count);
173}
174
175#if 0
176static int
177cacheIndexGetLogEntry(CacheIndex *idx, storeSwapLogData *s)
178{
179 if (!idx->has_log_entry)
180 cacheIndexStepLogEntry();
181 if (idx->has_log_entry) {
182 *s = idx->log_entry_buf;
183 return 1;
184 }
185 return 0;
186}
187
188static int
189cacheIndexStepLogEntry(CacheIndex *idx)
190{
191 if (fread(&idx->log_entry_buf, sizeof(idx->log_entry_buf), 1, idx->log) == 1) {
192 int op = (int) idx->log_entry_buf.op;
193 idx->scanned_count++;
194 idx->has_log_entry = 1;
195 if (op != SWAP_LOG_ADD && op != SWAP_LOG_DEL) {
196 fprintf(stderr, "%s:%d: unknown swap log action %d\n", idx->log_fname, idx->scanned_count, op);
197 exit(-3);
198 }
199 } else
200 idx->has_log_entry = 0;
201}
202
203static int
204cacheIndexScan(CacheIndex *idx, const char *fname, FILE *file)
205{
206 int count = 0;
207 int del_count = 0;
208 storeSwapLogData s;
209 fprintf(stderr, "%s scanning\n", fname);
210 while (fread(&s, sizeof(s), 1, file) == 1) {
211 count++;
212 idx->scanned_count++;
213 if (s.op == SWAP_LOG_ADD) {
214 CacheEntry *olde = (CacheEntry *) hash_lookup(idx->hash, s.key);
215 if (olde) {
216 idx->bad_add_count++;
217 } else {
218 CacheEntry *e = cacheEntryCreate(&s);
219 hash_join(idx->hash, (hash_link*) e);
220 idx->count++;
221 }
222 } else
223 if (s.op == SWAP_LOG_DEL) {
224 CacheEntry *olde = (CacheEntry *) hash_lookup(idx->hash, s.key);
225 if (!olde)
226 idx->bad_del_count++;
227 else {
228 assert(idx->count);
229 hash_remove_link(idx->hash, (hash_link*) olde);
230 cacheEntryDestroy(olde);
231 idx->count--;
232 }
233 del_count++;
234 } else {
235 fprintf(stderr, "%s:%d: unknown swap log action\n", fname, count);
236 exit(-3);
237 }
238 }
239 fprintf(stderr, "%s scanned %d entries, alloc: %d bytes\n",
240 fname, count,
241 (int)(count*sizeof(CacheEntry)));
242 return count;
243}
244#endif
245
246static int
247cacheIndexScanCleanPrefix(CacheIndex *idx, const char *fname, FILE *file)
248{
249 int count = 0;
250 storeSwapLogData s;
251 fprintf(stderr, "%s scanning\n", fname);
252 while (fread(&s, sizeof(s), 1, file) == 1) {
253 count++;
254 idx->scanned_count++;
255 if (s.op == SWAP_LOG_ADD) {
256 CacheEntry *olde = (CacheEntry *) hash_lookup(idx->hash, s.key);
257 if (olde) {
258 idx->bad_add_count++;
259 } else {
260 CacheEntry *e = cacheEntryCreate(&s);
261 hash_join(idx->hash, (hash_link*) e);
262 idx->count++;
263 }
264 } else
265 if (s.op == SWAP_LOG_DEL) {
266 break;
267 } else {
268 fprintf(stderr, "%s:%d: unknown swap log action\n", fname, count);
269 exit(-3);
270 }
271 }
272 fprintf(stderr, "%s scanned %d entries, alloc: %d bytes\n",
273 fname, count,
274 (int)(count*sizeof(CacheEntry)));
275 return count;
276}
277
278static int
279usage(const char *prg_name)
280{
281 fprintf(stderr, "usage: %s <access_log> <swap_state> ...\n",
282 prg_name);
283 return -1;
284}
285
286int
287main(int argc, char *argv[])
288{
289 CacheIndex *they = NULL;
290 int i;
291
292 if (argc < 3)
293 return usage(argv[0]);
294
295 they = cacheIndexCreate("they");
296 for (i = 2; i < argc; ++i) {
297 cacheIndexAddLog(they, argv[i]);
298 }
299 cacheIndexInitDigest(they);
300 cacheIndexInitReport(they);
301
302 cacheIndexDestroy(they);
303
304 return 1;
305}