Авто истекающий словарь - PullRequest
0 голосов
/ 27 апреля 2018

Мне нужна библиотека, которая предлагает структуру данных в памяти, такую, которую я могу записать, например:

cache.insert(key,value,expiry)

и я могу получить значение с чем-то вроде cache[key], если только оно не истекло.

Может быть сделано? Какую библиотеку мне использовать?

Предпочитайте библиотеки для D, если это возможно

1 Ответ

0 голосов
/ 27 апреля 2018

Я не знаю ни о какой библиотеке, которая делает это. С другой стороны, это не так много работы, чтобы заставить что-то работать. Вот что я набросал за десять минут:

struct Dict(K, V, E)
if (isExpiry!E)
{
    import std.typecons : Tuple;
private:
    Tuple!(V, "value", E, "expiry")[K] _payload;
public:
    V opIndex(K key)
    {
        return *(key in this);
    }

    V* opBinaryRight(string op : "in")(K key)
    {
        auto p = key in _payload;
        if (!p || p.expiry.expired) return null;
        return &p.value;
    }

    void insert(K key, V value, E expiry)
    {
        expiry.initialize();
        _payload[key] = typeof(_payload[key])(value, expiry);
    }

    void remove(K key)
    {
        _payload.remove(key);
    }
}

enum isExpiry(T) = is(typeof((T t){
        t.initialize();
        if (t.expired) {}
    }));
static assert(!isExpiry!int);

struct Timeout
{
    import core.time;
    Duration duration;
    MonoTime start;

    void initialize() {
        start = MonoTime.currTime;
    }

    @property
    bool expired()
    {
        auto elapsed = MonoTime.currTime - start;
        return elapsed > duration;
    }
}
static assert(isExpiry!Timeout);

unittest
{
    import core.time;
    import core.thread;
    Dict!(int, string, Timeout) a;
    assert(3 !in a);
    a.insert(3, "a", Timeout(100.dur!"msecs"));
    a.insert(4, "b", Timeout(10.dur!"days"));
    assert(3 in a);
    assert(4 in a);
    Thread.sleep(200.dur!"msecs");
    assert(3 !in a);
    assert(4 in a);
    a.remove(4);
    assert(4 !in a);
}
...