/* */ #include "WrDiskCache.h" #include "WrDiskCacheEntry.h" #include "LogFactory.h" #include "fmt.h" namespace aria2 { WrDiskCache::WrDiskCache(size_t limit) : limit_(limit), total_(0), clock_(0) {} WrDiskCache::~WrDiskCache() { if(total_) { A2_LOG_WARN(fmt("Write disk cache is not empty size=%lu", static_cast(total_))); } } bool WrDiskCache::add(WrDiskCacheEntry* ent) { ent->setSizeKey(ent->getSize()); ent->setLastUpdate(++clock_); std::pair rv = set_.insert(ent); if(rv.second) { total_ += ent->getSize(); ensureLimit(); return true; } else { A2_LOG_WARN(fmt("Found duplicate cache entry a.{size=%lu,clock=%"PRId64 "} b{size=%lu,clock=%"PRId64"}", static_cast((*rv.first)->getSize()), (*rv.first)->getLastUpdate(), static_cast(ent->getSize()), ent->getLastUpdate())); return false; } } bool WrDiskCache::remove(WrDiskCacheEntry* ent) { if(set_.erase(ent)) { A2_LOG_DEBUG(fmt("Removed cache entry size=%lu, clock=%"PRId64, static_cast(ent->getSize()), ent->getLastUpdate())); total_ -= ent->getSize(); return true; } else { return false; } } bool WrDiskCache::update(WrDiskCacheEntry* ent, ssize_t delta) { if(!set_.erase(ent)) { return false; } A2_LOG_DEBUG(fmt("Update cache entry size=%lu, delta=%ld, clock=%"PRId64, static_cast(ent->getSize()), static_cast(delta), ent->getLastUpdate())); ent->setSizeKey(ent->getSize()); ent->setLastUpdate(++clock_); set_.insert(ent); if(delta < 0) { assert(total_ >= static_cast(-delta)); } total_ += delta; ensureLimit(); return true; } void WrDiskCache::ensureLimit() { while(total_ > limit_) { EntrySet::iterator i = set_.begin(); WrDiskCacheEntry* ent = *i; A2_LOG_DEBUG(fmt("Force flush cache entry size=%lu, clock=%"PRId64, static_cast(ent->getSizeKey()), ent->getLastUpdate())); total_ -= ent->getSize(); ent->writeToDisk(); set_.erase(i); ent->setSizeKey(ent->getSize()); ent->setLastUpdate(++clock_); set_.insert(ent); } } } // namespace aria2