LOCAL_CACHE_TEMPLATE typename LOCAL_CACHE_CLASS::result LOCAL_CACHE_CLASS::get(const KeyT& key, ValueT& value) { // lock if (capacity < 1) { return MISS; } tbsys::CThreadGuard guard(&mutex); entry_cache_iterator iter = cache.find(&key); if (iter == cache.end()) { return MISS; } // adjust lru list lru.splice(lru.begin(), lru, iter->second); // whatever, find entry, fill value fill_value(iter, value); // check whether entry was expired uint64_t now = tbutil::Time::now().toMilliSeconds(); assert(expire != 0); if (now - entry_utime(iter) > expire) { // expired set_entry_utime(iter->second, now); return EXPIRED; } else { // fresh entry return HIT; } }
LOCAL_CACHE_TEMPLATE typename LOCAL_CACHE_CLASS::result LOCAL_CACHE_CLASS::put_if_absent(const KeyT &key, const ValueT &val, ValueT &curtVal) { if (capacity < 1) { return MISS; } result res = MISS; // lock tbsys::CThreadGuard guard(&mutex); entry_cache_iterator iter = cache.find(&key); internal_entry *entry = NULL; if (iter == cache.end()) { res = MISS; // not found // evict entry while (cache.size() >= capacity) { assert(capacity >= 1); const internal_entry *evict = evict_one(); assert(evict != NULL); // free entry drop_entry(evict); } // insert new one // allocate internal_entry, relase after evict or in clear() entry = make_entry(key, val); if (entry == NULL) { return SETERROR; } lru.push_front(entry); cache[entry->get_key()] = lru.begin(); curtVal = val; } else { res = HIT; // found, already exists // adjust lru list lru.splice(lru.begin(), lru, iter->second); // update entry value and utime // update first, some meta info fill_value(iter, curtVal); uint64_t now = tbutil::Time::now().toMilliSeconds(); assert(expire != 0); if (now - entry_utime(iter) > expire) { // expired set_entry_utime(iter->second, now); res = EXPIRED; } } return res; }