Skip to content

Commit 249b567

Browse files
committed
Implement efficient clearing of the Hashtable
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.
1 parent 3b3fc5d commit 249b567

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

include/fixed_containers/fixed_doubly_linked_list.hpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct LinkedListIndices
1818
template <typename T, std::size_t MAXIMUM_SIZE, typename IndexType = std::size_t>
1919
class FixedDoublyLinkedListBase
2020
{
21+
protected:
2122
static_assert(MAXIMUM_SIZE + 1 <= std::numeric_limits<IndexType>::max(),
2223
"must be able to index MAXIMUM_SIZE+1 elements with IndexType");
2324
using StorageType = FixedIndexBasedPoolStorage<T, MAXIMUM_SIZE>;
@@ -52,11 +53,6 @@ class FixedDoublyLinkedListBase
5253
}
5354
[[nodiscard]] constexpr bool full() const noexcept { return storage().full(); }
5455

55-
constexpr void clear() noexcept
56-
{
57-
delete_range_and_return_next_index(front_index(), MAXIMUM_SIZE);
58-
}
59-
6056
constexpr const T& at(const IndexType i) const { return storage().at(i); }
6157
constexpr T& at(const IndexType i) { return storage().at(i); }
6258

@@ -227,6 +223,11 @@ class FixedDoublyLinkedList : public FixedDoublyLinkedListBase<T, MAXIMUM_SIZE,
227223
return *this;
228224
}
229225

226+
constexpr void clear() noexcept
227+
{
228+
this->delete_range_and_return_next_index(this->front_index(), MAXIMUM_SIZE);
229+
}
230+
230231
constexpr ~FixedDoublyLinkedList() noexcept { this->clear(); }
231232
};
232233

@@ -240,6 +241,22 @@ class FixedDoublyLinkedList<T, MAXIMUM_SIZE, IndexType>
240241
// clang-format off
241242
constexpr FixedDoublyLinkedList() noexcept : Base() { }
242243
// clang-format on
244+
245+
constexpr void clear() noexcept
246+
{
247+
// Instead of iterating over the elements of the linked list (slow), just reset the backing
248+
// storage
249+
this->IMPLEMENTATION_DETAIL_DO_NOT_USE_storage_ = std::move(typename Base::StorageType{});
250+
251+
// And reset the start/end sentinel to point at itself.
252+
// The remaining links of the linked list will be overwritten as elements are allocated, so
253+
// we don't have to reset the entire chain
254+
this->next_of(MAXIMUM_SIZE) = MAXIMUM_SIZE;
255+
this->prev_of(MAXIMUM_SIZE) = MAXIMUM_SIZE;
256+
257+
// Finally, set the size back to 0
258+
this->IMPLEMENTATION_DETAIL_DO_NOT_USE_size_ = 0;
259+
}
243260
};
244261

245262
} // namespace fixed_containers::fixed_doubly_linked_list_detail::specializations

include/fixed_containers/fixed_robinhood_hashtable.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,14 @@ class FixedRobinhoodHashtable
386386
return end_value_index;
387387
}
388388

389-
constexpr void clear() { erase_range(begin_index(), end_index()); }
389+
constexpr void clear()
390+
{
391+
// reset the backing linked list
392+
IMPLEMENTATION_DETAIL_DO_NOT_USE_value_storage_.clear();
393+
394+
// reset the bucket array
395+
IMPLEMENTATION_DETAIL_DO_NOT_USE_bucket_array_.fill({});
396+
}
390397

391398
public:
392399
constexpr FixedRobinhoodHashtable() = default;

0 commit comments

Comments
 (0)