From f08f06891c94a2589d60203e2d4427e35f620625 Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Mon, 22 Jan 2024 14:05:11 +0800 Subject: [PATCH] =?UTF-8?q?test:=20super.BitSet=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/super/bit_set.go | 13 +++ utils/super/bit_set_example_test.go | 74 ++++++++++++++++ utils/super/bit_set_test.go | 125 ++++++++++++++++++++++++---- 3 files changed, 194 insertions(+), 18 deletions(-) create mode 100644 utils/super/bit_set_example_test.go diff --git a/utils/super/bit_set.go b/utils/super/bit_set.go index a7cce23..43efac2 100644 --- a/utils/super/bit_set.go +++ b/utils/super/bit_set.go @@ -7,9 +7,13 @@ import ( ) // NewBitSet 通过指定的 Bit 位创建一个 BitSet +// - 当指定的 Bit 位存在负数时,将会 panic func NewBitSet[Bit generic.Integer](bits ...Bit) *BitSet[Bit] { set := &BitSet[Bit]{set: make([]uint64, 0, 1)} for _, bit := range bits { + if bit < 0 { + panic(fmt.Errorf("bit %v is negative", bit)) + } set.Set(bit) } return set @@ -43,6 +47,15 @@ func (slf *BitSet[Bit]) Del(bit Bit) *BitSet[Bit] { // Shrink 将 BitSet 中的比特位集合缩小到最小 // - 正常情况下当 BitSet 中的比特位超出 64 位时,将自动增长,当 BitSet 中的比特位数量减少时,可以使用该方法将 BitSet 中的比特位集合缩小到最小 func (slf *BitSet[Bit]) Shrink() *BitSet[Bit] { + switch len(slf.set) { + case 0: + return slf + case 1: + if slf.set[0] == 0 { + slf.set = nil + return slf + } + } index := len(slf.set) - 1 if slf.set[index] != 0 { return slf diff --git a/utils/super/bit_set_example_test.go b/utils/super/bit_set_example_test.go new file mode 100644 index 0000000..ead6ea7 --- /dev/null +++ b/utils/super/bit_set_example_test.go @@ -0,0 +1,74 @@ +package super_test + +import ( + "fmt" + "github.com/kercylan98/minotaur/utils/super" +) + +func ExampleNewBitSet() { + var bs = super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9) + bs.Set(10) + fmt.Println(bs.Bits()) + // Output: + // [1 2 3 4 5 6 7 8 9 10] +} + +func ExampleBitSet_Set() { + var bs = super.NewBitSet[int]() + bs.Set(10) + fmt.Println(bs.Bits()) + // Output: + // [10] +} + +func ExampleBitSet_Del() { + var bs = super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9) + bs.Del(1) + fmt.Println(bs.Bits()) + // Output: + // [2 3 4 5 6 7 8 9] +} + +func ExampleBitSet_Shrink() { + var bs = super.NewBitSet(111, 222, 333, 444) + fmt.Println(bs.Cap()) + bs.Del(444) + fmt.Println(bs.Cap()) + bs.Shrink() + fmt.Println(bs.Cap()) + // Output: + // 448 + // 448 + // 384 +} + +func ExampleBitSet_Cap() { + var bs = super.NewBitSet(63) + fmt.Println(bs.Cap()) + // Output: + // 64 +} + +func ExampleBitSet_Has() { + var bs = super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9) + fmt.Println(bs.Has(1)) + fmt.Println(bs.Has(10)) + // Output: + // true + // false +} + +func ExampleBitSet_Clear() { + var bs = super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9) + bs.Clear() + fmt.Println(bs.Bits()) + // Output: + // [] +} + +func ExampleBitSet_Len() { + var bs = super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9) + fmt.Println(bs.Len()) + // Output: + // 9 +} diff --git a/utils/super/bit_set_test.go b/utils/super/bit_set_test.go index f654139..e74e9b9 100644 --- a/utils/super/bit_set_test.go +++ b/utils/super/bit_set_test.go @@ -5,29 +5,118 @@ import ( "testing" ) +func TestNewBitSet(t *testing.T) { + var cases = []struct { + name string + in []int + shouldPanic bool + }{ + {name: "normal", in: []int{1, 2, 3, 4, 5, 6, 7, 8, 9}}, + {name: "empty", in: make([]int, 0)}, + {name: "nil", in: nil}, + {name: "negative", in: []int{-1, -2}, shouldPanic: true}, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + defer func() { + if r := recover(); r != nil && !c.shouldPanic { + t.Fatalf("panic: %v", r) + } + }() + bs := super.NewBitSet(c.in...) + t.Log(bs) + }) + } +} + func TestBitSet_Set(t *testing.T) { - bs := super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - bs.Set(11) - bs.Set(12) - bs.Set(13) - t.Log(bs) + var cases = []struct { + name string + in []int + shouldPanic bool + }{ + {name: "normal", in: []int{1, 2, 3, 4, 5, 6, 7, 8, 9}}, + {name: "empty", in: make([]int, 0)}, + {name: "nil", in: nil}, + {name: "negative", in: []int{-1, -2}, shouldPanic: true}, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + defer func() { + if r := recover(); r != nil && !c.shouldPanic { + t.Fatalf("panic: %v", r) + } + }() + bs := super.NewBitSet[int]() + for _, bit := range c.in { + bs.Set(bit) + } + for _, bit := range c.in { + if !bs.Has(bit) { + t.Fatalf("bit %v not set", bit) + } + } + }) + } } func TestBitSet_Del(t *testing.T) { - bs := super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - bs.Del(11) - bs.Del(12) - bs.Del(13) - bs.Del(10) - t.Log(bs) + var cases = []struct { + name string + in []int + shouldPanic bool + }{ + {name: "normal", in: []int{1, 2, 3, 4, 5, 6, 7, 8, 9}}, + {name: "empty", in: make([]int, 0)}, + {name: "nil", in: nil}, + {name: "negative", in: []int{-1, -2}, shouldPanic: true}, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + defer func() { + if r := recover(); r != nil && !c.shouldPanic { + t.Fatalf("panic: %v", r) + } + }() + bs := super.NewBitSet[int]() + for _, bit := range c.in { + bs.Set(bit) + } + for _, bit := range c.in { + bs.Del(bit) + } + for _, bit := range c.in { + if bs.Has(bit) { + t.Fatalf("bit %v not del", bit) + } + } + }) + } } func TestBitSet_Shrink(t *testing.T) { - bs := super.NewBitSet(63) - t.Log(bs.Cap()) - bs.Set(200) - t.Log(bs.Cap()) - bs.Del(200) - bs.Shrink() - t.Log(bs.Cap()) + var cases = []struct { + name string + in []int + }{ + {name: "normal", in: []int{1, 2, 3, 4, 5, 6, 7, 8, 9}}, + {name: "empty", in: make([]int, 0)}, + {name: "nil", in: nil}, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + bs := super.NewBitSet(c.in...) + for _, v := range c.in { + bs.Del(v) + } + bs.Shrink() + if bs.Cap() != 0 { + t.Fatalf("cap %v != 0", bs.Cap()) + } + }) + } }