fix expire cache
All checks were successful
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Successful in 1m30s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (push) Successful in 1m50s
linux-arm-gcc / linux-gcc-armhf (push) Successful in 2m15s
linux-x64-gcc / linux-gcc (Release) (push) Successful in 2m22s
linux-x64-gcc / linux-gcc (Debug) (push) Successful in 2m24s
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Successful in 3m6s
All checks were successful
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Successful in 1m30s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (push) Successful in 1m50s
linux-arm-gcc / linux-gcc-armhf (push) Successful in 2m15s
linux-x64-gcc / linux-gcc (Release) (push) Successful in 2m22s
linux-x64-gcc / linux-gcc (Debug) (push) Successful in 2m24s
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Successful in 3m6s
This commit is contained in:
parent
0bafdc98c7
commit
794535e9a1
@ -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
src/sled/cache/expire_cache.h
vendored
5
src/sled/cache/expire_cache.h
vendored
@ -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
src/sled/cache/expire_cache_test.cc
vendored
Normal file
18
src/sled/cache/expire_cache_test.cc
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
#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);
|
||||
}
|
||||
}
|
22
src/sled/cache/policy/expire_cache_policy.h
vendored
22
src/sled/cache/policy/expire_cache_policy.h
vendored
@ -3,7 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
#include "abstract_cache_policy.h"
|
||||
#include "sled/time_utils.h"
|
||||
#include "sled/units/timestamp.h"
|
||||
#include <map>
|
||||
|
||||
@ -12,13 +11,15 @@ 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));
|
||||
keys_[key] = iter;
|
||||
Timestamp cur_expire_time = Timestamp::Now() + expire_time_;
|
||||
auto iter = key_index_.insert(std::make_pair(cur_expire_time, key));
|
||||
keys_[key] = iter;
|
||||
}
|
||||
|
||||
void OnRemove(const TKey &key) override
|
||||
@ -43,9 +44,8 @@ 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) {
|
||||
auto iter = key_index_.begin();
|
||||
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_;
|
||||
};
|
||||
|
13
src/sled/cache/policy/fifo_cache_policy.h
vendored
13
src/sled/cache/policy/fifo_cache_policy.h
vendored
@ -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); }
|
||||
|
@ -27,18 +27,25 @@ public:
|
||||
static constexpr TimeDelta Seconds(T value)
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "");
|
||||
return FromFraction(1000000, value);
|
||||
return FromFraction(1000000000, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr TimeDelta Millis(T value)
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "");
|
||||
return FromFraction(1000, value);
|
||||
return FromFraction(1000000, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr TimeDelta Micros(T value)
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "");
|
||||
return FromFraction(1000, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr TimeDelta Nanos(T value)
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "");
|
||||
return FromValue(value);
|
||||
@ -47,7 +54,7 @@ public:
|
||||
template<typename Clock, typename Duration>
|
||||
inline TimeDelta(const std::chrono::duration<Clock, Duration> &duration)
|
||||
{
|
||||
*this = FromValue(std::chrono::duration_cast<std::chrono::microseconds>(duration).count());
|
||||
*this = FromValue(std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count());
|
||||
}
|
||||
|
||||
TimeDelta() = delete;
|
||||
@ -55,32 +62,34 @@ public:
|
||||
template<typename T = int64_t>
|
||||
constexpr T seconds() const
|
||||
{
|
||||
return ToFraction<1000000, T>();
|
||||
return ToFraction<1000000000, T>();
|
||||
}
|
||||
|
||||
template<typename T = int64_t>
|
||||
constexpr T ms() const
|
||||
{
|
||||
return ToFraction<1000, T>();
|
||||
return ToFraction<1000000, T>();
|
||||
}
|
||||
|
||||
template<typename T = int64_t>
|
||||
constexpr T us() const
|
||||
{
|
||||
return ToValue<T>();
|
||||
return ToFraction<1000, T>();
|
||||
}
|
||||
|
||||
template<typename T = int64_t>
|
||||
constexpr T ns() const
|
||||
{
|
||||
return ToMultiple<1000, T>();
|
||||
return ToValue<T>();
|
||||
}
|
||||
|
||||
constexpr int64_t seconds_or(int64_t fallback_value) const { return ToFractionOr<1000000>(fallback_value); }
|
||||
constexpr int64_t seconds_or(int64_t fallback_value) const { return ToFractionOr<1000000000>(fallback_value); }
|
||||
|
||||
constexpr int64_t ms_or(int64_t fallback_value) const { return ToFractionOr<1000>(fallback_value); }
|
||||
constexpr int64_t ms_or(int64_t fallback_value) const { return ToFractionOr<1000000>(fallback_value); }
|
||||
|
||||
constexpr int64_t us_or(int64_t fallback_value) const { return ToValueOr(fallback_value); }
|
||||
constexpr int64_t us_or(int64_t fallback_value) const { return ToFractionOr<1000>(fallback_value); }
|
||||
|
||||
constexpr int64_t ns_or(int64_t fallback_value) const { return ToValueOr(fallback_value); }
|
||||
|
||||
constexpr TimeDelta Abs() const { return us() < 0 ? TimeDelta::Micros(-us()) : *this; }
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
#ifndef SLED_UNITS_TIMESTAMP_H
|
||||
#define SLED_UNITS_TIMESTAMP_H
|
||||
#include "sled/time_utils.h"
|
||||
#include "sled/units/time_delta.h"
|
||||
#include "sled/units/unit_base.h"
|
||||
|
||||
@ -14,65 +15,71 @@ namespace sled {
|
||||
|
||||
class Timestamp final : public detail::UnitBase<Timestamp> {
|
||||
public:
|
||||
static Timestamp Now() { return Timestamp::Nanos(TimeNanos()); }
|
||||
|
||||
template<typename T>
|
||||
static constexpr Timestamp Seconds(T value)
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "");
|
||||
return FromFraction(1000000, value);
|
||||
return FromFraction(1000000000, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr Timestamp Millis(T value)
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "");
|
||||
return FromFraction(1000, value);
|
||||
return FromFraction(1000000, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr Timestamp Micros(T value)
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "");
|
||||
return FromValue(value);
|
||||
return FromFraction(1000, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr Timestamp Nanos(T value)
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "");
|
||||
return FromValue(value * 1000LL);
|
||||
return FromValue(value);
|
||||
}
|
||||
|
||||
Timestamp() = delete;
|
||||
|
||||
bool IsExpired() const { return *this < Now(); }
|
||||
|
||||
template<typename T = int64_t>
|
||||
constexpr T seconds() const
|
||||
{
|
||||
return ToFraction<1000000, T>();
|
||||
return ToFraction<1000000000, T>();
|
||||
}
|
||||
|
||||
template<typename T = int64_t>
|
||||
constexpr T ms() const
|
||||
{
|
||||
return ToFraction<1000, T>();
|
||||
return ToFraction<1000000, T>();
|
||||
}
|
||||
|
||||
template<typename T = int64_t>
|
||||
constexpr T us() const
|
||||
{
|
||||
return ToValue<T>();
|
||||
return ToFraction<1000, T>();
|
||||
}
|
||||
|
||||
template<typename T = int64_t>
|
||||
constexpr T ns() const
|
||||
{
|
||||
return ToMultiple<1000, T>();
|
||||
return ToValue<T>();
|
||||
}
|
||||
|
||||
constexpr int64_t seconds_or(int64_t fallback_value) const { return ToFractionOr<1000000>(fallback_value); }
|
||||
constexpr int64_t seconds_or(int64_t fallback_value) const { return ToFractionOr<1000000000>(fallback_value); }
|
||||
|
||||
constexpr int64_t ms_or(int64_t fallback_value) const { return ToFractionOr<1000>(fallback_value); }
|
||||
constexpr int64_t ms_or(int64_t fallback_value) const { return ToFractionOr<1000000>(fallback_value); }
|
||||
|
||||
constexpr int64_t us_or(int64_t fallback_value) const { return ToValueOr(fallback_value); }
|
||||
constexpr int64_t us_or(int64_t fallback_value) const { return ToFractionOr<1000>(fallback_value); }
|
||||
|
||||
constexpr int64_t ns_or(int64_t fallback_value) const { return ToValueOr(fallback_value); }
|
||||
|
||||
Timestamp operator+(const TimeDelta delta) const
|
||||
{
|
||||
@ -81,7 +88,7 @@ public:
|
||||
} else if (IsMinusInfinity() || delta.IsMinusInfinity()) {
|
||||
return MinusInfinity();
|
||||
}
|
||||
return Timestamp::Micros(us() - delta.us());
|
||||
return Timestamp::Nanos(ns() + delta.ns());
|
||||
}
|
||||
|
||||
Timestamp operator-(const TimeDelta delta) const
|
||||
@ -91,7 +98,7 @@ public:
|
||||
} else if (IsMinusInfinity() || delta.IsPlusInfinity()) {
|
||||
return MinusInfinity();
|
||||
}
|
||||
return Timestamp::Micros(us() - delta.us());
|
||||
return Timestamp::Nanos(ns() - delta.ns());
|
||||
}
|
||||
|
||||
TimeDelta operator-(const Timestamp other) const
|
||||
|
21
src/sled/units/timestamp_test.cc
Normal file
21
src/sled/units/timestamp_test.cc
Normal file
@ -0,0 +1,21 @@
|
||||
#include <sled/units/timestamp.h>
|
||||
|
||||
TEST_SUITE("Timestamp")
|
||||
{
|
||||
TEST_CASE("ToString")
|
||||
{
|
||||
CHECK_EQ(sled::ToString(sled::Timestamp::PlusInfinity()), "+inf ms");
|
||||
CHECK_EQ(sled::ToString(sled::Timestamp::MinusInfinity()), "-inf ms");
|
||||
CHECK_EQ(sled::ToString(sled::Timestamp::Micros(1)), "1 us");
|
||||
CHECK_EQ(sled::ToString(sled::Timestamp::Millis(1)), "1 ms");
|
||||
CHECK_EQ(sled::ToString(sled::Timestamp::Seconds(1)), "1 s");
|
||||
}
|
||||
|
||||
TEST_CASE("IsExpired")
|
||||
{
|
||||
auto passed = sled::Timestamp::Now() - sled::TimeDelta::Millis(1);
|
||||
CHECK(passed.IsExpired());
|
||||
auto future = sled::Timestamp::Now() + sled::TimeDelta::Millis(1);
|
||||
CHECK_FALSE(future.IsExpired());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user