mirror of
https://github.com/bloeys/nset.git
synced 2025-12-29 06:28:19 +00:00
Keep count of set bits to offer .Len+optimizations
This commit is contained in:
49
nset_test.go
49
nset_test.go
@ -22,10 +22,23 @@ var (
|
||||
func TestNSet(t *testing.T) {
|
||||
|
||||
n1 := nset.NewNSet[uint32]()
|
||||
|
||||
// Double add/remove of the same value is not only important to test SetBits, but also
|
||||
// to test for bugs where double adding/removing incorrectly flips bits (checked using Contains())
|
||||
n1.Add(0)
|
||||
AllTrue(t, n1.Len() == 1)
|
||||
|
||||
n1.Add(0)
|
||||
AllTrue(t, n1.Len() == 1)
|
||||
|
||||
n1.Add(1)
|
||||
AllTrue(t, n1.Len() == 2)
|
||||
|
||||
n1.Add(63)
|
||||
AllTrue(t, n1.Len() == 3)
|
||||
|
||||
n1.Add(math.MaxUint32)
|
||||
AllTrue(t, n1.Len() == 4)
|
||||
|
||||
AllTrue(t, n1.Contains(0), n1.Contains(1), n1.Contains(63), n1.Contains(math.MaxUint32), !n1.Contains(10), !n1.Contains(599))
|
||||
AllTrue(t, n1.ContainsAll(0, 1, 63), !n1.ContainsAll(9, 0, 1), !n1.ContainsAll(0, 1, 63, 99))
|
||||
@ -35,7 +48,12 @@ func TestNSet(t *testing.T) {
|
||||
IsEq(t, math.MaxUint32/64/nset.BucketCount, n1.GetStorageUnitIndex(math.MaxUint32))
|
||||
|
||||
nCopy := n1.Copy()
|
||||
|
||||
n1.Remove(1)
|
||||
AllTrue(t, n1.Len() == 3)
|
||||
|
||||
n1.Remove(1)
|
||||
AllTrue(t, n1.Len() == 3)
|
||||
|
||||
AllTrue(t, n1.Contains(0), n1.Contains(63), !n1.Contains(1), nCopy.ContainsAll(0, 1, 63, math.MaxUint32))
|
||||
|
||||
@ -59,25 +77,25 @@ func TestNSet(t *testing.T) {
|
||||
n4n5Twin := nset.NewNSet[uint32]()
|
||||
n4n5Twin.AddMany(0, 1, 64, math.MaxUint32)
|
||||
|
||||
AllTrue(t, n4n5.ContainsAll(0, 1, 64, math.MaxUint32), !n4n5.Contains(63), n4n5Twin.IsEq(n4n5))
|
||||
AllTrue(t, n4n5.Len() == 4, n4n5.Len() == n4n5Twin.Len(), n4n5.ContainsAll(0, 1, 64, math.MaxUint32), !n4n5.Contains(63), n4n5Twin.IsEq(n4n5))
|
||||
|
||||
//Union
|
||||
n6 := nset.NewNSet[uint32]()
|
||||
n6.AddMany(4, 7, 100, 1000)
|
||||
n6.AddMany(1, 4, 7, 100, 1000)
|
||||
|
||||
n7 := nset.NewNSet[uint32]()
|
||||
n7.AddMany(math.MaxUint32)
|
||||
n7.AddMany(1, math.MaxUint32)
|
||||
n7OldStorageUnitCount := n7.StorageUnitCount
|
||||
n7.Union(n6)
|
||||
|
||||
AllTrue(t, n6.ContainsAll(4, 7, 100, 1000), !n6.Contains(math.MaxUint32), n7.ContainsAll(4, 7, 100, 1000, math.MaxUint32), n7.StorageUnitCount == n7OldStorageUnitCount+n6.StorageUnitCount)
|
||||
AllTrue(t, n6.Len() == 5, n7.Len() == 6, n6.ContainsAll(1, 4, 7, 100, 1000), !n6.Contains(math.MaxUint32), n7.ContainsAll(1, 4, 7, 100, 1000, math.MaxUint32), n7.StorageUnitCount == n7OldStorageUnitCount+n6.StorageUnitCount-1)
|
||||
|
||||
//UnionSets
|
||||
n7 = nset.NewNSet[uint32]()
|
||||
n7.AddMany(math.MaxUint32)
|
||||
n7.AddMany(4, math.MaxUint32)
|
||||
|
||||
unionedSet := nset.UnionSets(n6, n7)
|
||||
AllTrue(t, !n6.Contains(math.MaxUint32), !n7.ContainsAny(4, 7, 100, 1000), unionedSet.ContainsAll(4, 7, 100, 1000, math.MaxUint32), unionedSet.StorageUnitCount == n6.StorageUnitCount+n7OldStorageUnitCount)
|
||||
AllTrue(t, unionedSet.Len() == 6, !n6.Contains(math.MaxUint32), !n7.ContainsAny(7, 100, 1000), unionedSet.ContainsAll(4, 7, 100, 1000, math.MaxUint32), unionedSet.StorageUnitCount == n6.StorageUnitCount+n7OldStorageUnitCount-1)
|
||||
|
||||
//Equality
|
||||
AllTrue(t, !n6.IsEq(n7))
|
||||
@ -130,15 +148,18 @@ func TestNSetFullRange(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func AllTrue(t *testing.T, values ...bool) bool {
|
||||
func AllTrue(t *testing.T, values ...bool) (success bool) {
|
||||
|
||||
success = true
|
||||
|
||||
for i := 0; i < len(values); i++ {
|
||||
if !values[i] {
|
||||
t.Errorf("Expected 'true' but got 'false'\n")
|
||||
t.Fatalf("Expected 'true' but got 'false'\n")
|
||||
success = false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
return success
|
||||
}
|
||||
|
||||
func IsEq[T comparable](t *testing.T, expected, val T) bool {
|
||||
@ -147,7 +168,7 @@ func IsEq[T comparable](t *testing.T, expected, val T) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
t.Errorf("Expected '%v' but got '%v'\n", expected, val)
|
||||
t.Fatalf("Expected '%v' but got '%v'\n", expected, val)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -814,12 +835,12 @@ func BenchmarkNSetUnionRand(b *testing.B) {
|
||||
|
||||
b.StopTimer()
|
||||
|
||||
rand.Seed(RandSeed)
|
||||
randGen := rand.New(rand.NewSource(RandSeed))
|
||||
|
||||
s1 := nset.NewNSet[uint32]()
|
||||
s2 := nset.NewNSet[uint32]()
|
||||
for i := uint32(0); i < maxBenchSize; i++ {
|
||||
r := rand.Uint32()
|
||||
r := randGen.Uint32()
|
||||
s1.Add(r)
|
||||
s2.Add(r)
|
||||
}
|
||||
@ -837,12 +858,12 @@ func BenchmarkMapUnionRand(b *testing.B) {
|
||||
|
||||
b.StopTimer()
|
||||
|
||||
rand.Seed(RandSeed)
|
||||
randGen := rand.New(rand.NewSource(RandSeed))
|
||||
|
||||
m1 := map[uint32]struct{}{}
|
||||
m2 := map[uint32]struct{}{}
|
||||
for i := uint32(0); i < maxBenchSize; i++ {
|
||||
r := rand.Uint32()
|
||||
r := randGen.Uint32()
|
||||
m1[r] = struct{}{}
|
||||
m2[r] = struct{}{}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user