Changeset e912cdf in mainline
- Timestamp:
- 2018-07-05T21:41:21Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5ae8168
- Parents:
- ed9df7d
- git-author:
- Dzejrou <dzejrou@…> (2018-04-25 16:45:01)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:21)
- Location:
- uspace/lib/cpp/include
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/impl/unordered_map.hpp
red9df7d re912cdf 241 241 pair<iterator, bool> emplace(Args&&... args) 242 242 { 243 // TODO: currently there is code repetition in 244 // 3 places, try to find a way to reduce it 243 /** 244 * Note: Some of these modifier functions start off 245 * by incrementing the table's element count and 246 * decrement it when insertion does not take place. 247 * This is because we need to cause rehashing if 248 * there are too many elements, but rehashing itself 249 * would invalidate all pointers we get from 250 * find_insertion_spot, which would require us to 251 * do another find. But this way we avoid two searches 252 * with the possibility of a rehash that is not necessary 253 * (but hardly a bad thing as the table needs just one 254 * element more to rehash). 255 * 256 * Also, there are 3 functions with similar bodies, 257 * but the duplicit code cannot be moved to a common 258 * sub-function because all three require different 259 * handling of the value (move, forward and copy). 260 */ 261 table_.increment_size(); 262 245 263 auto val = value_type{forward<Args>(args)...}; 246 264 auto key = table_.get_key(val); … … 249 267 auto idx = get<2>(spot); 250 268 251 if (bucket->head) 269 if (!bucket) 270 return make_pair(end(), false); 271 272 auto target = table_.find_node_or_return_head(key, *bucket); 273 if (target && table_.keys_equal(key, target->value)) 252 274 { 253 auto head = bucket->head; 254 auto current = bucket->head; 255 256 do 257 { 258 if (table_.keys_equal(key, current->value)) 259 { 260 return make_pair(iterator{ 261 table_.table(), idx, 262 table_.bucket_count(), 263 current 264 }, false); 265 } 266 else 267 current = current->next; 268 } 269 while (current != head); 275 table_.decrement_size(); 276 return make_pair( 277 iterator{ 278 table_.table(), idx, table_.bucket_count(), 279 target 280 }, 281 false 282 ); 270 283 } 271 272 auto node = new node_type{move(val)}; 273 bucket->append(node); 274 table_.increment_size(); 275 276 return make_pair(iterator{ 277 table_.table(), idx, 278 table_.bucket_count(), 279 node 280 }, true); 284 else 285 { 286 auto node = new node_type{move(val)}; 287 bucket->append(node); 288 289 return make_pair(iterator{ 290 table_.table(), idx, 291 table_.bucket_count(), 292 node 293 }, true); 294 } 281 295 } 282 296 … … 289 303 pair<iterator, bool> insert(const value_type& val) 290 304 { 305 table_.increment_size(); 306 291 307 auto key = table_.get_key(val); 292 308 auto spot = table_.find_insertion_spot(key); … … 294 310 auto idx = get<2>(spot); 295 311 296 if (bucket->head) 312 if (!bucket) 313 return make_pair(end(), false); 314 315 auto target = table_.find_node_or_return_head(key, *bucket); 316 if (target && table_.keys_equal(key, target->value)) 297 317 { 298 auto head = bucket->head; 299 auto current = bucket->head; 300 301 do 302 { 303 if (table_.keys_equal(key, current->value)) 304 { 305 return make_pair(iterator{ 306 table_.table(), idx, 307 table_.bucket_count(), 308 current 309 }, false); 310 } 311 else 312 current = current->next; 313 } 314 while (current != head); 318 table_.decrement_size(); 319 return make_pair( 320 iterator{ 321 table_.table(), idx, table_.bucket_count(), 322 target 323 }, 324 false 325 ); 315 326 } 316 317 auto node = new node_type{val}; 318 bucket->append(node); 327 else 328 { 329 auto node = new node_type{val}; 330 bucket->append(node); 331 332 return make_pair(iterator{ 333 table_.table(), idx, 334 table_.bucket_count(), 335 node 336 }, true); 337 } 338 } 339 340 pair<iterator, bool> insert(value_type&& val) 341 { 319 342 table_.increment_size(); 320 343 321 return make_pair(iterator{322 table_.table(), idx,323 table_.bucket_count(),324 node325 }, true);326 }327 328 pair<iterator, bool> insert(value_type&& val)329 {330 344 auto key = table_.get_key(val); 331 345 auto spot = table_.find_insertion_spot(key); … … 333 347 auto idx = get<2>(spot); 334 348 335 if (bucket->head) 349 if (!bucket) 350 return make_pair(end(), false); 351 352 auto target = table_.find_node_or_return_head(key, *bucket); 353 if (target && table_.keys_equal(key, target->value)) 336 354 { 337 auto head = bucket->head; 338 auto current = bucket->head; 339 340 do 341 { 342 if (table_.keys_equal(key, current->value)) 343 { 344 return make_pair(iterator{ 345 table_.table(), idx, 346 table_.bucket_count(), 347 current 348 }, false); 349 } 350 else 351 current = current->next; 352 } 353 while (current != head); 355 table_.decrement_size(); 356 return make_pair( 357 iterator{ 358 table_.table(), idx, table_.bucket_count(), 359 target 360 }, 361 false 362 ); 354 363 } 355 356 auto node = new node_type{forward<value_type>(val)};357 bucket->append(node);358 table_.increment_size();359 // TODO: problem: rehashing here would invalidate the intel we have... 360 361 return make_pair(iterator{362 table_.table(), idx,363 table_.bucket_count(),364 node365 } , true);364 else 365 { 366 auto node = new node_type{forward<value_type>(val)}; 367 bucket->append(node); 368 369 return make_pair(iterator{ 370 table_.table(), idx, 371 table_.bucket_count(), 372 node 373 }, true); 374 } 366 375 } 367 376 -
uspace/lib/cpp/include/internal/hash_table.hpp
red9df7d re912cdf 1002 1002 void max_load_factor(float factor) 1003 1003 { 1004 /** 1005 * Note: According to the standard, this function 1006 * can have no effect. 1007 */ 1008 // TODO: change max factor and rehash if needed 1004 if (factor > 0.f) 1005 max_load_factor_ = factor; 1006 1007 rehash_if_needed(); 1009 1008 } 1010 1009 … … 1081 1080 } 1082 1081 1083 void set_hint(const_iterator hint)1084 {1085 // TODO: hint_ should be a ptr and we extract it here,1086 // then set it to nullptr after each operation1087 }1088 1089 1082 hint_type find_insertion_spot(const key_type& key) 1090 1083 { … … 1129 1122 { 1130 1123 ++size_; 1124 1125 rehash_if_needed(); 1126 } 1127 1128 void decrement_size() 1129 { 1130 --size_; 1131 } 1132 1133 node_type* find_node_or_return_head(const key_type& key, 1134 const hash_table_bucket<value_type, size_type>& bucket) 1135 { 1136 if (bucket.head) 1137 { 1138 auto head = bucket.head; 1139 auto current = bucket.head; 1140 1141 do 1142 { 1143 if (keys_equal(key, current->value)) 1144 return current; 1145 else 1146 current = current->next; 1147 } 1148 while (current != head); 1149 1150 return head; 1151 } 1152 else 1153 return nullptr; 1131 1154 } 1132 1155
Note:
See TracChangeset
for help on using the changeset viewer.