bool StatCache::AddStat()

in src/cache.cpp [448:520]


bool StatCache::AddStat(const std::string& key, headers_t& meta, bool forcedir, bool no_truncate, bool isfake)
{
    if(!no_truncate && CacheSize< 1){
        return true;
    }
    S3FS_PRN_INFO3("add stat cache entry[path=%s], flag(%d, %d, %d)", key.c_str(), forcedir, no_truncate, isfake);

    bool found;
    bool do_truncate;
    {
        AutoLock lock(&StatCache::stat_cache_lock);
        found       = stat_cache.end() != stat_cache.find(key);
        do_truncate = stat_cache.size() > CacheSize;
    }

    if(found){
        DelStat(key.c_str());
    }else{
        if(do_truncate){
            if(!TruncateCache()){
                return false;
            }
        }
    }

    // make new
    stat_cache_entry* ent = new stat_cache_entry();
    if(!convert_header_to_stat(key, meta, &(ent->stbuf), forcedir, IsNoExtendedMeta, CheckSizeForMeta)){
        delete ent;
        return false;
    }
    ent->hit_count  = 0;
    ent->isforce    = forcedir;
    ent->noobjcache = false;
    ent->notruncate = (no_truncate ? 1L : 0L);
    ent->isfake     = isfake;
    ent->meta.clear();
    SetStatCacheTime(ent->cache_date);    // Set time.
    //copy only some keys
    for(headers_t::iterator iter = meta.begin(); iter != meta.end(); ++iter){
        std::string tag   = lower(iter->first);
        std::string value = iter->second;
        if(tag == "content-type"){
            ent->meta[iter->first] = value;
        }else if(tag == "content-length"){
            ent->meta[iter->first] = value;
        }else if(tag == "etag"){
            ent->meta[iter->first] = value;
        }else if(tag == "last-modified"){
            ent->meta[iter->first] = value;
        }else if(is_prefix(tag.c_str(), "x-oss")){
            ent->meta[tag] = value;      // key is lower case for "x-oss"
        }
    }

    // add
    AutoLock lock(&StatCache::stat_cache_lock);

    std::pair<stat_cache_t::iterator, bool> pair = stat_cache.insert(std::make_pair(key, ent));
    if(!pair.second){
        delete pair.first->second;
        pair.first->second = ent;
    }

    // check symbolic link cache
    if(!S_ISLNK(ent->stbuf.st_mode)){
        if(symlink_cache.end() != symlink_cache.find(key)){
            // if symbolic link cache has key, thus remove it.
            DelSymlink(key.c_str(), true);
        }
    }
    return true;
}