Prevent negative hashcodes for all set operations.

This commit is contained in:
Trevor Pounds 2015-04-23 09:23:33 -07:00
parent 1ef9731a2f
commit 17b31925fe
2 changed files with 16 additions and 6 deletions

View File

@ -34,7 +34,7 @@ func (s *Set) Add(item interface{}) {
// Contains checks if the set has the given item. // Contains checks if the set has the given item.
func (s *Set) Contains(item interface{}) bool { func (s *Set) Contains(item interface{}) bool {
_, ok := s.m[s.F(item)] _, ok := s.m[s.hash(item)]
return ok return ok
} }
@ -122,10 +122,7 @@ func (s *Set) init() {
func (s *Set) add(item interface{}) int { func (s *Set) add(item interface{}) int {
s.once.Do(s.init) s.once.Do(s.init)
code := s.F(item) code := s.hash(item)
if code < 0 {
code *= -1
}
if _, ok := s.m[code]; !ok { if _, ok := s.m[code]; !ok {
s.m[code] = item s.m[code] = item
} }
@ -133,8 +130,17 @@ func (s *Set) add(item interface{}) int {
return code return code
} }
func (s *Set) hash(item interface{}) int {
code := s.F(item)
// Always return a nonnegative hashcode.
if code < 0 {
return -code
}
return code
}
func (s *Set) index(item interface{}) int { func (s *Set) index(item interface{}) int {
return sort.SearchInts(s.listCode(), s.F(item)) return sort.SearchInts(s.listCode(), s.hash(item))
} }
func (s *Set) listCode() []int { func (s *Set) listCode() []int {

View File

@ -35,6 +35,7 @@ func TestSetAdd_negative(t *testing.T) {
func TestSetContains(t *testing.T) { func TestSetContains(t *testing.T) {
s := &Set{F: testSetInt} s := &Set{F: testSetInt}
s.Add(5) s.Add(5)
s.Add(-5)
if s.Contains(2) { if s.Contains(2) {
t.Fatal("should not contain") t.Fatal("should not contain")
@ -42,6 +43,9 @@ func TestSetContains(t *testing.T) {
if !s.Contains(5) { if !s.Contains(5) {
t.Fatal("should contain") t.Fatal("should contain")
} }
if !s.Contains(-5) {
t.Fatal("should contain")
}
} }
func TestSetDifference(t *testing.T) { func TestSetDifference(t *testing.T) {