35 bool operator()(
const T &a,
const T &b)
const {
return a == b; }
42#ifndef FASTLED_HASHMAP_INLINED_COUNT
43#define FASTLED_HASHMAP_INLINED_COUNT 8
46template <
typename Key,
typename T,
typename Hash = Hash<Key>,
47 typename KeyEqual = EqualTo<Key>,
48 int INLINED_COUNT = FASTLED_HASHMAP_INLINED_COUNT>
52 float max_load = 0.7f)
80 return {e.key, e.value};
108 size_t cap =
_map->_buckets.size();
135 return {e.key, e.value};
163 size_t cap =
_map->_buckets.size();
176 iterator
begin() {
return iterator(
this, 0); }
178 const_iterator
begin()
const {
return const_iterator(
this, 0); }
179 const_iterator
end()
const {
return const_iterator(
this,
_buckets.size()); }
180 const_iterator
cbegin()
const {
return const_iterator(
this, 0); }
182 return const_iterator(
this,
_buckets.size());
186 uint8_t load_factor) {
189 uint32_t lhs = (
size + tombstones) << 8;
190 uint32_t rhs = (bucket_size * load_factor);
222 FASTLED_ASSERT(idx !=
npos,
"HashMap::insert: invalid index at "
223 << idx <<
" which is " <<
npos);
261 return idx ==
npos ?
end() : iterator(
this, idx);
266 return idx ==
npos ?
end() : const_iterator(
this, idx);
291 static constexpr size_t npos = size_t(-1);
335 const size_t mask = cap - 1;
336 const size_t h =
_hash(key) & mask;
337 size_t first_tomb =
npos;
341 for (
size_t i = 0; i < cap; ++i) {
342 const size_t idx = (h + i) & mask;
345 return {first_tomb !=
npos ? first_tomb : idx,
true};
347 if (first_tomb ==
npos)
357 const size_t idx = (h + i + i * i) & mask;
360 return {first_tomb !=
npos ? first_tomb : idx,
true};
362 if (first_tomb ==
npos)
369 for (; i < cap; ++i) {
370 const size_t idx = (h + i) & mask;
373 return {first_tomb !=
npos ? first_tomb : idx,
true};
375 if (first_tomb ==
npos)
383 return {
npos,
false};
393 const size_t mask = cap - 1;
394 const size_t h =
_hash(key) & mask;
398 for (
size_t i = 0; i < cap; ++i) {
399 const size_t idx = (h + i) & mask;
409 const size_t idx = (h + i + i * i) & mask;
416 for (; i < cap; ++i) {
417 const size_t idx = (h + i) & mask;
431 const size_t mask = cap - 1;
432 const size_t h =
_hash(key) & mask;
436 for (
size_t i = 0; i < cap; ++i) {
437 const size_t idx = (h + i) & mask;
438 bool occupied = occupied_set.
test(idx);
448 const size_t idx = (h + i + i * i) & mask;
449 bool occupied = occupied_set.
test(idx);
456 for (; i < cap; ++i) {
457 const size_t idx = (h + i) & mask;
458 bool occupied = occupied_set.
test(idx);
484 for (
size_t i = 0; i < old.
size(); i++) {
485 if (old_occupied.
test(i))
486 insert(old[i].key, old[i].value);
495 for (
size_t i = 0; i < cap; ++i) {
513 for (
size_t i = 0; i <
_size; ++i) {
514 const bool already_finished = occupied.
test(i);
515 if (already_finished) {
527 false,
"HashMap::rehash_inline_no_resize: invalid index at "
528 << idx <<
" which is " <<
npos);
533 "HashMap::rehash_inline_no_resize: invalid tmp");
542 while (!tmp.
empty()) {
545 auto key = tmp.
ptr()->key;
548 if (new_idx ==
npos) {
552 "HashMap::rehash_inline_no_resize: invalid index at "
553 << new_idx <<
" which is " <<
npos);
556 occupied.
set(new_idx);
557 if (new_idx <
_size) {
570 "HashMap::rehash_inline_no_resize: invalid occupied at " << i);
572 !tmp,
"HashMap::rehash_inline_no_resize: invalid tmp at " << i);
589template <
typename Key,
typename T,
typename Hash = Hash<Key>,
590 typename KeyEqual = equal_to<Key>>
593template <
typename Key,
typename T,
typename Hash = Hash<Key>,
594 typename KeyEqual = equal_to<Key>>
bool test(uint32_t pos) const noexcept
Tests whether the bit at position pos is set.
BitsetInlined & set(uint32_t pos, bool value=true)
Sets or clears the bit at position pos.
void mark_occupied(size_t idx)
static size_t next_power_of_two(size_t n)
void mark_deleted(size_t idx)
static constexpr size_t npos
void mark_empty(size_t idx)
T & operator[](const Key &key)
bool erase(const Key &key)
const T * find_value(const Key &key) const
void rehash_inline_no_resize()
bool is_empty(size_t idx) const
const_iterator cend() const
HashMap(size_t initial_capacity=FASTLED_HASHMAP_INLINED_COUNT, float max_load=0.7f)
size_t find_index(const Key &key) const
T * find_value(const Key &key)
size_t find_unoccupied_index_using_bitset(const Key &key, const fl::bitset< 1024 > &occupied_set) const
fl::bitset< 1024 > _deleted
bool remove(const Key &key)
void rehash(size_t new_cap)
const_iterator end() const
bool is_occupied(size_t idx) const
static bool NeedsRehash(size_t size, size_t bucket_size, size_t tombstones, uint8_t load_factor)
const_iterator find(const Key &key) const
fl::bitset< 1024 > _occupied
pair< size_t, bool > find_slot(const Key &key) const
fl::vector_inlined< Entry, FASTLED_HASHMAP_INLINED_COUNT > _buckets
void setLoadFactor(float f)
const_iterator begin() const
const_iterator cbegin() const
void insert(const Key &key, const T &value)
bool needs_rehash() const
iterator find(const Key &key)
bool is_deleted(size_t idx) const
#define FASTLED_HASHMAP_INLINED_COUNT
BitsetInlined< N > bitset
void swap(array< T, N > &lhs, array< T, N > &rhs) noexcept(noexcept(lhs.swap(rhs)))
InlinedVector< T, INLINED_SIZE > vector_inlined
FASTLED_FORCE_INLINE T clamp(T value, T min, T max)
HashMap< Key, T, Hash, KeyEqual > hash_map
HashMap< Key, T, Hash, KeyEqual > unordered_map
FASTLED_FORCE_INLINE U map_range(T value, T in_min, T in_max, U out_min, U out_max)
Implements a simple red square effect for 2D LED grids.
static FASTLED_NAMESPACE_BEGIN uint8_t const p[]
bool operator()(const T &a, const T &b) const
void advance_to_occupied()
const_iterator operator++(int)
const value_type * pointer
const_iterator & operator++()
bool operator==(const const_iterator &o) const
value_type operator*() const
const_iterator(const iterator &it)
pair< const Key, T > value_type
bool operator!=(const const_iterator &o) const
const_iterator(const HashMap *m, size_t idx)
const value_type & reference
pointer operator->() const
void advance_to_occupied()
pair< const Key, T > value_type
value_type operator*() const
bool operator!=(const iterator &o) const
bool operator==(const iterator &o) const
iterator(HashMap *m, size_t idx)