private:
/* migration logic */
StorePointer store(int const x) const;
+ SwapDir &dir(int const idx) const;
};
class StoreHashIndexEntry : public StoreEntry
return theType;
}
+bool
+SwapDir::active() const
+{
+ if (IamWorkerProcess())
+ return true;
+
+ // we are inside a disker dedicated to this disk
+ if (IamDiskProcess() && index == (KidIdentifier-1 - Config.workers))
+ return true;
+
+ return false; // Coordinator, wrong disker, etc.
+}
+
+bool
+SwapDir::needsDiskStrand() const
+{
+ return false;
+}
+
/* NOT performance critical. Really. Don't bother optimising for speed
* - RBC 20030718
*/
virtual void reconfigure(int, char *) = 0;
char const *type() const;
+ virtual bool needsDiskStrand() const; ///< needs a dedicated kid process
+ virtual bool active() const; ///< may be used in this strand
+
/* official Store interface functions */
virtual void diskFull();
static void
parse_cachedir(SquidConfig::_cacheSwap * swap)
{
- // coordinator does not need to handle cache_dir.
- if (IamCoordinatorProcess()) {
- // make sure the NumberOfKids() is correct for coordinator
- ++swap->n_processes; // XXX: does not work in reconfigure
- return;
- }
-
char *type_str;
char *path_str;
RefCount<SwapDir> sd;
sd->parse(swap->n_configured, path_str);
++swap->n_configured;
- ++swap->n_processes;
+
+ if (sd->needsDiskStrand())
+ ++swap->n_strands;
/* Update the max object size */
update_maxobjsize();
theFile->open(O_RDWR, 0644, this);
}
+bool
+Rock::SwapDir::needsDiskStrand() const
+{
+ return true;
+}
+
void
Rock::SwapDir::parse(int anIndex, char *aPath)
{
protected:
/* protected ::SwapDir API */
+ virtual bool needsDiskStrand() const;
virtual void create();
virtual void init();
virtual int canStore(StoreEntry const &) const;
return INDEXSD(x);
}
+SwapDir &
+StoreHashIndex::dir(const int i) const
+{
+ SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(i));
+ assert(sd);
+ return *sd;
+}
+
void
StoreController::sync(void)
{
// ask each cache_dir until the entry is found; use static starting
// point to avoid asking the same subset of disks more often
// TODO: coordinate with put() to be able to guess the right disk often
+ static int idx = 0;
for (int n = 0; n < cacheDirs; ++n) {
- static int idx = 0;
+ idx = (idx + 1) % cacheDirs;
SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(idx));
+ if (!sd->active())
+ continue;
+
if (StoreEntry *e = sd->get(key)) {
debugs(20, 3, HERE << "cache_dir " << idx <<
" got cached entry: " << *e);
return e;
}
- idx = (idx + 1) % cacheDirs;
}
}
void
StoreHashIndex::create()
{
- for (int i = 0; i < Config.cacheSwap.n_configured; i++)
- store(i)->create();
+ for (int i = 0; i < Config.cacheSwap.n_configured; i++) {
+ if (dir(i).active())
+ store(i)->create();
+ }
}
/* Lookup an object in the cache.
* above
* Step 3: have the hash index walk the searches itself.
*/
- if (IamDiskProcess() &&
- i != KidIdentifier % Config.cacheSwap.n_configured) {
- debugs(20, 3, HERE << " skipping init for cache_dir " <<
- dynamic_cast<const SwapDir &>(*store(i)).path);
- continue;
- }
- store(i)->init();
+ if (dir(i).active())
+ store(i)->init();
}
}
RefCount<class Store> *swapDirs;
int n_allocated;
int n_configured;
- ///< number of disk processes (set even when n_configured is not)
- int n_processes;
+ ///< number of disk processes required to support all cache_dirs
+ int n_strands;
} cacheSwap;
/*
* I'm sick of having to keep doing this ..
// XXX: detect and abort when called before workers/cache_dirs are parsed
- // XXX: this is not always the case as there are other cache_dir types
- const int rockDirs = Config.cacheSwap.n_processes;
+ const int rockDirs = Config.cacheSwap.n_strands;
const bool needCoord = Config.workers > 1 || rockDirs > 0;
return (needCoord ? 1 : 0) + Config.workers + rockDirs;