Subroutine of insertOnly() and grow() that doesn't bump count or grow table. This repeats a lot of the logic of insert(), but I decided performance trumps DRY.
| 156 | // Subroutine of insertOnly() and grow() that doesn't bump count or grow table. |
| 157 | // This repeats a lot of the logic of insert(), but I decided performance trumps DRY. |
| 158 | __hot void StringTable::_insertOnly(hash_t hash, entry_t entry) noexcept { |
| 159 | assert_precondition(entry.first); |
| 160 | assert_precondition(hash != hash_t::Empty); |
| 161 | ssize_t distance = 0; |
| 162 | auto maxDistance = _maxDistance; |
| 163 | // Walk along the table looking for an empty space: |
| 164 | size_t i; |
| 165 | for (i = indexOfHash(hash); _hashes[i] != hash_t::Empty; i = wrap(i + 1)) { |
| 166 | assert(distance < _count); |
| 167 | ssize_t itsDistance = wrap(i - indexOfHash(_hashes[i]) + _size); |
| 168 | if (itsDistance < distance) { |
| 169 | // Robin Hood hashing: Put new item where a less-distant existing item was: |
| 170 | std::swap(hash, _hashes[i]); |
| 171 | std::swap(entry, _entries[i]); |
| 172 | maxDistance = std::max(distance, maxDistance); |
| 173 | distance = itsDistance; |
| 174 | // Then continue, to find a new spot for the existing item we removed... |
| 175 | } |
| 176 | ++distance; |
| 177 | } |
| 178 | |
| 179 | // Now place the final item in the empty space: |
| 180 | _hashes[i] = hash; |
| 181 | _entries[i] = std::move(entry); |
| 182 | _maxDistance = std::max(distance, maxDistance); |
| 183 | } |
| 184 | |
| 185 | |
| 186 | #pragma mark - TABLE ALLOCATION: |
nothing calls this directly
no outgoing calls
no test coverage detected