bool StatCache::GetStat()

in src/cache.cpp [322:405]


bool StatCache::GetStat(const std::string& key, struct stat* pst, headers_t* meta, bool overcheck, const char* petag, bool* pisforce, bool *pisfake)
{
    bool is_delete_cache = false;
    std::string strpath = key;

    AutoLock lock(&StatCache::stat_cache_lock);

    stat_cache_t::iterator iter = stat_cache.end();
    if(overcheck && '/' != *strpath.rbegin()){
        strpath += "/";
        iter = stat_cache.find(strpath);
    }
    if(iter == stat_cache.end()){
        strpath = key;
        iter = stat_cache.find(strpath);
    }

    if(iter != stat_cache.end() && (*iter).second){
        stat_cache_entry* ent = (*iter).second;
        if(0 < ent->notruncate || !IsExpireTime || !IsExpireStatCacheTime(ent->cache_date, ExpireTime)){
            if(ent->noobjcache){
                if(!IsCacheNoObject){
                    // need to delete this cache.
                    DelStat(strpath, /*lock_already_held=*/ true);
                }else{
                    // noobjcache = true means no object.
                }
                return false;
            }
            // hit without checking etag
            std::string stretag;
            if(petag){
                // find & check ETag
                for(headers_t::iterator hiter = ent->meta.begin(); hiter != ent->meta.end(); ++hiter){
                    std::string tag = lower(hiter->first);
                    if(tag == "etag"){
                        stretag = hiter->second;
                        if('\0' != petag[0] && 0 != strcmp(petag, stretag.c_str())){
                            is_delete_cache = true;
                        }
                        break;
                    }
                }
            }
            if(is_delete_cache){
                // not hit by different ETag
                S3FS_PRN_DBG("stat cache not hit by ETag[path=%s][time=%lld.%09ld][hit count=%lu][ETag(%s)!=(%s)]",
                    strpath.c_str(), static_cast<long long>(ent->cache_date.tv_sec), ent->cache_date.tv_nsec, ent->hit_count, petag ? petag : "null", stretag.c_str());
            }else{
                // hit 
                S3FS_PRN_DBG("stat cache hit [path=%s][time=%lld.%09ld][hit count=%lu]",
                    strpath.c_str(), static_cast<long long>(ent->cache_date.tv_sec), ent->cache_date.tv_nsec, ent->hit_count);

                if(pst!= NULL){
                    *pst= ent->stbuf;
                }
                if(meta != NULL){
                    *meta = ent->meta;
                }
                if(pisforce != NULL){
                    (*pisforce) = ent->isforce;
                }
                if (pisfake != NULL) {
                    (*pisfake) = ent->isfake;
                }
                ent->hit_count++;
  
                if(IsExpireIntervalType){
                    SetStatCacheTime(ent->cache_date);
                }
                return true;
            }

        }else{
            // timeout
            is_delete_cache = true;
        }
    }

    if(is_delete_cache){
        DelStat(strpath, /*lock_already_held=*/ true);
    }
    return false;
}