shared = reinterpret_cast<Shared *>(shm.mem());
}
-bool
-Rock::DirMap::initialize(const cache_key *const key, const StoreEntryBasics &seBasics)
-{
- Slot &s = slot(key);
- if (s.state.swap_if(Slot::WaitingToBeInitialized, Slot::Initializing)) {
- s.setKey(key);
- s.seBasics = seBasics;
- ++shared->count;
- assert(s.state.swap_if(Slot::Initializing, Slot::Usable));
- return true;
- }
- return false;
-}
-
-bool
-Rock::DirMap::initialize(const int idx)
+StoreEntryBasics *
+Rock::DirMap::add(const cache_key *const key)
{
- return valid(idx) &&
- shared->slots[idx].state.swap_if(Slot::WaitingToBeInitialized, Slot::Empty);
+ return add(key, slotIdx(key));
}
StoreEntryBasics *
-Rock::DirMap::add(const cache_key *const key)
+Rock::DirMap::add(const cache_key *const key, const sfileno fileno)
{
- Slot &s = slot(key);
+ if (fileno != slotIdx(key))
+ return 0;
+
+ free(fileno);
+ Slot &s = shared->slots[fileno];
if (s.state.swap_if(Slot::Empty, Slot::Writing)) {
s.setKey(key);
return &s.seBasics;
bool
Rock::DirMap::free(const cache_key *const key)
{
- int idx;
- if (open(key, idx)) {
- Slot &s = shared->slots[idx];
+ return free(slotIdx(key));
+}
+
+bool
+Rock::DirMap::free(const int fileno)
+{
+ if (open(fileno)) {
+ Slot &s = shared->slots[fileno];
s.state.swap_if(Slot::Usable, Slot::WaitingToBeFreed);
--s.readLevel;
freeIfNeeded(s);
+ return true;
}
return false;
}
const StoreEntryBasics *
-Rock::DirMap::open(const cache_key *const key, sfileno &fileno)
+Rock::DirMap::open(const sfileno fileno)
{
- const int idx = slotIdx(key);
- Slot &s = shared->slots[idx];
+ Slot &s = shared->slots[fileno];
++s.readLevel;
- if (s.state == Slot::Usable && s.checkKey(key)) {
- fileno = idx;
+ if (s.state == Slot::Usable)
return &s.seBasics;
- }
--s.readLevel;
freeIfNeeded(s);
return 0;
}
+const StoreEntryBasics *
+Rock::DirMap::open(const cache_key *const key, sfileno &fileno)
+{
+ const int idx = slotIdx(key);
+ const StoreEntryBasics *const seBasics = open(idx);
+ if (seBasics && shared->slots[fileno].checkKey(key)) {
+ fileno = idx;
+ return seBasics;
+ }
+ return 0;
+}
+
void
Rock::DirMap::close(const cache_key *const key)
{
memset(s.key, 0, sizeof(s.key));
memset(&s.seBasics, 0, sizeof(s.seBasics));
--shared->count;
- s.state.swap_if(Slot::Freeing, Slot::Empty);
+ assert(s.state.swap_if(Slot::Freeing, Slot::Empty));
}
}
}
DirMap(const int id, const int limit); ///< create a new shared DirMap
DirMap(const int id); ///< open an existing shared DirMap
- /// initialize usable slot
- bool initialize(const cache_key *const key, const StoreEntryBasics &seBasics);
- /// initialize empty slot
- bool initialize(const int idx);
-
/// start adding a new entry
StoreEntryBasics *add(const cache_key *const key);
+ /// start adding a new entry, with fileno check
+ StoreEntryBasics *add(const cache_key *const key, const sfileno fileno);
/// finish adding a new entry
void added(const cache_key *const key);
private:
struct Slot {
enum {
- WaitingToBeInitialized,
- Initializing,
Empty,
Writing,
Usable,
int slotIdx(const cache_key *const key) const;
Slot &slot(const cache_key *const key);
+ bool free(const sfileno fileno);
+ const StoreEntryBasics *open(const sfileno fileno);
void freeIfNeeded(Slot &s);
static int SharedSize(const int limit);
StoreEntry loadedE;
if (!storeRebuildLoadEntry(fd, loadedE, key, counts, 0)) {
// skip empty slots
- if (loadedE.swap_filen > 0 || loadedE.swap_file_sz > 0) {
+ if (loadedE.swap_filen > 0 || loadedE.swap_file_sz > 0)
counts.invalid++;
- sd->unlink(fileno);
- }
return;
}
counts.objcount++;
// loadedE->dump(5);
- //StoreEntry *e =
sd->addEntry(fileno, loadedE);
- //storeDirSwapLog(e, SWAP_LOG_ADD);
}
void
/* Add a new object to the cache with empty memory copy and pointer to disk
* use to rebuild store from disk. XXX: dupes UFSSwapDir::addDiskRestore */
-StoreEntry *
-Rock::SwapDir::addEntry(int fileno, const StoreEntry &from)
+void
+Rock::SwapDir::addEntry(const int fileno, const StoreEntry &from)
{
- /* if you call this you'd better be sure file_number is not
- * already in use! */
- StoreEntry *e = new StoreEntry(); // TODO: optimize by reusing "from"?
- debugs(47, 5, HERE << e << ' ' << storeKeyText((const cache_key*)from.key)
+ const cache_key *const key = reinterpret_cast<const cache_key *>(from.key);
+ debugs(47, 5, HERE << &from << ' ' << storeKeyText(key)
<< ", fileno="<< std::setfill('0') << std::hex << std::uppercase <<
std::setw(8) << fileno);
- e->store_status = STORE_OK;
- e->setMemStatus(NOT_IN_MEMORY);
- e->swap_status = SWAPOUT_DONE;
- e->swap_filen = fileno;
- e->swap_dirn = index;
- e->swap_file_sz = from.swap_file_sz;
- e->lock_count = 0;
- e->lastref = from.lastref;
- e->timestamp = from.timestamp;
- e->expires = from.expires;
- e->lastmod = from.lastmod;
- e->refcount = from.refcount;
- e->flags = from.flags;
- EBIT_SET(e->flags, ENTRY_CACHABLE);
- EBIT_CLR(e->flags, RELEASE_REQUEST);
- EBIT_CLR(e->flags, KEY_PRIVATE);
- e->ping_status = PING_NONE;
- EBIT_CLR(e->flags, ENTRY_VALIDATED);
- map.use(e->swap_filen);
- e->hashInsert((const cache_key*)from.key); /* do it after we clear KEY_PRIVATE */
- trackReferences(*e);
- return e;
+
+ StoreEntryBasics *const basics = map.add(key, fileno);
+ if (!basics) {
+ debugs(47, 5, HERE << "Rock::SwapDir::addEntry: map.add failed");
+ }
+
+ memset(basics, 0, sizeof(*basics));
+ basics->timestamp = from.timestamp;
+ basics->lastref = from.lastref;
+ basics->expires = from.expires;
+ basics->lastmod = from.lastmod;
+ basics->swap_file_sz = from.swap_file_sz;
+ basics->refcount = from.refcount;
+ basics->flags = from.flags;
+
+ map.added(key);
}
repl->Dereferenced(repl, &e, &e.repl);
}
-void
-Rock::SwapDir::unlink(int fileno)
-{
- debugs(47,5, HERE << index << ' ' << fileno);
- if (map.has(fileno)) {
- map.clear(fileno);
- cur_size = (HeaderSize + max_objsize * map.entryCount()) >> 10;
- // XXX: update store
- }
-}
-
void
Rock::SwapDir::unlink(StoreEntry &e)
{
debugs(47, 5, HERE << &e << ' ' << e.swap_dirn << ' ' << e.swap_filen);
ignoreReferences(e);
- unlink(e.swap_filen);
+ map.free(e.key);
}
void
void validateOptions(); ///< warns of configuration problems; may quit
void rebuild(); ///< starts loading and validating stored entry metadata
- void unlink(int fileno); ///< used for entries failed to load in rebuild
///< used to add entries successfully loaded during rebuild
- StoreEntry *addEntry(int fileno, const StoreEntry &from);
+ void addEntry(const int fileno, const StoreEntry &from);
bool full() const; ///< no more entries can be stored without purging
void trackReferences(StoreEntry &e); ///< add to replacement policy scope