]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
- Added cache_diff.c, a stand alone program that
authorrousskov <>
Mon, 30 Mar 1998 03:02:43 +0000 (03:02 +0000)
committerrousskov <>
Mon, 30 Mar 1998 03:02:43 +0000 (03:02 +0000)
    - Computes the difference between the contents of two caches using
      swap logs
    - Reports the percentage of common files and other stats

src/Makefile.in
src/cache_diff.cc [new file with mode: 0644]

index 7f17d8aca49a54a815db70c16d0e206bfae84f23..1b439ed0b7dd5428c024f2a2b2fa0acf07e99d92 100644 (file)
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.in,v 1.137 1998/03/28 04:41:15 wessels Exp $
+#  $Id: Makefile.in,v 1.138 1998/03/29 20:02:44 rousskov Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
@@ -60,6 +60,7 @@ SQUID_LIBS    = -L../lib $(CRYPTLIB) $(REGEXLIB) @SQUID_PTHREAD_LIB@ \
 CLIENT_LIBS    = -L../lib -lmiscutil $(XTRA_LIBS)
 DNSSERVER_LIBS = -L../lib -lmiscutil $(XTRA_LIBS)
 PINGER_LIBS    = -L../lib -lmiscutil $(XTRA_LIBS)
+CACHE_DIFF_LIBS = -L../lib -lmiscutil $(XTRA_LIBS)
 
 PROGS           = squid client
 UTILS           = dnsserver unlinkd
@@ -198,6 +199,9 @@ unlinkd: unlinkd-daemon.o
 unlinkd-daemon.o: unlinkd.c
        $(CC) -c $(CFLAGS) -DUNLINK_DAEMON $(srcdir)/unlinkd.c -o $@
 
+cache_diff: cache_diff.o
+       $(CC) -o $@ $(LDFLAGS) $@.o debug.o globals.o hash.o store_key_md5.o $(CACHE_DIFF_LIBS)
+
 cache_cf.o: cf_parser.c
 
 squid.conf cf_parser.c: cf.data cf_gen
diff --git a/src/cache_diff.cc b/src/cache_diff.cc
new file mode 100644 (file)
index 0000000..c191b74
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * $Id: cache_diff.cc,v 1.1 1998/03/29 20:02:43 rousskov 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.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, 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;
+} 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;
+    e->key = &e->s.key[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 */
+       for (hashr = hash_first(idx->hash); hashr; 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: %s\n", 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:  %d\n",
+       idx->name, idx->bad_add_count);
+    fprintf(stderr, "%s: bad swap_del:  %d\n", 
+       idx->name, idx->bad_del_count);
+    fprintf(stderr, "%s: scanned lines: %d\n", 
+       idx->name, idx->scanned_count);
+}
+
+static int
+cacheIndexScan(CacheIndex *idx, const char *fname, FILE *file)
+{
+    int count = 0;
+    storeSwapLogData s;
+    fprintf(stderr, "%s scanning\n", 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 {
+               hash_delete_link(idx->hash, (hash_link*) olde);
+           }
+       } else {
+           fprintf(stderr, "%s:%d: unknown swap log action\n", fname, count);
+           exit(-3);
+       }
+    }
+    fprintf(stderr, "%s:%d: scanned (size: %d bytes)\n", 
+       fname, count, count*sizeof(CacheEntry));
+    return count;
+}
+
+static void
+cacheIndexCmpReport(CacheIndex *idx, int shared_count)
+{
+    assert(idx && shared_count <= idx->count);
+
+    printf("%s:\t %7d %7.2f%% + %7.2f%%\n", 
+       idx->name, 
+       idx->count, 
+       xpercent(idx->count-shared_count, idx->count),
+       xpercent(shared_count, idx->count));
+}
+
+static void
+cacheIndexCmp(CacheIndex *idx1, CacheIndex *idx2)
+{
+    int shared_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 */
+    for (hashr = hash_first(small_idx->hash); hashr; hashr = hash_next(small_idx->hash)) {
+       if (hash_lookup(large_idx->hash, hashr->key))
+           shared_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;
+}