in src/cache.cpp [645:703]
bool StatCache::TruncateCache()
{
AutoLock lock(&StatCache::stat_cache_lock);
if(stat_cache.empty()){
return true;
}
// 1) erase over expire time
if(IsExpireTime){
for(stat_cache_t::iterator iter = stat_cache.begin(); iter != stat_cache.end(); ){
stat_cache_entry* entry = iter->second;
if(!entry || (0L == entry->notruncate && IsExpireStatCacheTime(entry->cache_date, ExpireTime))){
delete entry;
stat_cache.erase(iter++);
}else{
++iter;
}
}
}
// 2) check stat cache count
if(stat_cache.size() < CacheSize){
return true;
}
// 3) erase from the old cache in order
size_t erase_count= stat_cache.size() - CacheSize + 1;
statiterlist_t erase_iters;
for(stat_cache_t::iterator iter = stat_cache.begin(); iter != stat_cache.end() && 0 < erase_count; ++iter){
// check no truncate
stat_cache_entry* ent = iter->second;
if(ent && 0L < ent->notruncate){
// skip for no truncate entry and keep extra counts for this entity.
if(0 < erase_count){
--erase_count; // decrement
}
}else{
// iter is not have notruncate flag
erase_iters.push_back(iter);
}
if(erase_count < erase_iters.size()){
sort(erase_iters.begin(), erase_iters.end(), sort_statiterlist());
while(erase_count < erase_iters.size()){
erase_iters.pop_back();
}
}
}
for(statiterlist_t::iterator iiter = erase_iters.begin(); iiter != erase_iters.end(); ++iiter){
stat_cache_t::iterator siter = *iiter;
S3FS_PRN_DBG("truncate stat cache[path=%s]", siter->first.c_str());
delete siter->second;
stat_cache.erase(siter);
}
S3FS_MALLOCTRIM(0);
return true;
}