Skip to content
An open addressing linear probing hash table, tuned for delete heavy workloads
C++ CMake
Branch: master
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
include/rigtorp Update to modern cmake layout Sep 13, 2018
src Fix clang compile warning Sep 13, 2018
vendor Add cited by secctions Sep 25, 2019
.clang-format Initial commit Dec 9, 2015
.gitignore Update gitignore to ignore CLion files Sep 13, 2018
.travis.yml Update to new travis-ci compilers Sep 13, 2018
CMakeLists.txt Update to modern cmake layout Sep 13, 2018
LICENSE Rename tests and cleanup Mar 29, 2016
README.md Add cited by secctions Sep 25, 2019

README.md

HashMap.h

Build Status License

A hash table mostly compatible with the C++11 std::unordered_map interface, but with much higher performance for many workloads.

Implementation

This hash table uses open addressing with linear probing and backshift deletion. Open addressing and linear probing minimizes memory allocations and achives high cache effiency. Backshift deletion keeps performance high for delete heavy workloads by not clobbering the hash table with tombestones.

Usage

HashMap is mostly compatible with the C++11 container interface. The main differences are:

  • A key value to represent the empty key is required.
  • Key and T needs to be default constructible.
  • Iterators are invalidated on all modifying operations.
  • It's invalid to perform any operations with the empty key.
  • Destructors are not called on erase.
  • Extensions for lookups using related key types.

Member functions:

  • HashMap(size_type bucket_count, key_type empty_key);

    Construct a HashMap with bucket_count buckets and empty_key as the empty key.

The rest of the member functions are implemented as for std::unordered_map.

Example

  using namespace rigtorp;

  // Hash for using std::string as lookup key
  struct Hash {
    size_t operator()(int v) { return v * 7; }
    size_t operator()(const std::string &v) { return std::stoi(v) * 7; }
  };

  // Equal comparison for using std::string as lookup key
  struct Equal {
    bool operator()(int lhs, int rhs) { return lhs == rhs; }
    bool operator()(int lhs, const std::string &rhs) {
      return lhs == std::stoi(rhs);
    }
  };

  // Create a HashMap with 16 buckets and 0 as the empty key
  HashMap<int, int, Hash, Equal> hm(16, 0);
  hm.emplace(1, 1);
  hm[2] = 2;

  // Iterate and print key-value pairs
  for (const auto &e : hm) {
    std::cout << e.first << " = " << e.second << "\n";
  }

  // Lookup using std::string
  std::cout << hm.at("1") << "\n";

  // Erase entry
  hm.erase(1);

Benchmark

The benchmark first inserts 1M random entries in the table and then removes the last inserted item and inserts a new random entry 1 billion times. This is benchmark is designed to simulate a delete heavy workload.

Implementation ns/iter
HashMap 77
google::dense_hash_map 122
std::unordered_map 220

Cited by

HashMap has been cited by the following papers:

About

This project was created by Erik Rigtorp <erik@rigtorp.se>.

You can’t perform that action at this time.