cache_diff.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /*
10  * Computes the difference between the contents of two caches
11  * using swap logs
12  * Reports the percentage of common files and other stats
13  */
14 
15 #include "squid.h"
16 #include <cerrno>
17 
18 typedef struct {
19  const char *name;
21  int count; /* #currently cached entries */
22  int scanned_count; /* #scanned entries */
23  int bad_add_count; /* #duplicate adds */
24  int bad_del_count; /* #dels with no prior add */
25 } CacheIndex;
26 
27 typedef struct _CacheEntry {
28  const cache_key *key;
29 
30  struct _CacheEntry *next;
31  /* StoreSwapLogData s; */
33 } CacheEntry;
34 
35 static int cacheIndexScan(CacheIndex * idx, const char *fname, FILE * file);
36 
37 static CacheEntry *
39 {
40  CacheEntry *e = xcalloc(1, sizeof(CacheEntry));
41  assert(s);
42  /* e->s = *s; */
43  memcpy(e->key_arr, s->key, SQUID_MD5_DIGEST_LENGTH);
44  e->key = &e->key_arr[0];
45  return e;
46 }
47 
48 static void
50 {
51  assert(e);
52  xfree(e);
53 }
54 
55 static CacheIndex *
56 cacheIndexCreate(const char *name)
57 {
58  CacheIndex *idx;
59 
60  if (!name || !strlen(name))
61  return NULL;
62 
63  idx = xcalloc(1, sizeof(CacheIndex));
64 
65  idx->name = name;
66 
68 
69  return idx;
70 }
71 
72 static void
74 {
75  hash_link *hashr = NULL;
76 
77  if (idx) {
78  /* destroy hash list contents */
79  hash_first(idx->hash);
80 
81  while (hashr = hash_next(idx->hash)) {
82  hash_remove_link(idx->hash, hashr);
83  cacheEntryDestroy((CacheEntry *) hashr);
84  }
85 
86  /* destroy the hash table itself */
87  hashFreeMemory(idx->hash);
88 
89  xfree(idx);
90  }
91 }
92 
93 static int
94 cacheIndexAddLog(CacheIndex * idx, const char *fname)
95 {
96  FILE *file;
97  int scanned_count = 0;
98  assert(idx);
99  assert(fname && strlen(fname));
100 
101  file = fopen(fname, "r");
102 
103  if (!file) {
104  fprintf(stderr, "cannot open %s: %s\n", fname, strerror(errno));
105  return 0;
106  }
107 
108 #if _SQUID_WINDOWS_
109  setmode(fileno(file), O_BINARY);
110 #endif
111 
112  scanned_count = cacheIndexScan(idx, fname, file);
113 
114  fclose(file);
115 
116  return scanned_count;
117 }
118 
119 static void
121 {
122  assert(idx);
123  fprintf(stderr, "%s: bad swap_add: %d\n",
124  idx->name, idx->bad_add_count);
125  fprintf(stderr, "%s: bad swap_del: %d\n",
126  idx->name, idx->bad_del_count);
127  fprintf(stderr, "%s: scanned lines: %d\n",
128  idx->name, idx->scanned_count);
129 }
130 
131 static int
132 cacheIndexScan(CacheIndex * idx, const char *fname, FILE * file)
133 {
134  int count = 0;
136  fprintf(stderr, "%s scanning\n", fname);
137 
138  while (fread(&s, sizeof(s), 1, file) == 1) {
139  ++count;
140  ++ idx->scanned_count;
141  /* if (!s.sane())
142  * continue; */
143 
144  if (s.op == SWAP_LOG_ADD) {
145  CacheEntry *olde = (CacheEntry *) hash_lookup(idx->hash, s.key);
146 
147  if (olde) {
148  ++ idx->bad_add_count;
149  } else {
150  CacheEntry *e = cacheEntryCreate(&s);
151  hash_join(idx->hash, &e->hash);
152  ++ idx->count;
153  }
154  } else if (s.op == SWAP_LOG_DEL) {
155  CacheEntry *olde = (CacheEntry *) hash_lookup(idx->hash, s.key);
156 
157  if (!olde)
158  ++ idx->bad_del_count;
159  else {
160  assert(idx->count);
161  hash_remove_link(idx->hash, (hash_link *) olde);
162  cacheEntryDestroy(olde);
163  -- idx->count;
164  }
165  } else {
166  fprintf(stderr, "%s:%d: unknown swap log action\n", fname, count);
167  exit(-3);
168  }
169  }
170 
171  fprintf(stderr, "%s:%d: scanned (size: %d bytes)\n",
172  fname, count, (int) (count * sizeof(CacheEntry)));
173  return count;
174 }
175 
176 static void
177 cacheIndexCmpReport(CacheIndex * idx, int shared_count)
178 {
179  assert(idx && shared_count <= idx->count);
180 
181  printf("%s:\t %7d = %7d + %7d (%7.2f%% + %7.2f%%)\n",
182  idx->name,
183  idx->count,
184  idx->count - shared_count,
185  shared_count,
186  xpercent(idx->count - shared_count, idx->count),
187  xpercent(shared_count, idx->count));
188 }
189 
190 static void
192 {
193  int shared_count = 0;
194  int hashed_count = 0;
195  hash_link *hashr = NULL;
196  CacheIndex *small_idx = idx1;
197  CacheIndex *large_idx = idx2;
198  assert(idx1 && idx2);
199 
200  /* check our guess */
201 
202  if (idx1->count > idx2->count) {
203  small_idx = idx2;
204  large_idx = idx1;
205  }
206 
207  /* find shared_count */
208  hash_first(small_idx->hash);
209 
210  for (hashr = hash_next(small_idx->hash)) {
211  ++hashed_count;
212 
213  if (hash_lookup(large_idx->hash, hashr->key))
214  ++shared_count;
215  }
216 
217  assert(hashed_count == small_idx->count);
218 
219  cacheIndexCmpReport(idx1, shared_count);
220  cacheIndexCmpReport(idx2, shared_count);
221 }
222 
223 static int
224 usage(const char *prg_name)
225 {
226  fprintf(stderr, "usage: %s <label1>: <swap_state>... <label2>: <swap_state>...\n",
227  prg_name);
228  return EXIT_FAILURE;
229 }
230 
231 int
232 main(int argc, char *argv[])
233 {
234  CacheIndex *CacheIdx[2];
235  CacheIndex *idx = NULL;
236  int idxCount = 0;
237  int i;
238 
239  if (argc < 5)
240  return usage(argv[0]);
241 
242  for (i = 1; i < argc; ++i) {
243  const int len = strlen(argv[i]);
244 
245  if (!len)
246  return usage(argv[0]);
247 
248  if (argv[i][len - 1] == ':') {
249  ++idxCount;
250 
251  if (len < 2 || idxCount > 2)
252  return usage(argv[0]);
253 
254  idx = cacheIndexCreate(argv[i]);
255 
256  CacheIdx[idxCount - 1] = idx;
257  } else {
258  if (!idx)
259  return usage(argv[0]);
260 
261  cacheIndexAddLog(idx, argv[i]);
262  }
263  }
264 
265  if (idxCount != 2)
266  return usage(argv[0]);
267 
268  cacheIndexInitReport(CacheIdx[0]);
269 
270  cacheIndexInitReport(CacheIdx[1]);
271 
272  cacheIndexCmp(CacheIdx[0], CacheIdx[1]);
273 
274  cacheIndexDestroy(CacheIdx[0]);
275 
276  cacheIndexDestroy(CacheIdx[1]);
277 
278  return EXIT_FAILURE;
279 }
280 
struct _CacheEntry * next
Definition: cache_diff.cc:30
#define assert(EX)
Definition: assert.h:17
SQUIDCEXTERN void hash_first(hash_table *)
Definition: hash.cc:176
char * strerror(int ern)
Definition: strerror.c:22
const char * name
Definition: cache_diff.cc:19
const cache_key * key
Definition: cache_diff.cc:28
static void cacheIndexDestroy(CacheIndex *idx)
Definition: cache_diff.cc:73
SQUIDCEXTERN void hashFreeMemory(hash_table *)
Definition: hash.cc:272
unsigned char key_arr[SQUID_MD5_DIGEST_LENGTH]
Definition: cache_diff.cc:32
SQUIDCEXTERN double xpercent(double part, double whole)
Definition: util.c:54
unsigned char cache_key
Store key.
Definition: forward.h:29
#define xcalloc
Definition: membanger.c:57
int i
Definition: membanger.c:49
HASHHASH storeKeyHashHash
static CacheIndex * cacheIndexCreate(const char *name)
Definition: cache_diff.cc:56
int main(int argc, char *argv[])
Definition: cache_diff.cc:232
SQUIDCEXTERN void hash_join(hash_table *, hash_link *)
Definition: hash.cc:132
static int cacheIndexAddLog(CacheIndex *idx, const char *fname)
Definition: cache_diff.cc:94
static void cacheEntryDestroy(CacheEntry *e)
Definition: cache_diff.cc:49
int bad_del_count
Definition: cache_diff.cc:24
static int cacheIndexScan(CacheIndex *idx, const char *fname, FILE *file)
Definition: cache_diff.cc:132
unsigned char key[SQUID_MD5_DIGEST_LENGTH]
int scanned_count
Definition: cache_diff.cc:22
#define SQUID_MD5_DIGEST_LENGTH
Definition: md5.h:66
HASHCMP storeKeyHashCmp
SQUIDCEXTERN hash_link * hash_lookup(hash_table *, const void *)
Definition: hash.cc:147
struct _CacheEntry CacheEntry
SQUIDCEXTERN hash_table * hash_create(HASHCMP *, int, HASHHASH *)
Definition: hash.cc:109
static int usage(const char *prg_name)
Definition: cache_diff.cc:224
int unsigned int const char *desc STUB void int len
Definition: stub_fd.cc:20
static void cacheIndexCmpReport(CacheIndex *idx, int shared_count)
Definition: cache_diff.cc:177
SQUIDCEXTERN hash_link * hash_next(hash_table *)
Definition: hash.cc:192
hash_table * hash
Definition: cache_diff.cc:20
static CacheEntry * cacheEntryCreate(const StoreSwapLogData *s)
Definition: cache_diff.cc:38
SQUIDCEXTERN void hash_remove_link(hash_table *, hash_link *)
Definition: hash.cc:224
static void cacheIndexInitReport(CacheIndex *idx)
Definition: cache_diff.cc:120
#define O_BINARY
Definition: defines.h:204
static void cacheIndexCmp(CacheIndex *idx1, CacheIndex *idx2)
Definition: cache_diff.cc:191
#define xfree
#define NULL
Definition: types.h:166
int bad_add_count
Definition: cache_diff.cc:23

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors