C ++, как смешать карту с круговым буфером? - PullRequest
4 голосов
/ 23 августа 2011

Интересно, возможно ли иметь карту, которая работала бы как круговой буфер повышения? Это означает, что он будет иметь ограниченный размер, и когда он достигнет своего ограниченного размера, он начнет перезаписывать первые вставленные элементы. Также я хочу быть в состоянии искать через такой буфер и find or create с [name]. Можно ли создать такую ​​вещь и как это сделать?

Ответы [ 3 ]

3 голосов
/ 23 августа 2011

То, что вы хотите, - это карта LRU (с наименьшим количеством использовавшихся недавно) или LRA (с наименьшим количеством добавленных недавно), в зависимости от ваших потребностей.

Реализации уже существуют.

1 голос
/ 23 августа 2011

Ну, я не думаю, что эта структура присутствует из коробки в boost (хотя может существовать в другом месте), поэтому вы должны ее создать.Я бы не рекомендовал использовать operator[](), по крайней мере, так как это реализовано в std::map, потому что это может затруднить отслеживание элементов, добавленных на карту (например, использование operator[]() со значением добавляет это пустое значениена карту) и перейти к более явным операциям get и put для добавления и извлечения элементов карты.

Что касается простейшей реализации, я бы использовал фактическое map в качестве хранилища,и deque для хранения добавленных элементов (не проверено):

template <typename K, typename V>
struct BoundedSpaceMap
{
    typedef std::map<K,V> map_t;
    typedef std::deque<K> deque_t;

    // ...
    typedef value_type map_t::value_type;
    // Reuse map's iterators
    typedef iterator map_t::iterator;

    // ...
    iterator begin() { return map_.begin(); }

    // put
    void put ( K k, V v)
    { map_.insert(std::make_pair(k,v));
      deque_.push_back(k);
      _ensure();  // ensure the size of the map, and remove the last element
    }

     // ...

private:
     map_t map_;
     deque_t deque_;

     void _ensure() { 
       if (deque_size() > LIMIT) { 
         map_.erase(deque_.front()); deque_.pop_front();
       }
     }
};
1 голос
/ 23 августа 2011

Ну, на самом деле это не «круговой буфер», поскольку для карты это не имеет особого смысла, но мы можем использовать простой массив без каких-либо дополнительных связанных списков или чего-либо еще.

Это называется закрытое хеширование - статья в вики резюмирует это довольно хорошо.Двойное хеширование используется чаще всего, поскольку оно позволяет избежать кластеризации (что приводит к снижению производительности), но имеет свои собственные проблемы (локальность).

Редактировать: поскольку вы хотите конкретную реализацию, я не думаю, что boostодин, но этот или этот были упомянуты в другом посте SO о закрытом хешировании ..

...