Merge pull request #1656 from tpounds/bug-fix-prevent-neg-hash-all-operations
helper/schema: Prevent negative hashcodes for all set operations.
This commit is contained in:
commit
b96027ac87
|
@ -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 {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue