Disks.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2018 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 /* DEBUG: section 47 Store Directory Routines */
10 
11 #include "squid.h"
12 #include "Debug.h"
13 #include "globals.h"
14 #include "profiler/Profiler.h"
15 #include "SquidConfig.h"
16 #include "Store.h"
17 #include "store/Disk.h"
18 #include "store/Disks.h"
19 #include "swap_log_op.h"
20 #include "util.h" // for tvSubDsec() which should be in SquidTime.h
21 
29 
32 static int64_t
34 {
35  // entry.objectLen() is negative here when we are still STORE_PENDING
36  int64_t minSize = entry.mem_obj->expectedReplySize();
37 
38  // If entry size is unknown, use already accumulated bytes as an estimate.
39  // Controller::accumulateMore() guarantees that there are enough of them.
40  if (minSize < 0)
41  minSize = entry.mem_obj->endOffset();
42 
43  assert(minSize >= 0);
44  minSize += entry.mem_obj->swap_hdr_sz;
45  return minSize;
46 }
47 
53 static int
55 {
56  const int64_t objsize = objectSizeForDirSelection(*e);
57 
58  // Increment the first candidate once per selection (not once per
59  // iteration) to reduce bias when some disk(s) attract more entries.
60  static int firstCandidate = 0;
61  if (++firstCandidate >= Config.cacheSwap.n_configured)
62  firstCandidate = 0;
63 
64  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
65  const int dirn = (firstCandidate + i) % Config.cacheSwap.n_configured;
66  const SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(dirn));
67 
68  int load = 0;
69  if (!sd->canStore(*e, objsize, load))
70  continue;
71 
72  if (load < 0 || load > 1000) {
73  continue;
74  }
75 
76  return dirn;
77  }
78 
79  return -1;
80 }
81 
95 static int
97 {
98  int64_t most_free = 0;
99  int64_t best_objsize = -1;
100  int least_load = INT_MAX;
101  int load;
102  int dirn = -1;
103  int i;
105 
106  const int64_t objsize = objectSizeForDirSelection(*e);
107 
108  for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
109  SD = dynamic_cast<SwapDir *>(INDEXSD(i));
110  SD->flags.selected = false;
111 
112  if (!SD->canStore(*e, objsize, load))
113  continue;
114 
115  if (load < 0 || load > 1000)
116  continue;
117 
118  if (load > least_load)
119  continue;
120 
121  const int64_t cur_free = SD->maxSize() - SD->currentSize();
122 
123  /* If the load is equal, then look in more details */
124  if (load == least_load) {
125  /* best max-size fit */
126  if (best_objsize != -1) {
127  // cache_dir with the smallest max-size gets the known-size object
128  // cache_dir with the largest max-size gets the unknown-size object
129  if ((objsize != -1 && SD->maxObjectSize() > best_objsize) ||
130  (objsize == -1 && SD->maxObjectSize() < best_objsize))
131  continue;
132  }
133 
134  /* most free */
135  if (cur_free < most_free)
136  continue;
137  }
138 
139  least_load = load;
140  best_objsize = SD->maxObjectSize();
141  most_free = cur_free;
142  dirn = i;
143  }
144 
145  if (dirn >= 0)
146  dynamic_cast<SwapDir *>(INDEXSD(dirn))->flags.selected = true;
147 
148  return dirn;
149 }
150 
152  largestMinimumObjectSize(-1),
153  largestMaximumObjectSize(-1),
154  secondLargestMaximumObjectSize(-1)
155 {
156 }
157 
158 SwapDir *
159 Store::Disks::store(int const x) const
160 {
161  return INDEXSD(x);
162 }
163 
164 SwapDir &
166 {
167  SwapDir *sd = INDEXSD(i);
168  assert(sd);
169  return *sd;
170 }
171 
172 int
174 {
175  int result = 0;
176  int j;
177  static int ndir = 0;
178 
179  do {
180  j = 0;
181 
182  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
183  if (ndir >= Config.cacheSwap.n_configured)
184  ndir = ndir % Config.cacheSwap.n_configured;
185 
186  int temp_result = store(ndir)->callback();
187 
188  ++ndir;
189 
190  j += temp_result;
191 
192  result += temp_result;
193 
194  if (j > 100)
195  fatal ("too much io\n");
196  }
197  } while (j > 0);
198 
199  ++ndir;
200 
201  return result;
202 }
203 
204 void
206 {
207  if (Config.cacheSwap.n_configured == 0) {
208  debugs(0, DBG_PARSE_NOTE(DBG_CRITICAL), "No cache_dir stores are configured.");
209  }
210 
211  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
212  if (Dir(i).active())
213  store(i)->create();
214  }
215 }
216 
217 StoreEntry *
219 {
220  if (const int cacheDirs = Config.cacheSwap.n_configured) {
221  // ask each cache_dir until the entry is found; use static starting
222  // point to avoid asking the same subset of disks more often
223  // TODO: coordinate with put() to be able to guess the right disk often
224  static int idx = 0;
225  for (int n = 0; n < cacheDirs; ++n) {
226  idx = (idx + 1) % cacheDirs;
227  SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(idx));
228  if (!sd->active())
229  continue;
230 
231  if (StoreEntry *e = sd->get(key)) {
232  debugs(20, 7, "cache_dir " << idx << " has: " << *e);
233  return e;
234  }
235  }
236  }
237 
238  debugs(20, 6, "none of " << Config.cacheSwap.n_configured <<
239  " cache_dirs have " << storeKeyText(key));
240  return nullptr;
241 }
242 
243 void
245 {
246  if (Config.Store.objectsPerBucket <= 0)
247  fatal("'store_objects_per_bucket' should be larger than 0.");
248 
249  if (Config.Store.avgObjectSize <= 0)
250  fatal("'store_avg_object_size' should be larger than 0.");
251 
252  /* Calculate size of hash table (maximum currently 64k buckets). */
253  /* this is very bogus, its specific to the any Store maintaining an
254  * in-core index, not global */
256  debugs(20, DBG_IMPORTANT, "Swap maxSize " << (Store::Root().maxSize() >> 10) <<
257  " + " << ( Config.memMaxSize >> 10) << " KB, estimated " << buckets << " objects");
258  buckets /= Config.Store.objectsPerBucket;
259  debugs(20, DBG_IMPORTANT, "Target number of buckets: " << buckets);
260  /* ideally the full scan period should be configurable, for the
261  * moment it remains at approximately 24 hours. */
263  debugs(20, DBG_IMPORTANT, "Using " << store_hash_buckets << " Store buckets");
264  debugs(20, DBG_IMPORTANT, "Max Mem size: " << ( Config.memMaxSize >> 10) << " KB" <<
265  (Config.memShared ? " [shared]" : ""));
266  debugs(20, DBG_IMPORTANT, "Max Swap size: " << (Store::Root().maxSize() >> 10) << " KB");
267 
270 
271  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
272  /* this starts a search of the store dirs, loading their
273  * index. under the new Store api this should be
274  * driven by the StoreHashIndex, not by each store.
275  *
276  * That is, the HashIndex should perform a search of each dir it is
277  * indexing to do the hash insertions. The search is then able to
278  * decide 'from-memory', or 'from-clean-log' or 'from-dirty-log' or
279  * 'from-no-log'.
280  *
281  * Step 1: make the store rebuilds use a search internally
282  * Step 2: change the search logic to use the four modes described
283  * above
284  * Step 3: have the hash index walk the searches itself.
285  */
286  if (Dir(i).active())
287  store(i)->init();
288  }
289 
290  if (strcasecmp(Config.store_dir_select_algorithm, "round-robin") == 0) {
292  debugs(47, DBG_IMPORTANT, "Using Round Robin store dir selection");
293  } else {
295  debugs(47, DBG_IMPORTANT, "Using Least Load store dir selection");
296  }
297 }
298 
299 uint64_t
301 {
302  uint64_t result = 0;
303 
304  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
305  if (Dir(i).doReportStat())
306  result += store(i)->maxSize();
307  }
308 
309  return result;
310 }
311 
312 uint64_t
314 {
315  uint64_t result = 0;
316 
317  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
318  if (Dir(i).doReportStat())
319  result += store(i)->minSize();
320  }
321 
322  return result;
323 }
324 
325 uint64_t
327 {
328  uint64_t result = 0;
329 
330  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
331  if (Dir(i).doReportStat())
332  result += store(i)->currentSize();
333  }
334 
335  return result;
336 }
337 
338 uint64_t
340 {
341  uint64_t result = 0;
342 
343  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
344  if (Dir(i).doReportStat())
345  result += store(i)->currentCount();
346  }
347 
348  return result;
349 }
350 
351 int64_t
353 {
354  return largestMaximumObjectSize;
355 }
356 
357 void
359 {
360  largestMinimumObjectSize = -1;
361  largestMaximumObjectSize = -1;
362  secondLargestMaximumObjectSize = -1;
363 
364  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
365  const auto &disk = Dir(i);
366  if (!disk.active())
367  continue;
368 
369  if (disk.minObjectSize() > largestMinimumObjectSize)
370  largestMinimumObjectSize = disk.minObjectSize();
371 
372  const auto diskMaxObjectSize = disk.maxObjectSize();
373  if (diskMaxObjectSize > largestMaximumObjectSize) {
374  if (largestMaximumObjectSize >= 0) // was set
375  secondLargestMaximumObjectSize = largestMaximumObjectSize;
376  largestMaximumObjectSize = diskMaxObjectSize;
377  }
378  }
379 }
380 
381 int64_t
383 {
384  const auto accumulated = entry.mem_obj->availableForSwapOut();
385 
386  /*
387  * Keep accumulating more bytes until the set of disks eligible to accept
388  * the entry becomes stable, and, hence, accumulating more is not going to
389  * affect the cache_dir selection. A stable set is usually reached
390  * immediately (or soon) because most configurations either do not use
391  * cache_dirs with explicit min-size/max-size limits or use the same
392  * max-size limit for all cache_dirs (and low min-size limits).
393  */
394 
395  // Can the set of min-size cache_dirs accepting this entry change?
396  if (accumulated < largestMinimumObjectSize)
397  return largestMinimumObjectSize - accumulated;
398 
399  // Can the set of max-size cache_dirs accepting this entry change
400  // (other than when the entry exceeds the largest maximum; see below)?
401  if (accumulated <= secondLargestMaximumObjectSize)
402  return secondLargestMaximumObjectSize - accumulated + 1;
403 
404  /*
405  * Checking largestMaximumObjectSize instead eliminates the risk of starting
406  * to swap out an entry that later grows too big, but also implies huge
407  * accumulation in most environments. Accumulating huge entries not only
408  * consumes lots of RAM but also creates a burst of doPages() write requests
409  * that overwhelm the disk. To avoid these problems, we take the risk and
410  * allow swap out now. The disk will quit swapping out if the entry
411  * eventually grows too big for its selected cache_dir.
412  */
413  debugs(20, 3, "no: " << accumulated << '>' <<
414  secondLargestMaximumObjectSize << ',' << largestMinimumObjectSize);
415  return 0;
416 }
417 
418 void
420 {
421  // accumulate per-disk cache stats
422  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
423  StoreInfoStats dirStats;
424  store(i)->getStats(dirStats);
425  stats += dirStats;
426  }
427 
428  // common to all disks
430 
431  // memory cache stats are collected in StoreController::getStats(), for now
432 }
433 
434 void
436 {
437  int i;
438 
439  /* Now go through each store, calling its stat routine */
440 
441  for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
442  storeAppendPrintf(&output, "\n");
443  store(i)->stat(output);
444  }
445 }
446 
447 void
449 {
450  e.disk().reference(e);
451 }
452 
453 bool
455 {
456  return e.disk().dereference(e);
457 }
458 
459 void
461 {
462  Must(e);
463  return e->disk().updateHeaders(e);
464 }
465 
466 void
468 {
469  int i;
470  /* walk each fs */
471 
472  for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
473  /* XXX FixMe: This should be done "in parallell" on the different
474  * cache_dirs, not one at a time.
475  */
476  /* call the maintain function .. */
477  store(i)->maintain();
478  }
479 }
480 
481 void
483 {
484  for (int i = 0; i < Config.cacheSwap.n_configured; ++i)
485  store(i)->sync();
486 }
487 
488 void
490  if (e.hasDisk()) {
491  // TODO: move into Fs::Ufs::UFSSwapDir::evictCached()
492  if (!EBIT_TEST(e.flags, KEY_PRIVATE)) {
493  // log before evictCached() below may clear hasDisk()
495  }
496 
497  e.disk().evictCached(e);
498  return;
499  }
500 
501  if (const auto key = e.publicKey())
502  evictIfFound(key);
503 }
504 
505 void
507 {
508  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
509  if (Dir(i).active())
510  Dir(i).evictIfFound(key);
511  }
512 }
513 
514 bool
516 {
517  if (const int cacheDirs = Config.cacheSwap.n_configured) {
518  // ask each cache_dir until the entry is found; use static starting
519  // point to avoid asking the same subset of disks more often
520  // TODO: coordinate with put() to be able to guess the right disk often
521  static int idx = 0;
522  for (int n = 0; n < cacheDirs; ++n) {
523  idx = (idx + 1) % cacheDirs;
524  SwapDir &sd = Dir(idx);
525  if (!sd.active())
526  continue;
527 
528  if (sd.anchorToCache(entry, inSync)) {
529  debugs(20, 3, "cache_dir " << idx << " anchors " << entry);
530  return true;
531  }
532  }
533  }
534 
535  debugs(20, 4, "none of " << Config.cacheSwap.n_configured <<
536  " cache_dirs have " << entry);
537  return false;
538 }
539 
540 bool
542 {
543  return entry.hasDisk() &&
544  Dir(entry.swap_dirn).updateAnchored(entry);
545 }
546 
547 bool
549 {
550  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
551  // A mix is not supported, but we conservatively check every
552  // dir because features like collapsed revalidation should
553  // currently be disabled if any dir is SMP-aware
554  if (Dir(i).smpAware())
555  return true;
556  }
557  return false;
558 }
559 
560 bool
562 {
563  for (int i = 0; i < Config.cacheSwap.n_configured; ++i)
564  if (Dir(i).active() && Dir(i).hasReadableEntry(e))
565  return true;
566  return false;
567 }
568 
569 void
571 {
572  for (int dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
573  INDEXSD(dirn)->openLog();
574 }
575 
576 void
578 {
579  for (int dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
580  INDEXSD(dirn)->closeLog();
581 }
582 
592 int
594 {
595  const StoreEntry *e = NULL;
596  int n = 0;
597 
598  struct timeval start;
599  double dt;
601  int dirn;
602  int notdone = 1;
603 
604  // Check for store_dirs_rebuilding because fatal() often calls us in early
605  // initialization phases, before store log is initialized and ready. Also,
606  // some stores do not support log cleanup during Store rebuilding.
608  debugs(20, DBG_IMPORTANT, "Not currently OK to rewrite swap log.");
609  debugs(20, DBG_IMPORTANT, "storeDirWriteCleanLogs: Operation aborted.");
610  return 0;
611  }
612 
613  debugs(20, DBG_IMPORTANT, "storeDirWriteCleanLogs: Starting...");
614  getCurrentTime();
615  start = current_time;
616 
617  for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn) {
618  sd = dynamic_cast<SwapDir *>(INDEXSD(dirn));
619 
620  if (sd->writeCleanStart() < 0) {
621  debugs(20, DBG_IMPORTANT, "log.clean.start() failed for dir #" << sd->index);
622  continue;
623  }
624  }
625 
626  /*
627  * This may look inefficient as CPU wise it is more efficient to do this
628  * sequentially, but I/O wise the parallellism helps as it allows more
629  * hdd spindles to be active.
630  */
631  while (notdone) {
632  notdone = 0;
633 
634  for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn) {
635  sd = dynamic_cast<SwapDir *>(INDEXSD(dirn));
636 
637  if (NULL == sd->cleanLog)
638  continue;
639 
640  e = sd->cleanLog->nextEntry();
641 
642  if (!e)
643  continue;
644 
645  notdone = 1;
646 
647  if (!sd->canLog(*e))
648  continue;
649 
650  sd->cleanLog->write(*e);
651 
652  if ((++n & 0xFFFF) == 0) {
653  getCurrentTime();
654  debugs(20, DBG_IMPORTANT, " " << std::setw(7) << n <<
655  " entries written so far.");
656  }
657  }
658  }
659 
660  /* Flush */
661  for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
662  dynamic_cast<SwapDir *>(INDEXSD(dirn))->writeCleanDone();
663 
664  if (reopen)
666 
667  getCurrentTime();
668 
669  dt = tvSubDsec(start, current_time);
670 
671  debugs(20, DBG_IMPORTANT, " Finished. Wrote " << n << " entries.");
672  debugs(20, DBG_IMPORTANT, " Took "<< std::setw(3)<< std::setprecision(2) << dt <<
673  " seconds ("<< std::setw(6) << ((double) n / (dt > 0.0 ? dt : 1.0)) << " entries/sec).");
674 
675  return n;
676 }
677 
678 /* Globals that should be converted to static Store::Disks methods */
679 
680 void
682 {
683  if (!swap->swapDirs) {
684  swap->n_allocated = 4;
685  swap->swapDirs = new SwapDir::Pointer[swap->n_allocated];
686  }
687 
688  if (swap->n_allocated == swap->n_configured) {
689  swap->n_allocated <<= 1;
690  const auto tmp = new SwapDir::Pointer[swap->n_allocated];
691  for (int i = 0; i < swap->n_configured; ++i) {
692  tmp[i] = swap->swapDirs[i];
693  }
694  delete[] swap->swapDirs;
695  swap->swapDirs = tmp;
696  }
697 }
698 
699 void
701 {
702  /* DON'T FREE THESE FOR RECONFIGURE */
703 
704  if (reconfiguring)
705  return;
706 
707  /* TODO XXX this lets the swapdir free resources asynchronously
708  * swap->swapDirs[i]->deactivate();
709  * but there may be such a means already.
710  * RBC 20041225
711  */
712 
713  // only free's the array memory itself
714  // the SwapDir objects may remain (ref-counted)
715  delete[] swap->swapDirs;
716  swap->swapDirs = nullptr;
717  swap->n_allocated = 0;
718  swap->n_configured = 0;
719 }
720 
721 /* Globals that should be moved to some Store::UFS-specific logging module */
722 
732 void
733 storeDirSwapLog(const StoreEntry * e, int op)
734 {
735  assert (e);
737  assert(e->hasDisk());
738  /*
739  * icons and such; don't write them to the swap log
740  */
741 
742  if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
743  return;
744 
745  assert(op > SWAP_LOG_NOP && op < SWAP_LOG_MAX);
746 
747  debugs(20, 3, "storeDirSwapLog: " <<
748  swap_log_op_str[op] << " " <<
749  e->getMD5Text() << " " <<
750  e->swap_dirn << " " <<
751  std::hex << std::uppercase << std::setfill('0') << std::setw(8) << e->swap_filen);
752 
753  dynamic_cast<SwapDir *>(INDEXSD(e->swap_dirn))->logEntry(*e, op);
754 }
755 
virtual void stat(StoreEntry &) const override
Definition: Disks.cc:435
CleanLog * cleanLog
Definition: Disk.h:140
sdirno swap_dirn
Definition: Store.h:214
virtual int64_t maxObjectSize() const override
the maximum size of a storable object; -1 if unlimited
Definition: Disk.cc:103
static int store_dirs_rebuilding
the number of cache_dirs being rebuilt; TODO: move to Disks::Rebuilding
Definition: Controller.h:139
hash_table * store_table
virtual bool active() const
Definition: Disk.cc:236
virtual void evictIfFound(const cache_key *) override
Definition: Disks.cc:506
virtual void sync() override
prepare for shutdown
Definition: Disks.cc:482
#define assert(EX)
Definition: assert.h:17
virtual bool dereference(StoreEntry &e) override
Definition: Disks.cc:454
virtual bool anchorToCache(StoreEntry &, bool &)
Definition: Controlled.h:40
void updateLimits()
slowly calculate (and cache) hi/lo watermarks and similar limits
Definition: Disks.cc:358
size_t swap_hdr_sz
Definition: MemObject.h:169
double open_disk_fd
number of opened disk files
Definition: StoreStats.h:35
void storeDirSwapLog(const StoreEntry *e, int op)
Definition: Disks.cc:733
virtual uint64_t currentCount() const override
the total number of objects stored right now
Definition: Disks.cc:339
virtual uint64_t minSize() const override
the minimum size the store will shrink to via normal housekeeping
Definition: Disks.cc:313
unsigned char cache_key
Store key.
Definition: forward.h:29
virtual void updateHeaders(StoreEntry *)
make stored metadata and HTTP headers the same as in the given entry
Definition: Controlled.h:35
int i
Definition: membanger.c:49
int64_t endOffset() const
Definition: MemObject.cc:218
virtual bool updateAnchored(StoreEntry &) override
Definition: Disks.cc:541
HASHHASH storeKeyHashHash
virtual bool anchorToCache(StoreEntry &e, bool &inSync) override
Definition: Disks.cc:515
const char * storeKeyText(const cache_key *key)
YesNoNone memShared
whether the memory cache is shared among workers
Definition: SquidConfig.h:83
bool hasDisk(const sdirno dirn=-1, const sfileno filen=-1) const
Definition: store.cc:1997
class Ping::pingStats_ stats
struct Store::Disk::Flags flags
virtual void reference(StoreEntry &) override
somebody needs this entry (many cache replacement policies need to know)
Definition: Disks.cc:448
bool canLog(StoreEntry const &e) const
Definition: Disk.cc:188
#define Must(condition)
Like assert() but throws an exception instead of aborting the process.
Definition: TextException.h:69
int64_t accumulateMore(const StoreEntry &) const
Definition: Disks.cc:382
struct SquidConfig::@110 Store
sfileno swap_filen
unique ID inside a cache_dir for swapped out entries; -1 for others
Definition: Store.h:212
#define DBG_CRITICAL
Definition: Debug.h:45
#define DBG_PARSE_NOTE(x)
Definition: Debug.h:50
Controller & Root()
safely access controller singleton
Definition: Controller.cc:877
virtual uint64_t currentSize() const =0
current size
High-level store statistics used by mgr:info action. Used inside PODs!
Definition: StoreStats.h:13
virtual bool dereference(StoreEntry &e) override
Definition: Disk.cc:139
struct timeval current_time
Definition: stub_time.cc:15
static int64_t objectSizeForDirSelection(const StoreEntry &entry)
Definition: Disks.cc:33
int store_hash_buckets
void storeDirOpenSwapLogs()
Definition: Disks.cc:570
virtual void reference(StoreEntry &e) override
somebody needs this entry (many cache replacement policies need to know)
Definition: Disk.cc:136
virtual uint64_t maxSize() const override
Definition: Controller.cc:163
virtual void getStats(StoreInfoStats &stats) const override
collect statistics
Definition: Disks.cc:419
int64_t avgObjectSize
Definition: SquidConfig.h:265
virtual uint64_t maxSize() const override
Definition: Disks.cc:300
STDIRSELECT * storeDirSelectSwapDir
Definition: Disks.cc:28
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
#define DBG_IMPORTANT
Definition: Debug.h:46
HASHCMP storeKeyHashCmp
bool hasReadableEntry(const StoreEntry &) const
whether any of disk caches has entry with e.key
Definition: Disks.cc:561
virtual void maintain() override
perform regular periodic maintenance; TODO: move to UFSSwapDir::Maintain
Definition: Disks.cc:467
void fatal(const char *message)
Definition: fatal.cc:28
static SwapDir & Dir(int const idx)
Definition: Disks.cc:165
virtual void write(StoreEntry const &)=0
uint16_t flags
Definition: Store.h:208
SQUIDCEXTERN hash_table * hash_create(HASHCMP *, int, HASHHASH *)
Definition: hash.cc:109
int storeDirWriteCleanLogs(int reopen)
Definition: Disks.cc:593
void free_cachedir(Store::DiskConfig *swap)
Definition: Disks.cc:700
MemObject * mem_obj
Definition: Store.h:197
int objectsPerBucket
Definition: SquidConfig.h:264
virtual uint64_t maxSize() const override
Definition: Disk.h:48
void allocate_new_swapdir(Store::DiskConfig *swap)
Definition: Disks.cc:681
#define INDEXSD(i)
Definition: SquidConfig.h:68
int STDIRSELECT(const StoreEntry *e)
Definition: Disks.h:78
static bool SmpAware()
whether any disk cache is SMP-aware
Definition: Disks.cc:548
const char * swap_log_op_str[]
int index
Definition: Disk.h:103
time_t getCurrentTime(void)
Get current time.
const char * getMD5Text() const
Definition: store.cc:184
RefCount< SwapDir > * swapDirs
Definition: SquidConfig.h:62
virtual void evictCached(StoreEntry &) override
Definition: Disks.cc:489
Store::Disk & disk() const
the disk this entry is [being] cached on; asserts for entries w/o a disk
Definition: store.cc:1988
virtual void init() override
Definition: Disks.cc:244
Store::DiskConfig cacheSwap
Definition: SquidConfig.h:422
int store_open_disk_fd
virtual uint64_t currentSize() const override
current size
Definition: Disks.cc:326
const cache_key * publicKey() const
Definition: Store.h:98
size_t memMaxSize
Definition: SquidConfig.h:85
SwapDir * store(int const x) const
Definition: Disks.cc:159
int storeKeyHashBuckets(int nbuckets)
static struct tok * buckets[HASHSIZE]
Definition: parse.c:219
static STDIRSELECT storeDirSelectSwapDirRoundRobin
Definition: Disks.cc:22
#define INT_MAX
Definition: types.h:76
virtual int writeCleanStart()
Definition: Disk.cc:218
virtual void create() override
create system resources needed for this store to operate in the future
Definition: Disks.cc:205
virtual int callback() override
called once every main loop iteration; TODO: Move to UFS code.
Definition: Disks.cc:173
static STDIRSELECT storeDirSelectSwapDirLeastLoad
Definition: Disks.cc:23
virtual void evictCached(StoreEntry &e)=0
virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const =0
check whether we can store the entry; if we can, report current load
Definition: Disk.cc:164
virtual int64_t maxObjectSize() const override
the maximum size of a storable object; -1 if unlimited
Definition: Disks.cc:352
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:875
int64_t availableForSwapOut() const
buffered bytes we have not swapped out yet
Definition: MemObject.cc:485
#define EBIT_TEST(flag, bit)
Definition: defines.h:107
virtual StoreEntry * get(const cache_key *) override
Definition: Disks.cc:218
class SquidConfig Config
Definition: SquidConfig.cc:12
#define NULL
Definition: types.h:166
char * store_dir_select_algorithm
Definition: SquidConfig.h:507
virtual const StoreEntry * nextEntry()=0
int64_t expectedReplySize() const
Definition: MemObject.cc:242
int reconfiguring
SQUIDCEXTERN double tvSubDsec(struct timeval, struct timeval)
Definition: util.c:46
Swap swap
cache_mem stats
Definition: StoreStats.h:48
virtual StoreEntry * get(const cache_key *) override
Definition: Disk.cc:393
virtual void updateHeaders(StoreEntry *) override
make stored metadata and HTTP headers the same as in the given entry
Definition: Disks.cc:460
manages a single cache_dir
Definition: Disk.h:21
void storeDirCloseSwapLogs()
Definition: Disks.cc:577

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors