LRU cache

So, I was asked to implement an LRU cache a few years ago in an interview with Oracle, which I couldn’t quite solve on my own in O(1). Recently I found this problem on LeetCode and I can say this time it was not a big deal, here is my solution.

#include <iostream>

#include <list>
#include <optional>
using std::list;

#include <unordered_map>
#include <cassert>

using std::unordered_map;

struct Entry {
    int key, value;
};

class LRUCache {
private:
    size_t capacity;
    list<Entry> L;
    unordered_map<int, list<Entry>::iterator> M;

public:
    explicit LRUCache(size_t capacity) {
        this->capacity = capacity;
    }

    int get(int key) {
        if (M.count(key) == 0) {
            return -1;
        }

        // Move entry to the front
        auto it = M[key];
        L.erase(it);

        L.push_front({*it});
        M[key] = L.begin();

        return it->value;
    }

    void put(int key, int value) {
        if (M.count(key) == 1) {
            // Move existing entry to the front
            L.erase(M[key]);
            L.push_front({key, value});
            M[key] = L.begin();
            return;
        }

        // Evict least-recently used entry
        if (L.size() >= capacity) {
            auto it = std::prev(L.end());
            M.erase(it->key);
            L.erase(it);
        }

        // Insert new entry at the front
        L.push_front({key, value});
        M[key] = L.begin();
    }
};

int main() {
    LRUCache cache(5);
    for (int v : {1, 2, 3, 4, 5}) {
        cache.put(v, 2 * v);
    }

    // At this point, the cache is full, so the first element inserted(1) should be evicted
    cache.put(6, 2 * 6);
    assert(cache.get(1) == -1);

    // This should bring 2 to the front and send 3 to the last position
    assert(cache.get(2) == 4);

    // This should put 7 in the first position and evict 3
    cache.put(7, 2 * 7);
    assert(cache.get(3) == -1);

    return EXIT_SUCCESS;
}

I know, my tests are not exhaustive, but hey, it’s better than nothing and it was accepted. I hope you find it kind of interesting and more importantly, that it could help you understand how this data structure works.


Posted

in

by

Tags: