Есть ли способ ограничить размер карты STL? - PullRequest
15 голосов
/ 26 апреля 2010

Я хочу реализовать некоторую таблицу поиска в C ++, которая будет действовать как кеш. Он предназначен для имитации части аппаратного обеспечения, которое я имитирую.

Ключи не целочисленные, поэтому я предполагаю, что хэш в порядке. Я не собираюсь изобретать колесо, поэтому намерен использовать для этого std::map (хотя предложения по альтернативам приветствуются).

Вопрос в том, есть ли способ ограничить размер хэша, чтобы эмулировать тот факт, что мое оборудование имеет конечный размер? Я ожидаю, что метод хеша insert вернет сообщение об ошибке или сгенерирует исключение, если достигнут предел.

Если такого способа нет, я просто проверю его размер, прежде чем пытаться вставить, но это выглядит неэффективным способом сделать это.

Ответы [ 3 ]

9 голосов
/ 26 апреля 2010

Прежде всего, структура map - это не hash table, а скорее сбалансированное двоичное дерево. Это влияет на время поиска O(log N) вместо O(1) для оптимальной реализации хеширования. Это может повлиять или не повлиять на вашу проблему (если количество реальных ключей и операций невелико, этого может быть достаточно, но эмуляция кэша может быть как-то неоптимальной.

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

class cache {
public:
   static const int max_size = 100;
   typedef std::map<key_t, value_t> cache_map_t;
   void add( key_t key, value_t value ) {
      cache_map_t::const_iterator it = m_table.find( key );
      if ( it != m_table.end() && m_table.size() == max_size ) { 
         // handle error, throw exception...
      } else {
         m_table.insert( it, std::make_pair(key,value) );
      }
   }
private:
   cache_map_t m_table;
};
// Don't forget, in just one translation unit:
const int cache::max_size;
4 голосов
/ 26 апреля 2010

Нет способа "автоматически" ограничить размер std::map просто потому, что "ограниченное std::map" больше не будет std::map.

Оберните std::map в свой собственный класс, который просто проверяет размер std::map по отношению к константе перед вставкой и делает все, что вы хотите, в случае достижения максимального размера.

2 голосов
/ 26 апреля 2010

Если вы используете кеш LRU или аналогичный, я обнаружил, что boost :: bimap неоценим. Используйте один индекс в качестве основного ключа «идентификатора объекта» (который может быть эффективным векторным представлением, если у вас есть простое перечисление объектов), а другой индекс может быть упорядоченной временной меткой.

...