/** * Stats the given file. If <tt>throttleRate</tt> seconds have passed since * the last time stat() was called on this file, then the file will be * re-stat()ted, otherwise the cached stat information will be returned. * * @param filename The file to stat. * @param stat A pointer to a stat struct; the retrieved stat information * will be stored here. * @param throttleRate Tells this CachedFileStat that the file may only * be statted at most every <tt>throttleRate</tt> seconds. * @return 0 if the stat() call succeeded or if the cached stat information was used; * -1 if something went wrong while statting the file. In the latter * case, <tt>errno</tt> will be populated with an appropriate error code. * @throws SystemException Something went wrong while retrieving the * system time. stat() errors will <em>not</em> result in * SystemException being thrown. * @throws boost::thread_interrupted */ int stat(const string &filename, struct stat *buf, unsigned int throttleRate = 0) { boost::unique_lock<boost::mutex> l(lock); EntryMap::iterator it(cache.find(filename)); EntryPtr entry; int ret; if (it == cache.end()) { // Filename not in cache. // If cache is full, remove the least recently used // cache entry. if (maxSize != 0 && cache.size() == maxSize) { EntryList::iterator listEnd(entries.end()); listEnd--; string filename((*listEnd)->filename); entries.pop_back(); cache.erase(filename); } // Add to cache as most recently used. entry = EntryPtr(new Entry(filename)); entries.push_front(entry); cache[filename] = entries.begin(); } else { // Cache hit. entry = *it->second; // Mark this cache item as most recently used. entries.erase(it->second); entries.push_front(entry); cache[filename] = entries.begin(); } ret = entry->refresh(throttleRate); *buf = entry->info; return ret; }
/** * Change the maximum size of the cache. If the new size is larger * than the old size, then the oldest entries in the cache are * removed. * * A size of 0 means unlimited. */ void setMaxSize(unsigned int maxSize) { boost::unique_lock<boost::mutex> l(lock); if (maxSize != 0) { int toRemove = cache.size() - maxSize; for (int i = 0; i < toRemove; i++) { string filename(entries.back()->filename); entries.pop_back(); cache.erase(filename); } } this->maxSize = maxSize; }