1 year ago

#362667

test-img

squishyvariably

Allocating with new and storing in LRU buffer, deletion does not happen?

I am implementing a simple cache of unordered maps allocating them with the new keyword, and I would like for the objects to be deleted when they are evicted from the cache. For reference, this is the LRU cache implementation I am using: https://github.com/facebook/hhvm/blob/master/hphp/util/concurrent-lru-cache.h

I am testing my program on Linux, 1 thread. The code is the following:

HPHP::ConcurrentLRUCache<std::string, std::unordered_map<int, int>*> my_cache(10);
for (int i = 0; i < 1000000; i++) {
    auto map = new std::unordered_map<int, int>(1000);
    for (int j = 0; j < 1000; j++)
        map->insert(std::make_pair(j, j));
    my_cache.insert(std::to_string(i), map);
}

template <class TKey, class TValue, class THash>
    bool ConcurrentLRUCache<TKey, TValue, THash>::
    insert(const TKey& key, const TValue& value) {
        // Insert into the CHM
        ListNode* node = new ListNode(key);
        HashMapAccessor hashAccessor;
        HashMapValuePair hashMapValue(key, HashMapValue(value, node));
        if (!m_map.insert(hashAccessor, hashMapValue)) {
            delete node;
            return false;
        }

        // Evict if necessary, now that we know the hashmap insertion was successful.
        size_t size = m_size.load();
        bool evictionDone = false;
        if (size >= m_maxSize) {
            evict();
            evictionDone = true;
        }

        std::unique_lock<ListMutex> lock(m_listMutex);
        pushFront(node);
        lock.unlock();
        if (!evictionDone) {
            size = m_size++;
        }
        if (size > m_maxSize) {
            if (m_size.compare_exchange_strong(size, size - 1)) {
                evict();
            }
        }
        return true;
    }

template <class TKey, class TValue, class THash>
    void ConcurrentLRUCache<TKey, TValue, THash>::
    evict() {
        std::unique_lock<ListMutex> lock(m_listMutex);
        ListNode* moribund = m_tail.m_prev;
        if (moribund == &m_head) {
            // List is empty, can't evict
            return;
        }
        delink(moribund);
        lock.unlock();

        HashMapAccessor hashAccessor;
        if (!m_map.find(hashAccessor, moribund->m_key)) {
            // Presumably unreachable
            return;
        }
        m_map.erase(hashAccessor);
        delete moribund;
    }

When inserting a map, if the cache is full, the last recently used element should get evicted. However, the map itself does not get deleted and the memory usage peaks. What am I doing wrong?

Note: the maps should be retrieved during the execution of my program, so they should be accessible from the cache.

c++

caching

memory-management

new-operator

0 Answers

Your Answer

Accepted video resources