@@ -79,42 +79,52 @@ dynamic_map<Key, Value, Scope, Allocator>::dynamic_map(std::size_t initial_capac
7979template <typename Key, typename Value, cuda::thread_scope Scope, typename Allocator>
8080void dynamic_map<Key, Value, Scope, Allocator>::reserve(std::size_t n, cudaStream_t stream)
8181{
82- std:: size_t num_elements_remaining = n;
83- std::size_t submap_idx = 0 ;
84- while (num_elements_remaining > 0 ) {
85- std::size_t submap_capacity;
86-
87- // if the submap already exists
88- if (submap_idx < submaps_. size () ) {
89- submap_capacity = submaps_[submap_idx]-> get_capacity () ;
82+ // Calculate current total available capacity across all submaps
83+ std::size_t total_available_capacity = 0 ;
84+ for (std:: size_t i = 0 ; i < submaps_. size (); ++i ) {
85+ std::size_t submap_usable_capacity =
86+ static_cast <std:: size_t >(max_load_factor_ * submaps_[i]-> get_capacity ());
87+ // Only count capacity above the minimum insert threshold
88+ if (submap_usable_capacity >= min_insert_size_ ) {
89+ total_available_capacity += submap_usable_capacity - min_insert_size_ ;
9090 }
91- // if the submap does not exist yet, create it
92- else {
93- submap_capacity = capacity_;
94- if (erased_key_sentinel_ != empty_key_sentinel_) {
95- submaps_.push_back (std::make_unique<cuco::legacy::static_map<Key, Value, Scope, Allocator>>(
96- submap_capacity,
97- empty_key<Key>{empty_key_sentinel_},
98- empty_value<Value>{empty_value_sentinel_},
99- erased_key<Key>{erased_key_sentinel_},
100- alloc_,
101- stream));
102- } else {
103- submaps_.push_back (std::make_unique<cuco::legacy::static_map<Key, Value, Scope, Allocator>>(
104- submap_capacity,
105- empty_key<Key>{empty_key_sentinel_},
106- empty_value<Value>{empty_value_sentinel_},
107- alloc_,
108- stream));
109- }
110- submap_num_successes_.push_back (submaps_[submap_idx]->num_successes_ );
111- submap_views_.push_back (submaps_[submap_idx]->get_device_view ());
112- submap_mutable_views_.push_back (submaps_[submap_idx]->get_device_mutable_view ());
113- capacity_ *= 2 ;
91+ }
92+
93+ // Create new submaps until we have enough capacity
94+ while (total_available_capacity < n) {
95+ std::size_t new_submap_capacity = capacity_;
96+
97+ if (erased_key_sentinel_ != empty_key_sentinel_) {
98+ submaps_.push_back (std::make_unique<cuco::legacy::static_map<Key, Value, Scope, Allocator>>(
99+ new_submap_capacity,
100+ empty_key<Key>{empty_key_sentinel_},
101+ empty_value<Value>{empty_value_sentinel_},
102+ erased_key<Key>{erased_key_sentinel_},
103+ alloc_,
104+ stream));
105+ } else {
106+ submaps_.push_back (std::make_unique<cuco::legacy::static_map<Key, Value, Scope, Allocator>>(
107+ new_submap_capacity,
108+ empty_key<Key>{empty_key_sentinel_},
109+ empty_value<Value>{empty_value_sentinel_},
110+ alloc_,
111+ stream));
114112 }
115113
116- num_elements_remaining -= max_load_factor_ * submap_capacity - min_insert_size_;
117- submap_idx++;
114+ std::size_t submap_idx = submaps_.size () - 1 ;
115+ submap_num_successes_.push_back (submaps_[submap_idx]->num_successes_ );
116+ submap_views_.push_back (submaps_[submap_idx]->get_device_view ());
117+ submap_mutable_views_.push_back (submaps_[submap_idx]->get_device_mutable_view ());
118+
119+ // Add the new submap's usable capacity
120+ std::size_t new_usable_capacity =
121+ static_cast <std::size_t >(max_load_factor_ * new_submap_capacity);
122+ if (new_usable_capacity >= min_insert_size_) {
123+ total_available_capacity += new_usable_capacity - min_insert_size_;
124+ }
125+
126+ // Update capacity for next submap (double the size)
127+ capacity_ *= 2 ;
118128 }
119129}
120130
0 commit comments