hash_table.hpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #ifndef SIMPLE_COMPRESS_HASH_TABLE_HPP
  2. #define SIMPLE_COMPRESS_HASH_TABLE_HPP
  3. #include <cstddef> // std::size_t
  4. #include <vector> // std::vector std::hash
  5. #include <algorithm> // std::partition std::max
  6. #include <functional> // std::not_fn
  7. namespace simple::compress
  8. {
  9. // why make own map? cause std devour all memory and never give it back
  10. template <typename Key, typename Value, std::size_t row_count>
  11. class hash_table
  12. {
  13. // TODO; make these contiguous, the buckets often end up very small
  14. std::vector<std::vector<Value>> table{row_count};
  15. std::size_t size_{0};
  16. template <typename T>
  17. static auto& row(T& self, const Key& key)
  18. {
  19. return self.table[std::hash<Key>{}(key) % row_count];
  20. }
  21. public:
  22. using key_type = Key;
  23. using value_type = Value;
  24. auto& equal_range(const Key& key)
  25. {
  26. return row(*this,key);
  27. }
  28. auto& equal_range(const Key& key) const
  29. {
  30. return row(*this,key);
  31. }
  32. void insert(const Key& key, const Value& value)
  33. {
  34. row(*this,key).push_back(value);
  35. ++size_;
  36. }
  37. template <typename Pred>
  38. void erase_if(Pred&& pred)
  39. {
  40. size_ = 0;
  41. for(auto& row : table)
  42. {
  43. row.erase(std::partition(row.begin(), row.end(), std::not_fn(pred)), row.end());
  44. size_ += row.size();
  45. }
  46. }
  47. std::size_t size() { return size_; }
  48. struct stats_t
  49. {
  50. std::size_t total_elements;
  51. std::size_t non_empty_rows;
  52. std::size_t max_row_size;
  53. };
  54. stats_t stats()
  55. {
  56. stats_t s{};
  57. for(auto&& row : table)
  58. s.total_elements += row.size(), s.non_empty_rows += bool(row.size()), s.max_row_size = std::max(s.max_row_size, row.size());
  59. return s;
  60. }
  61. };
  62. } // namespace simple::compress
  63. #endif /* end of include guard */