Skip to content

Commit

Permalink
Implement efficient clearing of the Hashtable
Browse files Browse the repository at this point in the history
Instead of iterating over the linked list (also requires hash lookups)
and erasing one by one, just reset the backing linked list and value
storage, then 0 out the bucket array.
  • Loading branch information
Bobobalink committed Apr 12, 2024
1 parent 55857e1 commit a7c35b7
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
27 changes: 22 additions & 5 deletions include/fixed_containers/fixed_doubly_linked_list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct LinkedListIndices
template <typename T, std::size_t MAXIMUM_SIZE, typename IndexType = std::size_t>
class FixedDoublyLinkedListBase
{
protected:
static_assert(MAXIMUM_SIZE + 1 <= std::numeric_limits<IndexType>::max(),
"must be able to index MAXIMUM_SIZE+1 elements with IndexType");
using StorageType = FixedIndexBasedPoolStorage<T, MAXIMUM_SIZE>;
Expand Down Expand Up @@ -52,11 +53,6 @@ class FixedDoublyLinkedListBase
}
[[nodiscard]] constexpr bool full() const noexcept { return storage().full(); }

constexpr void clear() noexcept
{
delete_range_and_return_next_index(front_index(), MAXIMUM_SIZE);
}

constexpr const T& at(const IndexType i) const { return storage().at(i); }
constexpr T& at(const IndexType i) { return storage().at(i); }

Expand Down Expand Up @@ -227,6 +223,11 @@ class FixedDoublyLinkedList : public FixedDoublyLinkedListBase<T, MAXIMUM_SIZE,
return *this;
}

constexpr void clear() noexcept
{
this->delete_range_and_return_next_index(this->front_index(), MAXIMUM_SIZE);
}

constexpr ~FixedDoublyLinkedList() noexcept { this->clear(); }
};

Expand All @@ -240,6 +241,22 @@ class FixedDoublyLinkedList<T, MAXIMUM_SIZE, IndexType>
// clang-format off
constexpr FixedDoublyLinkedList() noexcept : Base() { }
// clang-format on

constexpr void clear() noexcept
{
// Instead of iterating over the elements of the linked list (slow), just reset the backing
// storage
this->IMPLEMENTATION_DETAIL_DO_NOT_USE_storage_ = std::move(typename Base::StorageType{});

// And reset the start/end sentinel to point at itself.
// The remaining links of the linked list will be overwritten as elements are allocated, so
// we don't have to reset the entire chain
this->next_of(MAXIMUM_SIZE) = MAXIMUM_SIZE;
this->prev_of(MAXIMUM_SIZE) = MAXIMUM_SIZE;

// Finally, set the size back to 0
this->IMPLEMENTATION_DETAIL_DO_NOT_USE_size_ = 0;
}
};

} // namespace fixed_containers::fixed_doubly_linked_list_detail::specializations
Expand Down
9 changes: 8 additions & 1 deletion include/fixed_containers/fixed_robinhood_hashtable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,14 @@ class FixedRobinhoodHashtable
return end_value_index;
}

constexpr void clear() { erase_range(begin_index(), end_index()); }
constexpr void clear()
{
// reset the backing linked list
IMPLEMENTATION_DETAIL_DO_NOT_USE_value_storage_.clear();

// reset the bucket array
IMPLEMENTATION_DETAIL_DO_NOT_USE_bucket_array_.fill({});
}

public:
constexpr FixedRobinhoodHashtable() = default;
Expand Down

0 comments on commit a7c35b7

Please sign in to comment.