-
Notifications
You must be signed in to change notification settings - Fork 48
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
Add basic HashSet implementation #19
Conversation
Codecov Report
|
This looks great! Three comments:
|
I haven't added any additional tests yet (aside from the doc tests). I haven't had a chance to take a look at the examples you linked but I'm not sure how much they're needed yet as this is only using the public API which is already tested. I'll still take a look at adding some of the ones you linked. |
Oh interesting, it doesn't count doc tests. |
Just a heads up that I moved a bunch of code around (though it is mostly unchanged) and renamed |
I guess I got confused by the diff code cov dropping. I might have been the changes I rebased in. I still don't know why the coverage isn't 100%. Should be fixed when I add in the other tests.
Thanks for the heads up! |
When you get back to this, it would be nice to also have a |
Haha, I just rebased this branch! All good, taking a look at the tests now :) |
src/set/mod.rs
Outdated
map: HashMap<T, (), S>, | ||
} | ||
|
||
impl<T> HashSet<T, crate::DefaultHashBuilder> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DefaultHashBuilder
is correct for fn new
, but the other methods should allow a generic S: BuildHasher
. Consider adding the other constructors too: with_capacity
using the default, with_hasher
and with_capacity_and_hasher
using S
.
I had a look at the relevant tests from the Java codebase and honestly it looked like everything is covered by the doc tests. They were all pretty simple tests that didn't seem hugely relevant to how this is implemented here. I'm happy to “finish” this PR off by adding the missing constructor methods and getting it back up to date with
Thoughts? |
If you bring it up to speed with master, I'd be happy to merge without a Sticking to just the doc tests seems fine by me! |
Tests are failing with:
Looks like crossbeam-rs/crossbeam#458 has been merged which may have broken something? The branch is still around though, so not sure why it can't use it. |
Ah, sorry, should be fixed on |
The doc tests still don't seem to be included in the coverage tests: |
Ah, yes. I have a fix pending for that in #63. |
|
I think miri might be unavailable on nightly at the moment? |
Yup, it is — see also #61 (comment). Should hopefully be fixed soon-ish. |
It finally passed! 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 2 of 3 files at r1, 1 of 1 files at r2.
Reviewable status: all files reviewed, 6 unresolved discussions (waiting on @twe4ked)
src/set.rs, line 44 at r2 (raw file):
#[derive(Debug)] pub struct HashSet<T: 'static, S = crate::DefaultHashBuilder> where
I'm trying out a new review tool, so if this turns out super weird, I apologize in advance :p
We don't need to require all these bounds here. Instead, we should only specify those bounds further down on the impl
blocks that require it. You can probably just use the same bounds that HashMap
uses for its impl
s.
src/set.rs, line 117 at r2 (raw file):
} impl<T> HashSet<T, crate::DefaultHashBuilder>
Minor: It makes more sense to me for this impl
block to come before the with_hasher
methods.
src/set.rs, line 167 at r2 (raw file):
/// Adds a value to the set. /// /// If the set did not have this value present, true is returned.
Nit: Should false
and true
here be in backticks? Same in a couple of other places in the docs.
src/set.rs, line 182 at r2 (raw file):
/// assert!(set.contains(&2)); /// ``` pub fn insert(&self, value: T) -> bool {
Should we also add HashSet::replace
while we're at it? It'd have to return an Option<&'guard T>
for us, but should be a straightforward near-copy of insert
.
src/set.rs, line 183 at r2 (raw file):
/// ``` pub fn insert(&self, value: T) -> bool { let guard = epoch::pin();
Reading through this again, I think we should switch all of the HashSet
methods to taking a &Guard
, just like the HashMap
APIs. And then probably also provide a HashSet::guard
that calls into the underlying HashMap::guard
. That way it will be much easier to add HashSetRef
later.
src/set.rs, line 234 at r2 (raw file):
/// assert_eq!(set.remove(&2), false); /// ``` pub fn remove<Q>(&self, value: &Q) -> bool
Should we add HashSet::take
while we're at it? It'd have to return an Option<&'guard T>
for us, but beyond that the functionality should be easy-enough to add.
We can rely on the specific impl blocks below.
I've actioned your feedback except for adding Looks like miri is unavailable again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 1 of 3 files reviewed, 3 unresolved discussions (waiting on @jonhoo and @twe4ked)
Thanks! I'm going to go ahead and merge this, and then I'll do some tweaks after the fact since you're short on time :) |
See #68 |
Co-authored-by: rtkay123 <[email protected]>
Add a very basic implementation of
HashSet
as mentioned in #17.This change is