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

[WIP] OccupiedEntry.replace_ #11

Merged
merged 2 commits into from
Jul 2, 2020

Conversation

Michael-J-Ward
Copy link
Contributor

@Michael-J-Ward Michael-J-Ward commented Jul 2, 2020

First pass at implementing the OccupiedEntry.replace_ in #4

This is directly taken from hashbrown.

I see the existing warning in src/map.rs that the hashbrown implementation will not work (

griddle/src/map.rs

Lines 1857 to 1865 in 13509e4

// NOTE:
// replace_entry and replace_key are _not_ okay, because it may move a bucket in the old
// table to _before_ where the "move keys iterator" is currently pointed. in which case we'd
// fail to move them.
//
// it should be possible to work around this by checking if that's the case, and then
// restarting the iterator, though that would come at a performance penalty...
//
// when implemented, remove the #[allow(dead_code)] on OccupiedEntry::key
)

However, I do not see where the bucket gets moved. Aren't the replace_entry and replace_key replacing the values in place?

I additionally ran a test with a million random inserts / replaces comparing the results of griddle::HashMap vs hashbrown::HashMap and it passed.

Do you have any guidance on better understanding / triggering the warning condition?

Thanks

This is directly taken from `hashbrown`

There is an existing warning in `src/map.rs` that the hashbrown
implementation will not work, but I don't currently see why.
@jonhoo
Copy link
Owner

jonhoo commented Jul 2, 2020

Hmm, that's interesting. It feels like there has to be an unstated requirement that the new key hashes to the same as the old one for this to work. Apparently these methods are still under discussion in rust-lang/rust#44286, so I filed a comment there: rust-lang/rust#44286 (comment). Since this just seems to work though, and doesn't require shifting, I'm inclined to accept it!

One thing though: there are probably tests for replace_ in map as well that we should move over.

@Michael-J-Ward
Copy link
Contributor Author

My strategy for that was to place assert_eq!(1, 2) at the first line of each method in hashbrown, run the hashbrown tests with --no-fail-fast, and see what fails.

Only the test_set::test_replace unit test fails:

failures:
    set::test_set::test_replace

test result: FAILED. 62 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

And these doctests

failures:
    src/map.rs - map::OccupiedEntry::replace_entry (line 2567)
    src/set.rs - set::HashSet<T, S>::replace (line 845)

test result: FAILED. 96 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out

@jonhoo
Copy link
Owner

jonhoo commented Jul 2, 2020

Oh, how weird... I definitely feel like we should have more tests for this, but it sounds like we should contribute those tests to hashbrown first then.

I just realized why this is okay (rust-lang/rust#44286 (comment)), and so I think it's fine for us to include this too then! Thank you :)

@jonhoo jonhoo merged commit 78787e6 into jonhoo:master Jul 2, 2020
@Michael-J-Ward
Copy link
Contributor Author

Should that warning note about the replace_ implementations also be removed?

@jonhoo
Copy link
Owner

jonhoo commented Jul 2, 2020

Ah, yes, good catch! I just pushed that change.

jonhoo pushed a commit that referenced this pull request Oct 19, 2024
Put 1.70 in there (for instance if you want to pin against OnceLock stabilizing) and it will actually test 1.7 as it appears github auto converts this to a float?

Putting in quotes seems to do the right thing here
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.

2 participants