]> 127.0.0.1 Git - part/.git/commitdiff
1 v0.28.20231214142916
authorqydysky <qydysky@foxmail.com>
Thu, 14 Dec 2023 14:26:12 +0000 (22:26 +0800)
committerqydysky <qydysky@foxmail.com>
Thu, 14 Dec 2023 14:26:12 +0000 (22:26 +0800)
slice/Blocks.go [new file with mode: 0644]
slice/Blocks_test.go [new file with mode: 0644]

diff --git a/slice/Blocks.go b/slice/Blocks.go
new file mode 100644 (file)
index 0000000..5de6c8a
--- /dev/null
@@ -0,0 +1,45 @@
+package part
+
+import (
+       "errors"
+)
+
+type blocks[T any] struct {
+       free chan int
+       size int
+       buf  []T
+}
+
+var ErrOverflow = errors.New("ErrOverflow")
+
+func NewBlocks[T any](blockSize int, blockNum int) *blocks[T] {
+       p := &blocks[T]{
+               size: blockSize,
+               free: make(chan int, blockNum+1),
+               buf:  make([]T, blockSize*blockNum),
+       }
+       for i := 0; i < blockNum; i++ {
+               p.free <- i
+       }
+       return p
+}
+
+// // eg
+//
+//     if tmpbuf, putBack, e := buf.Get(); e == nil {
+//             clear(tmpbuf)
+//             // do something with tmpbuf
+//             putBack()
+//     }
+func (t *blocks[T]) Get() ([]T, func(), error) {
+       select {
+       case offset := <-t.free:
+               offset *= t.size
+               return t.buf[offset : offset+t.size], func() {
+                       clear(t.buf[offset : offset+t.size])
+                       t.free <- offset
+               }, nil
+       default:
+               return nil, func() {}, ErrOverflow
+       }
+}
diff --git a/slice/Blocks_test.go b/slice/Blocks_test.go
new file mode 100644 (file)
index 0000000..b6eae39
--- /dev/null
@@ -0,0 +1,12 @@
+package part
+
+import "testing"
+
+func TestMain(t *testing.T) {
+       buf := NewBlocks[byte](1024, 10)
+       if tmpbuf, putBack, e := buf.Get(); e == nil {
+               clear(tmpbuf)
+               // do something with tmpbuf
+               putBack()
+       }
+}