From dd7eabec28162945d39af0d1c6af90810c4a00bc Mon Sep 17 00:00:00 2001 From: Michael Li Date: Sat, 21 Oct 2023 15:36:13 +0800 Subject: [PATCH] types package add Bitmap based by roaring for sql binary type --- go.mod | 2 +- go.sum | 4 +- pkg/types/bitmap_roaring.go | 157 +++++++++++++++++++++++++++++++ pkg/types/bitmap_roaring_test.go | 36 +++++++ 4 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 pkg/types/bitmap_roaring.go create mode 100644 pkg/types/bitmap_roaring_test.go diff --git a/go.mod b/go.mod index 2703d5a8..3d73b6be 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/RoaringBitmap/roaring v1.6.0 github.com/afocus/captcha v0.0.0-20191010092841-4bd1f21c8868 github.com/alimy/mir/v4 v4.0.0 - github.com/alimy/tryst v0.9.2 + github.com/alimy/tryst v0.9.3 github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible github.com/allegro/bigcache/v3 v3.1.0 github.com/bufbuild/connect-go v1.10.0 diff --git a/go.sum b/go.sum index 2fa30cc6..878d2a51 100644 --- a/go.sum +++ b/go.sum @@ -127,8 +127,8 @@ github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:C github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/alimy/mir/v4 v4.0.0 h1:MzGfmoLjjvR69jbZEmpKJO3tUuqB0RGRv1UWPbtukBg= github.com/alimy/mir/v4 v4.0.0/go.mod h1:d58dBvw2KImcVbAUANrciEV/of0arMNsI9c/5UNCMMc= -github.com/alimy/tryst v0.9.2 h1:u/YYFtUesKeueKrgkPQvnApQspTKjBam69357DgkAew= -github.com/alimy/tryst v0.9.2/go.mod h1:6FcqEImav7S62em+p+MODh+stt/UPp23HobUOK3XwFY= +github.com/alimy/tryst v0.9.3 h1:R5HtBZoimiCszvsnBxhig8W75Rzi2NoEH7qaJ3nwhW8= +github.com/alimy/tryst v0.9.3/go.mod h1:6FcqEImav7S62em+p+MODh+stt/UPp23HobUOK3XwFY= github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible h1:Sg/2xHwDrioHpxTN6WMiwbXTpUEinBpHsN7mG21Rc2k= github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/allegro/bigcache/v3 v3.1.0 h1:H2Vp8VOvxcrB91o86fUSVJFqeuz8kpyyB02eH3bSzwk= diff --git a/pkg/types/bitmap_roaring.go b/pkg/types/bitmap_roaring.go new file mode 100644 index 00000000..d620d2fa --- /dev/null +++ b/pkg/types/bitmap_roaring.go @@ -0,0 +1,157 @@ +// Copyright 2023 ROC. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package types + +import ( + "github.com/RoaringBitmap/roaring" + "github.com/RoaringBitmap/roaring/roaring64" + "github.com/alimy/tryst/types" +) + +type roaringBitmap struct { + Map *roaring.Bitmap +} + +type roaring64Bitmap struct { + Map *roaring64.Bitmap +} + +func (m *roaringBitmap) MarshalBinary() ([]byte, error) { + if m == nil { + return []byte{}, nil + } + return m.Map.MarshalBinary() +} + +func (m *roaringBitmap) UnmarshalBinary(data []byte) (res *roaringBitmap, err error) { + res = &roaringBitmap{ + Map: roaring.New(), + } + err = res.Map.UnmarshalBinary(data) + return +} + +func (m *roaring64Bitmap) MarshalBinary() ([]byte, error) { + if m == nil { + return []byte{}, nil + } + return m.Map.MarshalBinary() +} + +func (m *roaring64Bitmap) UnmarshalBinary(data []byte) (res *roaring64Bitmap, err error) { + res = &roaring64Bitmap{ + Map: roaring64.New(), + } + err = res.Map.UnmarshalBinary(data) + return +} + +// Bitmap alias type of types.Binary[*roaringBitmap] +type Bitmap = types.Binary[*roaringBitmap] + +// NullBitmap alias type of types.NullBinary[*roaringBitmap] +type NullBitmap = types.NullBinary[*roaringBitmap] + +// Bitmap64 alias type of types.Binary[*roaring64Bitmap] +type Bitmap64 = types.Binary[*roaring64Bitmap] + +// NullBitmap64 alias type of types.NullBinary[*roaring64Bitmap] +type NullBitmap64 = types.NullBinary[*roaring64Bitmap] + +// NewBitmap create a Bitmap instance +func NewBitmap() (res *Bitmap) { + return &types.Binary[*roaringBitmap]{ + Data: &roaringBitmap{ + Map: roaring.New(), + }, + } +} + +// NewNullBitmap create a NullBitmap instance +func NewNullBitmap() *NullBitmap { + return &types.NullBinary[*roaringBitmap]{ + Data: &roaringBitmap{ + Map: roaring.New(), + }, + } +} + +// NewBitmap64 create a Bitmap64 instance +func NewBitmap64() *Bitmap64 { + return &types.Binary[*roaring64Bitmap]{ + Data: &roaring64Bitmap{ + Map: roaring64.New(), + }, + } +} + +// NewNullBitmap64 create a NullBitmap64 instance +func NewNullBitmap64() *NullBitmap64 { + return &types.NullBinary[*roaring64Bitmap]{ + Data: &roaring64Bitmap{ + Map: roaring64.New(), + }, + } +} + +// MustBitmap create a Bitmap instance +func MustBitmap(data ...[]byte) (res *Bitmap) { + res = &types.Binary[*roaringBitmap]{ + Data: &roaringBitmap{ + Map: roaring.New(), + }, + } + if len(data) > 0 && len(data[0]) > 0 { + if err := res.Data.Map.UnmarshalBinary(data[0]); err != nil { + panic(err) + } + } + return +} + +// MustNullBitmap create a NullBitmap instance +func MustNullBitmap(data ...[]byte) (res *NullBitmap) { + res = &types.NullBinary[*roaringBitmap]{ + Data: &roaringBitmap{ + Map: roaring.New(), + }, + } + if len(data) > 0 && len(data[0]) > 0 { + if err := res.Data.Map.UnmarshalBinary(data[0]); err != nil { + panic(err) + } + } + return +} + +// MustBitmap64 create a Bitmap64 instance +func MustBitmap64(data ...[]byte) (res *Bitmap64) { + res = &types.Binary[*roaring64Bitmap]{ + Data: &roaring64Bitmap{ + Map: roaring64.New(), + }, + } + if len(data) > 0 && len(data[0]) > 0 { + if err := res.Data.Map.UnmarshalBinary(data[0]); err != nil { + panic(err) + } + } + return +} + +// MustNullBitmap64 create a NullBitmap64 instance +func MustNullBitmap64(data ...[]byte) (res *NullBitmap64) { + res = &types.NullBinary[*roaring64Bitmap]{ + Data: &roaring64Bitmap{ + Map: roaring64.New(), + }, + } + if len(data) > 0 && len(data[0]) > 0 { + if err := res.Data.Map.UnmarshalBinary(data[0]); err != nil { + panic(err) + } + } + return +} diff --git a/pkg/types/bitmap_roaring_test.go b/pkg/types/bitmap_roaring_test.go new file mode 100644 index 00000000..e045914e --- /dev/null +++ b/pkg/types/bitmap_roaring_test.go @@ -0,0 +1,36 @@ +// Copyright 2023 ROC. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package types_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/rocboss/paopao-ce/pkg/types" +) + +var _ = Describe("Bitmap", Ordered, func() { + It("sql scaner for Bitmap", func() { + bitmap := types.NewBitmap() + bitmap.Data.Map.Add(128) + value, err := bitmap.Value() + Expect(err).To(BeNil()) + + var bm types.Bitmap + bm.Scan(value) + Expect(bm.Data.Map.Contains(128)).To(BeTrue()) + }) + + It("sql scaner for Bitmap64", func() { + bitmap := types.NewBitmap64() + bitmap.Data.Map.Add(128) + value, err := bitmap.Value() + Expect(err).To(BeNil()) + + var bm types.Bitmap64 + bm.Scan(value) + Expect(bm.Data.Map.Contains(128)).To(BeTrue()) + }) +})