commit
996beb12a8
2
cache/memorymapcache.go
vendored
2
cache/memorymapcache.go
vendored
|
@ -82,7 +82,7 @@ func (m *MemoryMapCache[K, V]) Ver(_ context.Context, key K) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MemoryMapCache[K, V]) Flush(context.Context) {
|
func (m *MemoryMapCache[K, V]) Flush(context.Context) {
|
||||||
m.Map = safety.NewMap[K, mapVal[V]]()
|
m.Map.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MemoryMapCache[K, V]) Delete(_ context.Context, key K) {
|
func (m *MemoryMapCache[K, V]) Delete(_ context.Context, key K) {
|
||||||
|
|
|
@ -76,8 +76,6 @@ postCommentUrl: http://wp.test/wp-comments-post.php
|
||||||
trustIps: []
|
trustIps: []
|
||||||
# trust servername 信任的域名
|
# trust servername 信任的域名
|
||||||
trustServerNames: ["xy.test","blog.xy.test"]
|
trustServerNames: ["xy.test","blog.xy.test"]
|
||||||
# port
|
|
||||||
port: 8082
|
|
||||||
# 主题 为空值为option template,没有就默认为twentyfifteen
|
# 主题 为空值为option template,没有就默认为twentyfifteen
|
||||||
theme: "twentyfifteen"
|
theme: "twentyfifteen"
|
||||||
# 文档排序默认升序还是降序
|
# 文档排序默认升序还是降序
|
||||||
|
|
63
safety/safemap_test.go
Normal file
63
safety/safemap_test.go
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
package safety
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/fthvgb1/wp-go/helper/number"
|
||||||
|
"github.com/fthvgb1/wp-go/taskPools"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMap_Load(t *testing.T) {
|
||||||
|
type args[K comparable] struct {
|
||||||
|
key K
|
||||||
|
}
|
||||||
|
m := NewMap[int, int]()
|
||||||
|
m.Store(1, 1)
|
||||||
|
type testCase[K comparable, V any] struct {
|
||||||
|
name string
|
||||||
|
m Map[K, V]
|
||||||
|
args args[K]
|
||||||
|
wantValue V
|
||||||
|
wantOk bool
|
||||||
|
}
|
||||||
|
tests := []testCase[int, int]{
|
||||||
|
{
|
||||||
|
name: "t1",
|
||||||
|
m: m,
|
||||||
|
args: args[int]{1},
|
||||||
|
wantValue: 1,
|
||||||
|
wantOk: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p := taskPools.NewPools(10)
|
||||||
|
var a0, a1 []int
|
||||||
|
for i := 0; i < 5000; i++ {
|
||||||
|
v := number.Rand(0, 1)
|
||||||
|
if 1 == v {
|
||||||
|
a1 = append(a1, 1)
|
||||||
|
} else {
|
||||||
|
a0 = append(a0, 0)
|
||||||
|
}
|
||||||
|
p.Execute(func() {
|
||||||
|
if 1 == v {
|
||||||
|
m.Load(number.Rand(2, 1000))
|
||||||
|
} else {
|
||||||
|
m.Store(number.Rand(2, 1000), number.Rand(1, 1000))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
fmt.Println(len(a0), len(a1), m.Len())
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
gotValue, gotOk := tt.m.Load(tt.args.key)
|
||||||
|
if !reflect.DeepEqual(gotValue, tt.wantValue) {
|
||||||
|
t.Errorf("Load() gotValue = %v, want %v", gotValue, tt.wantValue)
|
||||||
|
}
|
||||||
|
if gotOk != tt.wantOk {
|
||||||
|
t.Errorf("Load() gotOk = %v, want %v", gotOk, tt.wantOk)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -68,7 +68,7 @@ func TestSimpleMapFilterAndMapToSlice(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
if got := SimpleMapFilterAndMapToSlice(tt.args.mm, tt.args.fn, tt.args.c).Sort(func(i, j int) bool {
|
if got := SimpleMapFilterAndMapToSlice(tt.args.mm, tt.args.fn).Sort(func(i, j int) bool {
|
||||||
return i < j
|
return i < j
|
||||||
}); !reflect.DeepEqual(got, tt.want) {
|
}); !reflect.DeepEqual(got, tt.want) {
|
||||||
t.Errorf("SimpleMapFilterAndMapToSlice() = %v, want %v", got, tt.want)
|
t.Errorf("SimpleMapFilterAndMapToSlice() = %v, want %v", got, tt.want)
|
||||||
|
|
|
@ -50,14 +50,6 @@ func FilterAndMapNewStream[R, T any](a Stream[T], fn func(T) (R, bool)) Stream[R
|
||||||
return NewStream(slice.FilterAndMap(a.arr, fn))
|
return NewStream(slice.FilterAndMap(a.arr, fn))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParallelMap[R, T any](a Stream[T], fn func(T) R, c int) Stream[R] {
|
|
||||||
var x []R
|
|
||||||
rr := safety.NewSlice(x)
|
|
||||||
a.ParallelForEach(func(t T) {
|
|
||||||
rr.Append(fn(t))
|
|
||||||
}, c)
|
|
||||||
return Stream[R]{rr.Load()}
|
|
||||||
}
|
|
||||||
func MapNewStream[R, T any](a Stream[T], fn func(T) R) Stream[R] {
|
func MapNewStream[R, T any](a Stream[T], fn func(T) R) Stream[R] {
|
||||||
return NewStream(slice.Map(a.arr, fn))
|
return NewStream(slice.Map(a.arr, fn))
|
||||||
}
|
}
|
||||||
|
@ -91,31 +83,24 @@ func (r Stream[T]) ParallelForEach(fn func(T), c int) {
|
||||||
p.Wait()
|
p.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Stream[T]) ParallelFilter(fn func(T) bool, c int) Stream[T] {
|
func (r Stream[T]) ParallelFilterAndMap(fn func(T) (T, bool), c int) Stream[T] {
|
||||||
rr := safety.NewSlice([]T{})
|
rr := safety.NewSlice([]T{})
|
||||||
r.ParallelForEach(func(t T) {
|
r.ParallelForEach(func(t T) {
|
||||||
if fn(t) {
|
v, ok := fn(t)
|
||||||
rr.Append(t)
|
if ok {
|
||||||
|
rr.Append(v)
|
||||||
}
|
}
|
||||||
}, c)
|
}, c)
|
||||||
return Stream[T]{rr.Load()}
|
return Stream[T]{rr.Load()}
|
||||||
}
|
}
|
||||||
func (r Stream[T]) Filter(fn func(T) bool) Stream[T] {
|
|
||||||
r.arr = slice.Filter(r.arr, fn)
|
func (r Stream[T]) FilterAndMap(fn func(T) (T, bool)) Stream[T] {
|
||||||
|
r.arr = slice.FilterAndMap(r.arr, fn)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Stream[T]) ParallelMap(fn func(T) T, c int) Stream[T] {
|
func (r Stream[T]) Reduce(fn func(v, r T) T, init T) T {
|
||||||
rr := safety.NewSlice([]T{})
|
return slice.Reduce[T, T](r.arr, fn, init)
|
||||||
r.ParallelForEach(func(t T) {
|
|
||||||
rr.Append(fn(t))
|
|
||||||
}, c)
|
|
||||||
return Stream[T]{rr.Load()}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r Stream[T]) Map(fn func(T) T) Stream[T] {
|
|
||||||
r.arr = slice.Map(r.arr, fn)
|
|
||||||
return r
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Stream[T]) Sort(fn func(i, j T) bool) Stream[T] {
|
func (r Stream[T]) Sort(fn func(i, j T) bool) Stream[T] {
|
||||||
|
|
|
@ -11,40 +11,6 @@ import (
|
||||||
|
|
||||||
var s = NewStream(number.Range(1, 10, 1))
|
var s = NewStream(number.Range(1, 10, 1))
|
||||||
|
|
||||||
func TestSimpleSliceStream_Filter(t *testing.T) {
|
|
||||||
type args[T int] struct {
|
|
||||||
fn func(T) bool
|
|
||||||
}
|
|
||||||
type testCase[T int] struct {
|
|
||||||
name string
|
|
||||||
r Stream[T]
|
|
||||||
args args[T]
|
|
||||||
want Stream[T]
|
|
||||||
}
|
|
||||||
tests := []testCase[int]{
|
|
||||||
{
|
|
||||||
name: "t1",
|
|
||||||
r: s,
|
|
||||||
args: args[int]{
|
|
||||||
func(t int) (r bool) {
|
|
||||||
if t > 5 {
|
|
||||||
r = true
|
|
||||||
}
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: Stream[int]{number.Range(6, 10, 1)},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if got := tt.r.Filter(tt.args.fn); !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("Filter() = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSimpleSliceStream_ForEach(t *testing.T) {
|
func TestSimpleSliceStream_ForEach(t *testing.T) {
|
||||||
type args[T int] struct {
|
type args[T int] struct {
|
||||||
fn func(T)
|
fn func(T)
|
||||||
|
@ -121,37 +87,6 @@ func TestSimpleSliceStream_Limit(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSimpleSliceStream_Map(t *testing.T) {
|
|
||||||
type args[T int] struct {
|
|
||||||
fn func(T) T
|
|
||||||
}
|
|
||||||
type testCase[T int] struct {
|
|
||||||
name string
|
|
||||||
r Stream[T]
|
|
||||||
args args[T]
|
|
||||||
want Stream[T]
|
|
||||||
}
|
|
||||||
tests := []testCase[int]{
|
|
||||||
{
|
|
||||||
name: "t1",
|
|
||||||
r: s,
|
|
||||||
args: args[int]{
|
|
||||||
func(t int) (r int) {
|
|
||||||
return t * 2
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: Stream[int]{number.Range(2, 20, 2)},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if got := tt.r.Map(tt.args.fn); !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("MapNewStream() = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSimpleSliceStream_Result(t *testing.T) {
|
func TestSimpleSliceStream_Result(t *testing.T) {
|
||||||
type testCase[T int] struct {
|
type testCase[T int] struct {
|
||||||
name string
|
name string
|
||||||
|
@ -234,76 +169,6 @@ func TestSimpleSliceStream_parallelForEach(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSimpleSliceStream_ParallelFilter(t *testing.T) {
|
|
||||||
type args[T int] struct {
|
|
||||||
fn func(T) bool
|
|
||||||
c int
|
|
||||||
}
|
|
||||||
type testCase[T int] struct {
|
|
||||||
name string
|
|
||||||
r Stream[T]
|
|
||||||
args args[T]
|
|
||||||
want Stream[T]
|
|
||||||
}
|
|
||||||
tests := []testCase[int]{
|
|
||||||
{
|
|
||||||
name: "t1",
|
|
||||||
r: s,
|
|
||||||
args: args[int]{
|
|
||||||
fn: func(t int) bool {
|
|
||||||
return t > 3
|
|
||||||
},
|
|
||||||
c: 6,
|
|
||||||
},
|
|
||||||
want: Stream[int]{number.Range(4, 10, 1)},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if got := tt.r.ParallelFilter(tt.args.fn, tt.args.c).Sort(func(i, j int) bool {
|
|
||||||
return i < j
|
|
||||||
}); !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("ParallelFilter() = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSimpleSliceStream_ParallelMap(t *testing.T) {
|
|
||||||
type args[T int] struct {
|
|
||||||
fn func(T) T
|
|
||||||
c int
|
|
||||||
}
|
|
||||||
type testCase[T int] struct {
|
|
||||||
name string
|
|
||||||
r Stream[T]
|
|
||||||
args args[T]
|
|
||||||
want Stream[T]
|
|
||||||
}
|
|
||||||
tests := []testCase[int]{
|
|
||||||
{
|
|
||||||
name: "t1",
|
|
||||||
r: s,
|
|
||||||
args: args[int]{
|
|
||||||
fn: func(t int) int {
|
|
||||||
return t * 2
|
|
||||||
},
|
|
||||||
c: 6,
|
|
||||||
},
|
|
||||||
want: Stream[int]{number.Range(2, 20, 2)},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if got := tt.r.ParallelMap(tt.args.fn, tt.args.c).Sort(func(i, j int) bool {
|
|
||||||
return i < j
|
|
||||||
}); !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("ParallelMap() = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReduce(t *testing.T) {
|
func TestReduce(t *testing.T) {
|
||||||
type args[S, T int] struct {
|
type args[S, T int] struct {
|
||||||
s Stream[S]
|
s Stream[S]
|
||||||
|
@ -391,43 +256,6 @@ func TestSimpleStreamMap(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSimpleParallelMap(t *testing.T) {
|
|
||||||
type args[T string, R int] struct {
|
|
||||||
a Stream[string]
|
|
||||||
fn func(T) R
|
|
||||||
c int
|
|
||||||
}
|
|
||||||
type testCase[T string, R int] struct {
|
|
||||||
name string
|
|
||||||
args args[T, R]
|
|
||||||
want Stream[R]
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := []testCase[string, int]{
|
|
||||||
{
|
|
||||||
name: "t1",
|
|
||||||
args: args[string, int]{
|
|
||||||
a: NewStream(slice.Map(x, strconv.Itoa)),
|
|
||||||
fn: func(s string) int {
|
|
||||||
i, _ := strconv.Atoi(s)
|
|
||||||
return i
|
|
||||||
},
|
|
||||||
c: 6,
|
|
||||||
},
|
|
||||||
want: NewStream(x),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if got := ParallelMap(tt.args.a, tt.args.fn, tt.args.c).Sort(func(i, j int) bool {
|
|
||||||
return i < j
|
|
||||||
}); !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("ParallelMap() = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSimpleParallelFilterAndMap(t *testing.T) {
|
func TestSimpleParallelFilterAndMap(t *testing.T) {
|
||||||
type args[T string, R int] struct {
|
type args[T string, R int] struct {
|
||||||
a Stream[string]
|
a Stream[string]
|
||||||
|
@ -598,3 +426,80 @@ func TestSimpleSliceFilterAndMapToMap(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStream_ParallelFilterAndMap(t *testing.T) {
|
||||||
|
type xy struct {
|
||||||
|
args int
|
||||||
|
res string
|
||||||
|
}
|
||||||
|
type args[T any] struct {
|
||||||
|
fn func(T) (T, bool)
|
||||||
|
c int
|
||||||
|
}
|
||||||
|
type testCase[T xy] struct {
|
||||||
|
name string
|
||||||
|
r Stream[T]
|
||||||
|
args args[T]
|
||||||
|
want Stream[T]
|
||||||
|
}
|
||||||
|
tests := []testCase[xy]{
|
||||||
|
{
|
||||||
|
name: "t1",
|
||||||
|
r: NewStream(slice.Map(number.Range(1, 10, 1), func(t int) xy {
|
||||||
|
return xy{args: t}
|
||||||
|
})),
|
||||||
|
args: args[xy]{func(v xy) (xy, bool) {
|
||||||
|
v.res = strconv.Itoa(v.args)
|
||||||
|
return v, true
|
||||||
|
}, 6},
|
||||||
|
want: NewStream(slice.Map(number.Range(1, 10, 1), func(t int) xy {
|
||||||
|
return xy{args: t, res: strconv.Itoa(t)}
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := tt.r.ParallelFilterAndMap(tt.args.fn, tt.args.c).Sort(func(i, j xy) bool {
|
||||||
|
return i.args < j.args
|
||||||
|
}); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("ParallelFilterAndMap() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStream_Reduce(t *testing.T) {
|
||||||
|
type aa struct {
|
||||||
|
args int
|
||||||
|
res int
|
||||||
|
}
|
||||||
|
type args[T any] struct {
|
||||||
|
fn func(v, r T) T
|
||||||
|
init T
|
||||||
|
}
|
||||||
|
type testCase[T any] struct {
|
||||||
|
name string
|
||||||
|
r Stream[T]
|
||||||
|
args args[T]
|
||||||
|
want T
|
||||||
|
}
|
||||||
|
tests := []testCase[aa]{
|
||||||
|
{
|
||||||
|
name: "t1",
|
||||||
|
r: NewStream(slice.Map(number.Range(1, 10, 1), func(t int) aa {
|
||||||
|
return aa{args: t}
|
||||||
|
})),
|
||||||
|
args: args[aa]{func(v, r aa) aa {
|
||||||
|
return aa{res: v.args + r.res}
|
||||||
|
}, aa{}},
|
||||||
|
want: aa{res: 55},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := tt.r.Reduce(tt.args.fn, tt.args.init); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("Reduce() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user