go test -count 1 -timeout 5s -v -race github.com/qydysky/part/pool
go test -count 1 -timeout 10s -v -race github.com/qydysky/part/funcCtrl
go test -count 1 -timeout 30s -v -race github.com/qydysky/part/msgq
+ go test -count 1 -timeout 5s -v -race github.com/qydysky/part/sync
inUse func(*T) bool
reuseF func(*T) *T
poolF func(*T) *T
- buf []*T
+ buf []poolItem[T]
l sync.RWMutex
}
+type poolItem[T any] struct {
+ i *T
+ pooled bool
+}
+
// 创建池
//
// NewF: func() *T 新值
defer t.l.RUnlock()
for i := 0; i < len(t.buf); i++ {
- if t.inUse(t.buf[i]) {
+ if !t.buf[i].pooled && t.inUse(t.buf[i].i) {
inUse++
}
}
defer t.l.Unlock()
for i := 0; i < len(t.buf); i++ {
- if !t.inUse(t.buf[i]) {
- t.buf[i] = nil
+ if t.buf[i].pooled && !t.inUse(t.buf[i].i) {
t.buf = append(t.buf[:i], t.buf[i+1:]...)
i--
}
defer t.l.Unlock()
for i := 0; i < len(t.buf); i++ {
- if !t.inUse(t.buf[i]) {
- return t.reuseF(t.buf[i])
+ if t.buf[i].pooled && !t.inUse(t.buf[i].i) {
+ t.buf[i].pooled = false
+ return t.reuseF(t.buf[i].i)
}
}
var cu = 0
for i := 0; i < len(t.buf); i++ {
- if !t.inUse(t.buf[i]) {
- t.buf[i] = t.poolF(item[cu])
+ if t.buf[i].pooled && !t.inUse(t.buf[i].i) {
+ t.buf[i].i = t.poolF(item[cu])
+ t.buf[i].pooled = true
cu++
if cu >= len(item) {
return
}
for i := cu; i < len(item) && t.maxsize > len(t.buf); i++ {
- t.buf = append(t.buf, t.poolF(item[i]))
+ t.buf = append(t.buf, poolItem[T]{t.poolF(item[i]), true})
}
}
t.Fatal()
}
- b.Put(c1)
c1.v = false
+
var c3 = b.Get()
var c3p = uintptr(unsafe.Pointer(c3))
- if c1p != c3p || len(c1.d) != 0 || b.PoolInUse() != 1 || b.PoolSum() != 1 {
+ if c1p == c3p || len(c1.d) == 0 || b.PoolInUse() != 0 || b.PoolSum() != 0 {
t.Fatal()
}
+
+ b.Put(c1)
+
+ if len(c1.d) == 0 || b.PoolInUse() != 0 || b.PoolSum() != 1 {
+ t.Fatal(len(c1.d) != 0, b.PoolInUse() != 0, b.PoolSum() != 1)
+ }
}
import (
"bytes"
"context"
+ "encoding/json"
"io"
"net/http"
"testing"
time.Sleep(time.Second)
}
},
+ `/json`: func(w http.ResponseWriter, _ *http.Request) {
+ w.WriteHeader(200)
+ flusher, flushSupport := w.(http.Flusher)
+ if flushSupport {
+ flusher.Flush()
+ }
+ w.Write([]byte("{\"a\":"))
+ if flushSupport {
+ flusher.Flush()
+ }
+ time.Sleep(time.Millisecond * 20)
+ w.Write([]byte("123}"))
+ if flushSupport {
+ flusher.Flush()
+ }
+ },
`/exit`: func(_ http.ResponseWriter, _ *http.Request) {
s.Server.Shutdown(context.Background())
},
}
}
+type J struct {
+ A int `json:"a"`
+}
+
+func Test_req12(t *testing.T) {
+ r := New()
+ r.Reqf(Rval{
+ Url: "http://" + addr + "/json",
+ Timeout: 10 * 1000,
+ Retry: 2,
+ })
+ var j J
+ json.Unmarshal(r.Respon, &j)
+}
+
func Test_req2(t *testing.T) {
r := New()
{
package part
import (
- "runtime"
"sync"
"sync/atomic"
- "unsafe"
)
type Map struct {
return int(t.size.Load())
}
-type ptr struct {
- p unsafe.Pointer
-}
-
-func (t *ptr) tryStore(v *any) {
- t.p = unsafe.Pointer(v)
- // atomic.StorePointer(&t.p, unsafe.Pointer(v))
-}
-
-func (t *ptr) tryLoad() (any, bool) {
- // p := atomic.LoadPointer(&t.p)
- if t.p == nil {
- return nil, false
- }
- return *(*any)(t.p), true
-}
-
-type pLock struct {
- i unsafe.Pointer
- busy unsafe.Pointer
-}
-
-func (l *pLock) Lock() {
- if l.busy == nil {
- l.busy = unsafe.Pointer(&struct{}{})
- }
- for !atomic.CompareAndSwapPointer(&l.i, nil, l.busy) {
- runtime.Gosched()
- }
-}
-
-func (l *pLock) Locking() bool {
- return atomic.LoadPointer(&l.i) != nil
-}
-
-func (l *pLock) Unlock() {
- atomic.CompareAndSwapPointer(&l.i, l.busy, nil)
+func (t *Map) Copy() (m Map) {
+ t.Range(func(k, v any) bool {
+ m.Store(k, v)
+ return true
+ })
+ return
}
//range
c.Store(1, 1)
c.Range(func(key, value interface{}) bool {
- t.Log(key, value)
if key.(int) != value.(int) {
t.Error(`3`)
}
if v, ok := c.Load(0); ok && v != nil {
t.Error(`4`)
}
- t.Log(c.Len())
c.Delete(1)
if v, ok := c.Load(1); ok && v != nil {
t.Error(`6`)
}
- t.Log(c.Len())
}
func Benchmark_customMap_Set(b *testing.B) {
}
}
+func Test_1(t *testing.T) {
+ var c Map
+ c.Store("o", []string{"111", "222"})
+ m := c.Copy()
+ if v, ok := m.LoadV("o").([]string); !ok || len(v) != 2 || v[0] != "111" || v[1] != "222" {
+ t.Fatal()
+ }
+ c.Delete("o")
+ if v, ok := m.LoadV("o").([]string); !ok || len(v) != 2 || v[0] != "111" || v[1] != "222" {
+ t.Fatal()
+ }
+}
+
func Benchmark_customMap_Range(b *testing.B) {
var c Map
var w = &sync.WaitGroup{}