// Intersects reports whether this points-to set and the // argument points-to set contain common members. func (x PointsToSet) Intersects(y PointsToSet) bool { if x.pts == nil || y.pts == nil { return false } // This takes Θ(|x|+|y|) time. var z intsets.Sparse z.Intersection(&x.pts.Sparse, &y.pts.Sparse) return !z.IsEmpty() }
func BenchmarkAppendTo(b *testing.B) { prng := rand.New(rand.NewSource(0)) var x intsets.Sparse for i := 0; i < 1000; i++ { x.Insert(int(prng.Int()) % 10000) } var space [1000]int for tries := 0; tries < b.N; tries++ { x.AppendTo(space[:0]) } }
func TestFailFastOnShallowCopy(t *testing.T) { var x intsets.Sparse x.Insert(1) y := x // shallow copy (breaks representation invariants) defer func() { got := fmt.Sprint(recover()) want := "A Sparse has been copied without (*Sparse).Copy()" if got != want { t.Errorf("shallow copy: recover() = %q, want %q", got, want) } }() y.String() // panics t.Error("didn't panic as expected") }
func TestBitString(t *testing.T) { for _, test := range []struct { input []int want string }{ {nil, "0"}, {[]int{0}, "1"}, {[]int{0, 4, 5}, "110001"}, {[]int{0, 7, 177}, "1" + strings.Repeat("0", 169) + "10000001"}, {[]int{-3, 0, 4, 5}, "110001.001"}, {[]int{-3}, "0.001"}, } { var set intsets.Sparse for _, x := range test.input { set.Insert(x) } if got := set.BitString(); got != test.want { t.Errorf("BitString(%s) = %s, want %s", set.String(), got, test.want) } } }
func TestIntersects(t *testing.T) { prng := rand.New(rand.NewSource(0)) for i := uint(0); i < 12; i++ { X, Y := randomPset(prng, 1<<i), randomPset(prng, 1<<i) x, y := &X.bits, &Y.bits // test the slow way var z intsets.Sparse z.Copy(x) z.IntersectionWith(y) if got, want := x.Intersects(y), !z.IsEmpty(); got != want { t.Errorf("Intersects: got %v, want %v", got, want) } // make it false a := x.AppendTo(nil) for _, v := range a { y.Remove(v) } if got, want := x.Intersects(y), false; got != want { t.Errorf("Intersects: got %v, want %v", got, want) } // make it true if x.IsEmpty() { continue } i := prng.Intn(len(a)) y.Insert(a[i]) if got, want := x.Intersects(y), true; got != want { t.Errorf("Intersects: got %v, want %v", got, want) } } }
func TestSubsetOf(t *testing.T) { prng := rand.New(rand.NewSource(0)) for i := uint(0); i < 12; i++ { X, Y := randomPset(prng, 1<<i), randomPset(prng, 1<<i) x, y := &X.bits, &Y.bits // test the slow way var z intsets.Sparse z.Copy(x) z.DifferenceWith(y) if got, want := x.SubsetOf(y), z.IsEmpty(); got != want { t.Errorf("SubsetOf: got %v, want %v", got, want) } // make it true y.UnionWith(x) if got, want := x.SubsetOf(y), true; got != want { t.Errorf("SubsetOf: got %v, want %v", got, want) } // make it false if x.IsEmpty() { continue } a := x.AppendTo(nil) i := prng.Intn(len(a)) y.Remove(a[i]) if got, want := x.SubsetOf(y), false; got != want { t.Errorf("SubsetOf: got %v, want %v", got, want) } } }
func TestTakeMin(t *testing.T) { var set intsets.Sparse set.Insert(456) set.Insert(123) set.Insert(789) set.Insert(-123) var got int for i, want := range []int{-123, 123, 456, 789} { if !set.TakeMin(&got) || got != want { t.Errorf("TakeMin #%d: got %d, want %d", i, got, want) } } if set.TakeMin(&got) { t.Errorf("%s.TakeMin returned true", &set) } if err := set.Check(); err != nil { t.Fatalf("check: %s: %#v", err, &set) } }
// Insert, Len, IsEmpty, Hash, Clear, AppendTo. func TestMoreBasics(t *testing.T) { set := new(intsets.Sparse) set.Insert(456) set.Insert(123) set.Insert(789) if set.Len() != 3 { t.Errorf("%s.Len: got %d, want 3", set, set.Len()) } if set.IsEmpty() { t.Errorf("%s.IsEmpty: got true", set) } if !set.Has(123) { t.Errorf("%s.Has(123): got false", set) } if set.Has(1234) { t.Errorf("%s.Has(1234): got true", set) } got := set.AppendTo([]int{-1}) if want := []int{-1, 123, 456, 789}; fmt.Sprint(got) != fmt.Sprint(want) { t.Errorf("%s.AppendTo: got %v, want %v", set, got, want) } set.Clear() if set.Len() != 0 { t.Errorf("Clear: got %d, want 0", set.Len()) } if !set.IsEmpty() { t.Errorf("IsEmpty: got false") } if set.Has(123) { t.Errorf("%s.Has: got false", set) } }
func BenchmarkSparseBitVector(b *testing.B) { prng := rand.New(rand.NewSource(0)) for tries := 0; tries < b.N; tries++ { var x, y, z intsets.Sparse for i := 0; i < 1000; i++ { n := int(prng.Int()) % 100000 if i%2 == 0 { x.Insert(n) } else { y.Insert(n) } } z.Union(&x, &y) z.Difference(&x, &y) } }
func TestIntersectionWith(t *testing.T) { // Edge cases: the pairs (1,1), (1000,2000), (8000,4000) // exercise the <, >, == cases in IntersectionWith that the // TestSetOperations data is too dense to cover. var X, Y intsets.Sparse X.Insert(1) X.Insert(1000) X.Insert(8000) Y.Insert(1) Y.Insert(2000) Y.Insert(4000) X.IntersectionWith(&Y) if got, want := X.String(), "{1}"; got != want { t.Errorf("IntersectionWith: got %s, want %s", got, want) } }
func TestBasics(t *testing.T) { var s intsets.Sparse if len := s.Len(); len != 0 { t.Errorf("Len({}): got %d, want 0", len) } if s := s.String(); s != "{}" { t.Errorf("String({}): got %q, want \"{}\"", s) } if s.Has(3) { t.Errorf("Has(3): got true, want false") } if err := s.Check(); err != nil { t.Error(err) } if !s.Insert(3) { t.Errorf("Insert(3): got false, want true") } if max := s.Max(); max != 3 { t.Errorf("Max: got %d, want 3", max) } if !s.Insert(435) { t.Errorf("Insert(435): got false, want true") } if s := s.String(); s != "{3 435}" { t.Errorf("String({3 435}): got %q, want \"{3 435}\"", s) } if max := s.Max(); max != 435 { t.Errorf("Max: got %d, want 435", max) } if len := s.Len(); len != 2 { t.Errorf("Len: got %d, want 2", len) } if !s.Remove(435) { t.Errorf("Remove(435): got false, want true") } if s := s.String(); s != "{3}" { t.Errorf("String({3}): got %q, want \"{3}\"", s) } }
func TestEquals(t *testing.T) { var setX intsets.Sparse setX.Insert(456) setX.Insert(123) setX.Insert(789) if !setX.Equals(&setX) { t.Errorf("Equals(%s, %s): got false", &setX, &setX) } var setY intsets.Sparse setY.Insert(789) setY.Insert(456) setY.Insert(123) if !setX.Equals(&setY) { t.Errorf("Equals(%s, %s): got false", &setX, &setY) } setY.Insert(1) if setX.Equals(&setY) { t.Errorf("Equals(%s, %s): got true", &setX, &setY) } var empty intsets.Sparse if setX.Equals(&empty) { t.Errorf("Equals(%s, %s): got true", &setX, &empty) } // Edge case: some block (with offset=0) appears in X but not Y. setY.Remove(123) if setX.Equals(&setY) { t.Errorf("Equals(%s, %s): got true", &setX, &setY) } }
func TestMinAndMax(t *testing.T) { values := []int{0, 456, 123, 789, -123} // elt 0 => empty set wantMax := []int{intsets.MinInt, 456, 456, 789, 789} wantMin := []int{intsets.MaxInt, 456, 123, 123, -123} var set intsets.Sparse for i, x := range values { if i != 0 { set.Insert(x) } if got, want := set.Min(), wantMin[i]; got != want { t.Errorf("Min #%d: got %d, want %d", i, got, want) } if got, want := set.Max(), wantMax[i]; got != want { t.Errorf("Max #%d: got %d, want %d", i, got, want) } } set.Insert(intsets.MinInt) if got, want := set.Min(), intsets.MinInt; got != want { t.Errorf("Min: got %d, want %d", got, want) } set.Insert(intsets.MaxInt) if got, want := set.Max(), intsets.MaxInt; got != want { t.Errorf("Max: got %d, want %d", got, want) } }