cache_diff.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:7k
源码类别:

代理服务器

开发平台:

Unix_Linux

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