cache_diff.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:7k
- /*
- * $Id: cache_diff.c,v 1.10 1998/07/22 20:37:02 wessels Exp $
- *
- * AUTHOR: Alex Rousskov
- *
- * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
- * ----------------------------------------------------------
- *
- * Squid is the result of efforts by numerous individuals from the
- * Internet community. Development is led by Duane Wessels of the
- * National Laboratory for Applied Network Research and funded by the
- * National Science Foundation. Squid is Copyrighted (C) 1998 by
- * Duane Wessels and the University of California San Diego. Please
- * see the COPYRIGHT file for full details. Squid incorporates
- * software developed and/or copyrighted by other sources. Please see
- * the CREDITS file for full details.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
- *
- */
- /*
- * Computes the difference between the contents of two caches
- * using swap logs
- * Reports the percentage of common files and other stats
- */
- #include "squid.h"
- typedef struct {
- const char *name;
- hash_table *hash;
- int count; /* #currently cached entries */
- int scanned_count; /* #scanned entries */
- int bad_add_count; /* #duplicate adds */
- int bad_del_count; /* #dels with no prior add */
- } CacheIndex;
- typedef struct _CacheEntry {
- const cache_key *key;
- struct _CacheEntry *next;
- /* storeSwapLogData s; */
- unsigned char key_arr[MD5_DIGEST_CHARS];
- } CacheEntry;
- /* copied from url.c */
- const char *RequestMethodStr[] =
- {
- "NONE",
- "GET",
- "POST",
- "PUT",
- "HEAD",
- "CONNECT",
- "TRACE",
- "PURGE"
- };
- static int cacheIndexScan(CacheIndex * idx, const char *fname, FILE * file);
- static CacheEntry *
- cacheEntryCreate(const storeSwapLogData * s)
- {
- CacheEntry *e = xcalloc(1, sizeof(CacheEntry));
- assert(s);
- /* e->s = *s; */
- xmemcpy(e->key_arr, s->key, MD5_DIGEST_CHARS);
- e->key = &e->key_arr[0];
- return e;
- }
- static void
- cacheEntryDestroy(CacheEntry * e)
- {
- assert(e);
- xfree(e);
- }
- static CacheIndex *
- cacheIndexCreate(const char *name)
- {
- CacheIndex *idx;
- if (!name || !strlen(name))
- return NULL;
- idx = xcalloc(1, sizeof(CacheIndex));
- idx->name = name;
- idx->hash = hash_create(storeKeyHashCmp, 2e6, storeKeyHashHash);
- return idx;
- }
- static void
- cacheIndexDestroy(CacheIndex * idx)
- {
- hash_link *hashr = NULL;
- if (idx) {
- /* destroy hash list contents */
- hash_first(idx->hash);
- while (hashr = hash_next(idx->hash)) {
- hash_remove_link(idx->hash, hashr);
- cacheEntryDestroy((CacheEntry *) hashr);
- }
- /* destroy the hash table itself */
- hashFreeMemory(idx->hash);
- xfree(idx);
- }
- }
- static int
- cacheIndexAddLog(CacheIndex * idx, const char *fname)
- {
- FILE *file;
- int scanned_count = 0;
- assert(idx);
- assert(fname && strlen(fname));
- file = fopen(fname, "r");
- if (!file) {
- fprintf(stderr, "cannot open %s: %sn", fname, strerror(errno));
- return 0;
- }
- scanned_count = cacheIndexScan(idx, fname, file);
- fclose(file);
- return scanned_count;
- }
- static void
- cacheIndexInitReport(CacheIndex * idx)
- {
- assert(idx);
- fprintf(stderr, "%s: bad swap_add: %dn",
- idx->name, idx->bad_add_count);
- fprintf(stderr, "%s: bad swap_del: %dn",
- idx->name, idx->bad_del_count);
- fprintf(stderr, "%s: scanned lines: %dn",
- idx->name, idx->scanned_count);
- }
- static int
- cacheIndexScan(CacheIndex * idx, const char *fname, FILE * file)
- {
- int count = 0;
- storeSwapLogData s;
- fprintf(stderr, "%s scanningn", fname);
- while (fread(&s, sizeof(s), 1, file) == 1) {
- count++;
- idx->scanned_count++;
- /* if (s.op <= SWAP_LOG_NOP || s.op >= SWAP_LOG_MAX)
- * continue; */
- if (s.op == SWAP_LOG_ADD) {
- CacheEntry *olde = (CacheEntry *) hash_lookup(idx->hash, s.key);
- if (olde) {
- idx->bad_add_count++;
- } else {
- CacheEntry *e = cacheEntryCreate(&s);
- hash_join(idx->hash, (hash_link *) e);
- idx->count++;
- }
- } else if (s.op == SWAP_LOG_DEL) {
- CacheEntry *olde = (CacheEntry *) hash_lookup(idx->hash, s.key);
- if (!olde)
- idx->bad_del_count++;
- else {
- assert(idx->count);
- hash_remove_link(idx->hash, (hash_link *) olde);
- cacheEntryDestroy(olde);
- idx->count--;
- }
- } else {
- fprintf(stderr, "%s:%d: unknown swap log actionn", fname, count);
- exit(-3);
- }
- }
- fprintf(stderr, "%s:%d: scanned (size: %d bytes)n",
- fname, count, (int) (count * sizeof(CacheEntry)));
- return count;
- }
- static void
- cacheIndexCmpReport(CacheIndex * idx, int shared_count)
- {
- assert(idx && shared_count <= idx->count);
- printf("%s:t %7d = %7d + %7d (%7.2f%% + %7.2f%%)n",
- idx->name,
- idx->count,
- idx->count - shared_count,
- shared_count,
- xpercent(idx->count - shared_count, idx->count),
- xpercent(shared_count, idx->count));
- }
- static void
- cacheIndexCmp(CacheIndex * idx1, CacheIndex * idx2)
- {
- int shared_count = 0;
- int hashed_count = 0;
- hash_link *hashr = NULL;
- CacheIndex *small_idx = idx1;
- CacheIndex *large_idx = idx2;
- assert(idx1 && idx2);
- /* check our guess */
- if (idx1->count > idx2->count) {
- small_idx = idx2;
- large_idx = idx1;
- }
- /* find shared_count */
- hash_first(small_idx->hash);
- for (hashr = hash_next(small_idx->hash)) {
- hashed_count++;
- if (hash_lookup(large_idx->hash, hashr->key))
- shared_count++;
- }
- assert(hashed_count == small_idx->count);
- cacheIndexCmpReport(idx1, shared_count);
- cacheIndexCmpReport(idx2, shared_count);
- }
- static int
- usage(const char *prg_name)
- {
- fprintf(stderr, "usage: %s <label1>: <swap_state>... <label2>: <swap_state>...n",
- prg_name);
- return -1;
- }
- int
- main(int argc, char *argv[])
- {
- CacheIndex *CacheIdx[2];
- CacheIndex *idx = NULL;
- int idxCount = 0;
- int i;
- if (argc < 5)
- return usage(argv[0]);
- for (i = 1; i < argc; ++i) {
- const int len = strlen(argv[i]);
- if (!len)
- return usage(argv[0]);
- if (argv[i][len - 1] == ':') {
- idxCount++;
- if (len < 2 || idxCount > 2)
- return usage(argv[0]);
- idx = cacheIndexCreate(argv[i]);
- CacheIdx[idxCount - 1] = idx;
- } else {
- if (!idx)
- return usage(argv[0]);
- cacheIndexAddLog(idx, argv[i]);
- }
- }
- if (idxCount != 2)
- return usage(argv[0]);
- cacheIndexInitReport(CacheIdx[0]);
- cacheIndexInitReport(CacheIdx[1]);
- cacheIndexCmp(CacheIdx[0], CacheIdx[1]);
- cacheIndexDestroy(CacheIdx[0]);
- cacheIndexDestroy(CacheIdx[1]);
- return 1;
- }