Commit 794535e9 authored by tqcq's avatar tqcq
Browse files

fix expire cache

parent 0bafdc98
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -201,8 +201,10 @@ if(SLED_BUILD_TESTS)
  sled_add_test(NAME sled_ioc_test SRCS src/sled/ioc/ioc_test.cc)
  sled_add_test(NAME sled_inja_test SRCS src/sled/nonstd/inja_test.cc)
  sled_add_test(NAME sled_fsm_test SRCS src/sled/nonstd/fsm_test.cc)
  sled_add_test(NAME sled_cache_test SRCS src/sled/cache/lru_cache_test.cc
                src/sled/cache/fifo_cache_test.cc)
  sled_add_test(NAME sled_timestamp_test SRCS src/sled/units/timestamp_test.cc)
  sled_add_test(
    NAME sled_cache_test SRCS src/sled/cache/lru_cache_test.cc
    src/sled/cache/fifo_cache_test.cc src/sled/cache/expire_cache_test.cc)
endif(SLED_BUILD_TESTS)

if(SLED_BUILD_FUZZ)
+5 −0
Original line number Diff line number Diff line
@@ -9,6 +9,11 @@ namespace sled {
template<typename TKey, typename TValue>
class ExpireCache : public AbstractCache<TKey, TValue, ExpireCachePolicy<TKey>> {
public:
    ExpireCache(const TimeDelta &expire_time)
    {
        this->policy_.insert(std::make_shared<ExpireCachePolicy<TKey>>(expire_time));
    }

    ~ExpireCache() override = default;
};
}// namespace sled
+18 −0
Original line number Diff line number Diff line
#include <sled/cache/expire_cache.h>
#include <sled/system/thread.h>

TEST_SUITE("Expire Cache")
{
    TEST_CASE("Remove Expired Key")
    {
        sled::ExpireCache<int, int> expire_cache(sled::TimeDelta::Millis(25));
        expire_cache.Add(1, 1);
        REQUIRE(expire_cache.Has(1));
        CHECK_EQ(*expire_cache.Get(1), 1);

        sled::Thread::SleepMs(30);
        CHECK_FALSE(expire_cache.Has(1));
        CHECK(expire_cache.empty());
        CHECK_EQ(expire_cache.Get(1), nullptr);
    }
}
+9 −13
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@

#pragma once
#include "abstract_cache_policy.h"
#include "sled/time_utils.h"
#include "sled/units/timestamp.h"
#include <map>

@@ -12,12 +11,14 @@ namespace sled {
template<typename TKey>
class ExpireCachePolicy : public AbstractCachePolicy<TKey> {
public:
    ExpireCachePolicy(const TimeDelta &expire_time) : expire_time_(expire_time) {}

    ~ExpireCachePolicy() override = default;

    void OnAdd(const TKey &key) override
    {
        Timestamp now = Timestamp::Nanos(TimeNanos());
        auto iter     = key_index_.insert(std::make_pair(now, key));
        Timestamp cur_expire_time = Timestamp::Now() + expire_time_;
        auto iter                 = key_index_.insert(std::make_pair(cur_expire_time, key));
        keys_[key]                = iter;
    }

@@ -44,8 +45,7 @@ public:
    void OnReplace(std::set<TKey> &elems_to_remove) override
    {
        auto iter = key_index_.begin();
        Timestamp now = Timestamp::Nanos(TimeNanos());
        while (iter != key_index_.end() && iter->first < now) {
        while (iter != key_index_.end() && iter->first.IsExpired()) {
            elems_to_remove.insert(iter->second);
            ++iter;
        }
@@ -54,15 +54,11 @@ public:
    bool IsValid(const TKey &key) override
    {
        auto iter = keys_.find(key);
        if (iter != keys_.end()) {
            return iter->second->first + expire_time_ > Timestamp::Nanos(TimeNanos());
        } else {
            return false;
        }
        return iter != keys_.end() && !iter->second->first.IsExpired();
    }

private:
    TimeDelta expire_time_;
    const TimeDelta expire_time_;
    std::multimap<Timestamp, TKey> key_index_;
    std::map<TKey, typename std::multimap<Timestamp, TKey>::iterator> keys_;
};
+11 −2
Original line number Diff line number Diff line
@@ -41,9 +41,18 @@ public:
        BaseClass::OnClear();
    }

    void OnReplace(std::set<TKey> &key) override
    void OnReplace(std::set<TKey> &elems_to_remove) override
    {
        // do nothing
        BaseClass::OnReplace(elems_to_remove);

        if (keys_.size() <= size_) { return; }
        std::size_t diff  = keys_.size() - size_;
        std::size_t index = 0;
        auto iter         = keys_.begin();
        while (index++ < diff) {
            elems_to_remove.insert(*iter);
            if (iter != keys_.end()) { ++iter; }
        }
    }

    bool IsValid(const TKey &key) override { return BaseClass::IsValid(key); }
Loading