Rehash the inline buckets without resizing
| 1005 | |
| 1006 | // Rehash the inline buckets without resizing |
| 1007 | FL_DISABLE_WARNING_PUSH |
| 1008 | FL_DISABLE_WARNING_NULL_DEREFERENCE |
| 1009 | void rehash_inline_no_resize() { |
| 1010 | // filter out tombstones and compact |
| 1011 | fl::size cap = _buckets.size(); |
| 1012 | fl::size pos = 0; |
| 1013 | // compact live elements to the left. |
| 1014 | for (fl::size i = 0; i < cap; ++i) { |
| 1015 | if (is_occupied(i)) { |
| 1016 | if (pos != i) { |
| 1017 | _buckets[pos] = fl::move(_buckets[i]); |
| 1018 | mark_empty(i); |
| 1019 | mark_occupied(pos); |
| 1020 | } |
| 1021 | ++pos; |
| 1022 | } else if (is_deleted(i)) { |
| 1023 | mark_empty(i); |
| 1024 | } |
| 1025 | } |
| 1026 | |
| 1027 | fl::bitset<1024> occupied; // Preallocate a bitset of size 1024 |
| 1028 | // swap the components, this will happen at most N times, |
| 1029 | // use the occupied bitset to track which entries are occupied |
| 1030 | // in the array rather than just copied in. |
| 1031 | fl::optional<Entry> tmp; |
| 1032 | for (fl::size i = 0; i < _size; ++i) { |
| 1033 | const bool already_finished = occupied.test(i); |
| 1034 | if (already_finished) { |
| 1035 | continue; |
| 1036 | } |
| 1037 | auto &e = _buckets[i]; |
| 1038 | // FASTLED_ASSERT(e.state == EntryState::Occupied, |
| 1039 | // "unordered_map::rehash_inline_no_resize: invalid |
| 1040 | // state"); |
| 1041 | |
| 1042 | fl::size idx = find_unoccupied_index_using_bitset(e.key, occupied); |
| 1043 | if (idx == npos()) { |
| 1044 | // no more space |
| 1045 | FASTLED_ASSERT( |
| 1046 | false, "unordered_map::rehash_inline_no_resize: invalid index at " |
| 1047 | << idx << " which is " << npos()); |
| 1048 | return; |
| 1049 | } |
| 1050 | // if idx < pos then we are moving the entry to a new location |
| 1051 | FASTLED_ASSERT(!tmp, |
| 1052 | "unordered_map::rehash_inline_no_resize: invalid tmp"); |
| 1053 | if (idx >= _size) { |
| 1054 | // directly move it now |
| 1055 | _buckets[idx] = fl::move(e); |
| 1056 | continue; |
| 1057 | } |
| 1058 | tmp = fl::move(e); |
| 1059 | occupied.set(idx); |
| 1060 | _buckets[idx] = fl::move(*tmp.ptr()); |
| 1061 | while (!tmp.empty()) { |
| 1062 | // we have to find a place for temp. |
| 1063 | // find new position for tmp. |
| 1064 | auto key = tmp.ptr()->key; |
no test coverage detected