Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SafeUnorderedMap fixes #99

Closed
wants to merge 3 commits into from
Closed

Conversation

fcecin
Copy link
Collaborator

@fcecin fcecin commented Mar 8, 2024

This patch hides the std::unordered_map iterators that were exposed, and replaces them with new SafeUnorderedMap::iterator and SafeUnorderedMap::const_iterator.

As part of the proposed changes, some SafeUnorderedMap methods had to be removed. We can re-implement them later without exposing internal details, if it turns out that we will be needing them.

Added tests for the new features, and also some additional tests to make sure all of the insert/emplace/erase methods from the template type get instantiated at least once.

fcecin added 2 commits March 8, 2024 14:42
- new custom iterators keep all internals hidden
- remove range-erase erase(first, last) method (use
  it = erase(it) in a loop instead)
- remove all node_type methods (harder to implement now
  that internals are not exposed)
- remove insert(T&&) template methods (don't instantiate)
- add testcases for functionality tests and for template
  instantiation tests
- Keep size_ valid in operator[] and erase() at no extra cost
- Keep size_ valid in insert(pair) and insert_or_assign(k,v) at the cost of
  two extra hash lookups (map_ & erasedKeys_), miminizing odds that a call
  to size() would have to count elements, which can be expensive; better to
  pay the (constant) cost upfront as the default (can be improved later by
  e.g. adding a configuration bool to control this behavior)
- Added a few size() checks to tests
Copy link
Collaborator

@Jean-Lessa Jean-Lessa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

check();
auto mapPtrIt = mapPtr_->find(std::forward<K>(key));
if (mapPtrIt != mapPtr_->end()) {
mapPtr_->erase(std::forward<K>(key));
Copy link
Collaborator

@Pedrozo Pedrozo Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

key might dangle since you already forwarded it in line 628. We should std::forward a forwarding reference only once. Do you think this overload is truly necessary? It will be a bit tricky to ensure a single std::forward as we track erased keys.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, why is this overload so different from the erase(const Key& key)?

Copy link
Collaborator Author

@fcecin fcecin Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I also understand that std::forward should be used only once, though I don't know if there's some kind of nuance here being exploited. This was the previous behavior (if I'm not mistaken). I tried to mimic as much of the previous code as possible. I'm down with removing this overload (and perhaps others) if people want to.

EDIT: Let's just remove this overload.

std::pair<typename std::unordered_map<Key, T, SafeHash>::iterator, bool> insert(
typename std::unordered_map<Key, T, SafeHash>::value_type&& value
std::pair<typename SafeUnorderedMap<Key, T>::iterator, bool> insert(
const typename SafeUnorderedMap<Key, T>::value_type&& value
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const here is preventing moving. Remember that moving A to B requires modifying A, so it can't be const. The current code will actually cause a copy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops! Thanks!

- Fix const argument bug on insert(&&)
- Removed erase(&&)
Copy link
Collaborator

@Pedrozo Pedrozo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

@fcecin
Copy link
Collaborator Author

fcecin commented May 17, 2024

This is obsoleted by some radical changes coming to the Safe Variables feature. I'll keep this branch for now as a source of ideas for upcoming work.

@fcecin fcecin closed this May 17, 2024
@itamarcps itamarcps deleted the safeunorderedmap_custom_iter branch May 21, 2024 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants