78 static size_t firstCandidate = 0;
87 if (!dir.canStore(*e, objsize, load))
90 if (load < 0 || load > 1000) {
116 int64_t most_free = 0;
117 int64_t best_objsize = -1;
120 SwapDir *selectedDir =
nullptr;
126 sd.flags.selected =
false;
128 if (!sd.canStore(*e, objsize, load))
131 if (load < 0 || load > 1000)
134 if (load > least_load)
137 const int64_t cur_free = sd.maxSize() - sd.currentSize();
140 if (load == least_load) {
142 if (best_objsize != -1) {
145 if ((objsize != -1 && sd.maxObjectSize() > best_objsize) ||
146 (objsize == -1 && sd.maxObjectSize() < best_objsize))
151 if (cur_free < most_free)
156 best_objsize = sd.maxObjectSize();
157 most_free = cur_free;
168 largestMinimumObjectSize(-1),
169 largestMaximumObjectSize(-1),
170 secondLargestMaximumObjectSize(-1)
191 static size_t ndir = 0;
200 int temp_result = store(ndir)->callback();
206 result += temp_result;
209 fatal (
"too much io\n");
238 static size_t idx = 0;
239 for (
size_t n = 0; n < cacheDirs; ++n) {
240 idx = (idx + 1) % cacheDirs;
245 if (
auto e = sd.get(key)) {
246 debugs(20, 7,
"cache_dir " << idx <<
" has: " << *e);
261 fatal(
"'store_objects_per_bucket' should be larger than 0.");
264 fatal(
"'store_avg_object_size' should be larger than 0.");
326 if (Dir(i).doReportStat())
327 result += store(i)->maxSize();
339 if (Dir(i).doReportStat())
340 result += store(i)->minSize();
352 if (Dir(i).doReportStat())
353 result += store(i)->currentSize();
365 if (Dir(i).doReportStat())
366 result += store(i)->currentCount();
375 return largestMaximumObjectSize;
384 largestMinimumObjectSize = -1;
385 largestMaximumObjectSize = -1;
386 secondLargestMaximumObjectSize = -1;
392 if (disk.needsDiskStrand()) {
401 if (disk.minObjectSize() > largestMinimumObjectSize)
402 largestMinimumObjectSize = disk.minObjectSize();
404 const auto diskMaxObjectSize = disk.maxObjectSize();
405 if (diskMaxObjectSize > largestMaximumObjectSize) {
406 if (largestMaximumObjectSize >= 0)
407 secondLargestMaximumObjectSize = largestMaximumObjectSize;
408 largestMaximumObjectSize = diskMaxObjectSize;
430 const auto fsType = fs->type();
436 if ((strcasecmp(pathStr, disk.path)) == 0) {
444 if (strcmp(disk.type(), fsType) == 0)
448 disk.type() <<
" " << disk.path <<
" to " << fsType <<
". Restart required");
454 const size_t cacheDirCountLimit = 64;
456 throw TextException(
ToSBuf(
"Squid cannot handle more than ", cacheDirCountLimit,
" cache_dir directives"),
Here());
470 const auto &disk = Dir(i);
492 if (accumulated < largestMinimumObjectSize)
493 return largestMinimumObjectSize - accumulated;
497 if (accumulated <= secondLargestMaximumObjectSize)
498 return secondLargestMaximumObjectSize - accumulated + 1;
509 debugs(20, 3,
"no: " << accumulated <<
'>' <<
510 secondLargestMaximumObjectSize <<
',' << largestMinimumObjectSize);
520 store(i)->getStats(dirStats);
537 store(i)->stat(output);
570 store(i)->maintain();
603 Dir(i).evictIfFound(key);
617 static size_t idx = 0;
618 for (
size_t n = 0; n < cacheDirs; ++n) {
619 idx = (idx + 1) % cacheDirs;
625 debugs(20, 3,
"cache_dir " << idx <<
" anchors " << entry);
632 " cache_dirs have " << entry);
650 if (Dir(i).smpAware())
666 if (Dir(i).active() && Dir(i).hasReadableEntry(e))
700 struct timeval start;
709 debugs(20,
Important(38),
"storeDirWriteCleanLogs: Operation aborted.");
720 if (sd.writeCleanStart() < 0) {
740 e = sd.cleanLog->nextEntry();
750 sd.cleanLog->
write(*e);
752 if ((++n & 0xFFFF) == 0) {
755 " entries written so far.");
772 debugs(20,
Important(41),
" Took "<< std::setw(3) << std::setprecision(2) << dt <<
773 " seconds ("<< std::setw(6) << ((
double) n / (dt > 0.0 ? dt : 1.0)) <<
" entries/sec).");
847 debugs(20, 3,
"storeDirSwapLog: " <<
void free_cachedir(Store::DiskConfig *swap)
static int64_t objectSizeForDirSelection(const StoreEntry &entry)
SwapDir * STDIRSELECT(const StoreEntry *e)
static STDIRSELECT storeDirSelectSwapDirRoundRobin
static SwapDir & SwapDirByIndex(const size_t i)
TODO: Remove when cache_dir-iterating functions are converted to Disks methods.
void storeDirSwapLog(const StoreEntry *e, int op)
static STDIRSELECT storeDirSelectSwapDirLeastLoad
void allocate_new_swapdir(Store::DiskConfig &swap)
void storeDirOpenSwapLogs()
int storeDirWriteCleanLogs(int reopen)
static STDIRSELECT * storeDirSelectSwapDir
void storeDirCloseSwapLogs()
#define Here()
source code location of the caller
AsHex< Integer > asHex(const Integer n)
a helper to ease AsHex object creation
static char * NextToken()
int64_t availableForSwapOut() const
buffered bytes we have not swapped out yet
int64_t expectedReplySize() const
int64_t endOffset() const
Store::DiskConfig cacheSwap
char * store_dir_select_algorithm
struct SquidConfig::@88 Store
YesNoNone memShared
whether the memory cache is shared among workers
bool hasDisk(const sdirno dirn=-1, const sfileno filen=-1) const
void write(StoreIOBuffer)
const cache_key * publicKey() const
Store::Disk & disk() const
the disk this entry is [being] cached on; asserts for entries w/o a disk
const char * getMD5Text() const
sfileno swap_filen
unique ID inside a cache_dir for swapped out entries; -1 for others
static StoreFileSystem * FindByType(const char *type)
double open_disk_fd
number of opened disk files
High-level store statistics used by mgr:info action. Used inside PODs!
virtual void updateHeaders(StoreEntry *)
make stored metadata and HTTP headers the same as in the given entry
virtual bool updateAnchored(StoreEntry &)
virtual bool anchorToCache(StoreEntry &)
uint64_t maxSize() const override
static int store_dirs_rebuilding
the number of cache_dirs being rebuilt; TODO: move to Disks::Rebuilding
RefCount< SwapDir > * swapDirs
int n_strands
number of disk processes required to support all cache_dirs
manages a single cache_dir
virtual bool active() const
virtual void writeCleanDone()
struct Store::Disk::Flags flags
virtual void logEntry(const StoreEntry &e, int op) const
void reference(StoreEntry &e) override
somebody needs this entry (many cache replacement policies need to know)
bool dereference(StoreEntry &e) override
void reference(StoreEntry &) override
somebody needs this entry (many cache replacement policies need to know)
void create() override
create system resources needed for this store to operate in the future
int64_t maxObjectSize() const override
the maximum size of a storable object; -1 if unlimited
void evictCached(StoreEntry &) override
static void Dump(const DiskConfig &, StoreEntry &, const char *name)
prints the configuration into the provided StoreEntry
uint64_t currentCount() const override
the total number of objects stored right now
bool dereference(StoreEntry &e) override
bool hasReadableEntry(const StoreEntry &) const
whether any of disk caches has entry with e.key
void getStats(StoreInfoStats &stats) const override
collect statistics
void configure()
update configuration, including limits (re)calculation
uint64_t currentSize() const override
current size
uint64_t minSize() const override
the minimum size the store will shrink to via normal housekeeping
void maintain() override
perform regular periodic maintenance; TODO: move to UFSSwapDir::Maintain
void evictIfFound(const cache_key *) override
int64_t accumulateMore(const StoreEntry &) const
SwapDir * store(size_t index) const
bool updateAnchored(StoreEntry &) override
void sync() override
prepare for shutdown
void updateHeaders(StoreEntry *) override
make stored metadata and HTTP headers the same as in the given entry
void stat(StoreEntry &) const override
static SwapDir * SelectSwapDir(const StoreEntry *)
int callback() override
called once every main loop iteration; TODO: Move to UFS code.
StoreEntry * get(const cache_key *) override
bool anchorToCache(StoreEntry &) override
uint64_t maxSize() const override
static void Parse(DiskConfig &)
parses a single cache_dir configuration line
static SwapDir & Dir(size_t index)
static bool SmpAware()
whether any disk cache is SMP-aware
virtual void evictCached(StoreEntry &e)=0
an std::runtime_error with thrower location info
#define DBG_PARSE_NOTE(x)
#define debugs(SECTION, LEVEL, CONTENT)
#define EBIT_TEST(flag, bit)
void fatal(const char *message)
hash_table * hash_create(HASHCMP *, int, HASHHASH *)
Controller & Root()
safely access controller singleton
static struct tok * buckets[HASHSIZE]
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
unsigned char cache_key
Store key.
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
int storeKeyHashBuckets(int nbuckets)
const char * storeKeyText(const cache_key *key)
HASHHASH storeKeyHashHash
void storeRebuildComplete(StoreRebuildData *dc)
time_t getCurrentTime() STUB_RETVAL(0) int tvSubUsec(struct timeval
const char * swap_log_op_str[]
double tvSubDsec(struct timeval t1, struct timeval t2)
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format