From: Dmitry Kurochkin Date: Sun, 30 Jan 2011 23:15:05 +0000 (+0300) Subject: Shared Rock::DirMap version 4. X-Git-Tag: take01~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=44704b509b44fc49f3bbfc03898149e4a6b0bd39;p=thirdparty%2Fsquid.git Shared Rock::DirMap version 4. --- diff --git a/src/fs/rock/RockDirMap.cc b/src/fs/rock/RockDirMap.cc index 6f8f88b244..d6377671d5 100644 --- a/src/fs/rock/RockDirMap.cc +++ b/src/fs/rock/RockDirMap.cc @@ -25,31 +25,20 @@ Rock::DirMap::DirMap(const int id): shared = reinterpret_cast(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; @@ -70,31 +59,46 @@ Rock::DirMap::added(const cache_key *const key) 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) { @@ -160,7 +164,7 @@ Rock::DirMap::freeIfNeeded(Slot &s) 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)); } } } diff --git a/src/fs/rock/RockDirMap.h b/src/fs/rock/RockDirMap.h index 016050ae39..f9ac56f14a 100644 --- a/src/fs/rock/RockDirMap.h +++ b/src/fs/rock/RockDirMap.h @@ -27,13 +27,10 @@ public: 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); @@ -55,8 +52,6 @@ public: private: struct Slot { enum { - WaitingToBeInitialized, - Initializing, Empty, Writing, Usable, @@ -84,6 +79,8 @@ private: 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); diff --git a/src/fs/rock/RockRebuild.cc b/src/fs/rock/RockRebuild.cc index 3074605446..c3cef445b0 100644 --- a/src/fs/rock/RockRebuild.cc +++ b/src/fs/rock/RockRebuild.cc @@ -97,10 +97,8 @@ Rock::Rebuild::doOneEntry() { 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; } @@ -111,9 +109,7 @@ Rock::Rebuild::doOneEntry() { counts.objcount++; // loadedE->dump(5); - //StoreEntry *e = sd->addEntry(fileno, loadedE); - //storeDirSwapLog(e, SWAP_LOG_ADD); } void diff --git a/src/fs/rock/RockSwapDir.cc b/src/fs/rock/RockSwapDir.cc index f3ec99b6a8..7002539da2 100644 --- a/src/fs/rock/RockSwapDir.cc +++ b/src/fs/rock/RockSwapDir.cc @@ -255,37 +255,29 @@ Rock::SwapDir::rebuild() { /* 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(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); } @@ -537,23 +529,12 @@ Rock::SwapDir::dereference(StoreEntry &e) 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 diff --git a/src/fs/rock/RockSwapDir.h b/src/fs/rock/RockSwapDir.h index 67c5ffaf8e..7e92bf0064 100644 --- a/src/fs/rock/RockSwapDir.h +++ b/src/fs/rock/RockSwapDir.h @@ -52,9 +52,8 @@ protected: 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