bool StatCache::TruncateCache()

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;
}