diff --git a/g/container/gbtree/gbtree.go b/g/container/gbtree/gbtree.go index 5bf90fc97..3547d849c 100644 --- a/g/container/gbtree/gbtree.go +++ b/g/container/gbtree/gbtree.go @@ -1,6 +1,6 @@ // from https://github.com/google/btree -// B+ Tree +// B-Tree package gbtree import ( diff --git a/g/container/gtype/README.MD b/g/container/gtype/README.MD new file mode 100644 index 000000000..729c5f10f --- /dev/null +++ b/g/container/gtype/README.MD @@ -0,0 +1,36 @@ +benchmarks: +```shell +john@johnstation:~/Workspace/Go/GOPATH/src/gitee.com/johng/gf/g/container/gtype$ go test *.go -bench=".*" +goos: linux +goarch: amd64 +BenchmarkInt_Set-8 300000000 5.65 ns/op +BenchmarkInt_Get-8 2000000000 0.35 ns/op +BenchmarkInt_Add-8 300000000 5.68 ns/op +BenchmarkInt32_Set-8 300000000 5.67 ns/op +BenchmarkInt32_Get-8 2000000000 0.36 ns/op +BenchmarkInt32_Add-8 300000000 5.68 ns/op +BenchmarkInt64_Set-8 300000000 5.66 ns/op +BenchmarkInt64_Get-8 2000000000 0.35 ns/op +BenchmarkInt64_Add-8 300000000 5.67 ns/op +BenchmarkUint_Set-8 300000000 5.68 ns/op +BenchmarkUint_Get-8 2000000000 0.34 ns/op +BenchmarkUint_Add-8 300000000 5.68 ns/op +BenchmarkUint32_Set-8 300000000 5.65 ns/op +BenchmarkUint32_Get-8 2000000000 0.34 ns/op +BenchmarkUint32_Add-8 300000000 5.66 ns/op +BenchmarkUint64_Set-8 300000000 5.68 ns/op +BenchmarkUint64_Get-8 2000000000 0.34 ns/op +BenchmarkUint64_Add-8 300000000 5.68 ns/op +BenchmarkBool_Set-8 300000000 5.67 ns/op +BenchmarkBool_Get-8 2000000000 0.34 ns/op +BenchmarkString_Set-8 30000000 48.5 ns/op +BenchmarkString_Get-8 100000000 12.3 ns/op +BenchmarkBytes_Set-8 50000000 34.9 ns/op +BenchmarkBytes_Get-8 100000000 12.5 ns/op +BenchmarkInterface_Set-8 50000000 34.2 ns/op +BenchmarkInterface_Get-8 100000000 12.2 ns/op +PASS +ok command-line-arguments 43.447s +``` + + diff --git a/g/container/gtype/bool.go b/g/container/gtype/bool.go new file mode 100644 index 000000000..4ba580fdd --- /dev/null +++ b/g/container/gtype/bool.go @@ -0,0 +1,39 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync/atomic" +) + +type Bool struct { + val int32 +} + +func NewBool(value...bool) *Bool { + t := &Bool{} + if len(value) > 0 { + if value[0] { + t.val = 1 + } else { + t.val = 0 + } + } + return t +} + +func (t *Bool)Set(value bool) { + if value { + atomic.StoreInt32(&t.val, 1) + } else { + atomic.StoreInt32(&t.val, 0) + } +} + +func (t *Bool)Get() bool { + return atomic.LoadInt32(&t.val) > 0 +} diff --git a/g/container/gtype/bytes.go b/g/container/gtype/bytes.go new file mode 100644 index 000000000..8d07ad113 --- /dev/null +++ b/g/container/gtype/bytes.go @@ -0,0 +1,36 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync" +) + +type Bytes struct { + mu sync.RWMutex + val []byte +} + +func NewBytes(value...[]byte) *Bytes { + if len(value) > 0 { + return &Bytes{val:value[0]} + } + return &Bytes{} +} + +func (t *Bytes)Set(value []byte) { + t.mu.Lock() + t.val = value + t.mu.Unlock() +} + +func (t *Bytes)Get() []byte { + t.mu.RLock() + b := t.val + t.mu.RUnlock() + return b +} diff --git a/g/container/gtype/float32.go b/g/container/gtype/float32.go new file mode 100644 index 000000000..d65e8de3b --- /dev/null +++ b/g/container/gtype/float32.go @@ -0,0 +1,34 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync/atomic" +) + +type Float32 struct { + val uint32 +} + +func NewFloat32(value...float32) *Float32 { + if len(value) > 0 { + return &Float32{val:uint32(value[0])} + } + return &Float32{} +} + +func (t *Float32)Set(value float32) { + atomic.StoreUint32(&t.val, uint32(value)) +} + +func (t *Float32)Get() int { + return int(atomic.LoadUint32(&t.val)) +} + +func (t *Float32)Add(delta float32) int { + return int(atomic.AddUint32(&t.val, uint32(delta))) +} \ No newline at end of file diff --git a/g/container/gtype/float64.go b/g/container/gtype/float64.go new file mode 100644 index 000000000..4959eef67 --- /dev/null +++ b/g/container/gtype/float64.go @@ -0,0 +1,34 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync/atomic" +) + +type Float64 struct { + val uint64 +} + +func NewFloat64(value...float32) *Float64 { + if len(value) > 0 { + return &Float64{val:uint64(value[0])} + } + return &Float64{} +} + +func (t *Float64)Set(value float32) { + atomic.StoreUint64(&t.val, uint64(value)) +} + +func (t *Float64)Get() int { + return int(atomic.LoadUint64(&t.val)) +} + +func (t *Float64)Add(delta float32) int { + return int(atomic.AddUint64(&t.val, uint64(delta))) +} \ No newline at end of file diff --git a/g/container/gtype/gtype.go b/g/container/gtype/gtype.go new file mode 100644 index 000000000..800e75baa --- /dev/null +++ b/g/container/gtype/gtype.go @@ -0,0 +1,8 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +// 并发安全的基本类型. +package gtype diff --git a/g/container/gtype/gtype_test.go b/g/container/gtype/gtype_test.go new file mode 100644 index 000000000..f62a9ee5b --- /dev/null +++ b/g/container/gtype/gtype_test.go @@ -0,0 +1,196 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +// go test *.go -bench=".*" + +package gtype_test + +import ( + "testing" + "gitee.com/johng/gf/g/container/gtype" + "strconv" + "gitee.com/johng/gf/g/encoding/gbinary" +) + +var it = gtype.NewInt() +var it32 = gtype.NewInt32() +var it64 = gtype.NewInt64() +var uit = gtype.NewUint() +var uit32 = gtype.NewUint32() +var uit64 = gtype.NewUint64() +var bl = gtype.NewBool() +var bytes = gtype.NewBytes() +var str = gtype.NewString() +var inf = gtype.NewInterface() + +func BenchmarkInt_Set(b *testing.B) { + for i := 0; i < b.N; i++ { + it.Set(i) + } +} + +func BenchmarkInt_Get(b *testing.B) { + for i := 0; i < b.N; i++ { + it.Get() + } +} + +func BenchmarkInt_Add(b *testing.B) { + for i := 0; i < b.N; i++ { + it.Add(i) + } +} + +func BenchmarkInt32_Set(b *testing.B) { + for i := int32(0); i < int32(b.N); i++ { + it32.Set(i) + } +} + +func BenchmarkInt32_Get(b *testing.B) { + for i := int32(0); i < int32(b.N); i++ { + it32.Get() + } +} + +func BenchmarkInt32_Add(b *testing.B) { + for i := int32(0); i < int32(b.N); i++ { + it32.Add(i) + } +} + +func BenchmarkInt64_Set(b *testing.B) { + for i := int64(0); i < int64(b.N); i++ { + it64.Set(i) + } +} + +func BenchmarkInt64_Get(b *testing.B) { + for i := int64(0); i < int64(b.N); i++ { + it64.Get() + } +} + +func BenchmarkInt64_Add(b *testing.B) { + for i := int64(0); i < int64(b.N); i++ { + it64.Add(i) + } +} + + + +func BenchmarkUint_Set(b *testing.B) { + for i := uint(0); i < uint(b.N); i++ { + uit.Set(i) + } +} + +func BenchmarkUint_Get(b *testing.B) { + for i := uint(0); i < uint(b.N); i++ { + uit.Get() + } +} + +func BenchmarkUint_Add(b *testing.B) { + for i := uint(0); i < uint(b.N); i++ { + uit.Add(i) + } +} + + + +func BenchmarkUint32_Set(b *testing.B) { + for i := uint32(0); i < uint32(b.N); i++ { + uit32.Set(i) + } +} + +func BenchmarkUint32_Get(b *testing.B) { + for i := uint32(0); i < uint32(b.N); i++ { + uit32.Get() + } +} + +func BenchmarkUint32_Add(b *testing.B) { + for i := uint32(0); i < uint32(b.N); i++ { + uit32.Add(i) + } +} + + +func BenchmarkUint64_Set(b *testing.B) { + for i := uint64(0); i < uint64(b.N); i++ { + uit64.Set(i) + } +} + +func BenchmarkUint64_Get(b *testing.B) { + for i := uint64(0); i < uint64(b.N); i++ { + uit64.Get() + } +} + +func BenchmarkUint64_Add(b *testing.B) { + for i := uint64(0); i < uint64(b.N); i++ { + uit64.Add(i) + } +} + + + +func BenchmarkBool_Set(b *testing.B) { + for i := 0; i < b.N; i++ { + bl.Set(true) + } +} + +func BenchmarkBool_Get(b *testing.B) { + for i := 0; i < b.N; i++ { + bl.Get() + } +} + + + +func BenchmarkString_Set(b *testing.B) { + for i := 0; i < b.N; i++ { + str.Set(strconv.Itoa(i)) + } +} + +func BenchmarkString_Get(b *testing.B) { + for i := 0; i < b.N; i++ { + str.Get() + } +} + + + +func BenchmarkBytes_Set(b *testing.B) { + for i := 0; i < b.N; i++ { + bytes.Set(gbinary.EncodeInt(i)) + } +} + +func BenchmarkBytes_Get(b *testing.B) { + for i := 0; i < b.N; i++ { + bytes.Get() + } +} + + +func BenchmarkInterface_Set(b *testing.B) { + for i := 0; i < b.N; i++ { + inf.Set(i) + } +} + +func BenchmarkInterface_Get(b *testing.B) { + for i := 0; i < b.N; i++ { + inf.Get() + } +} + diff --git a/g/container/gtype/int.go b/g/container/gtype/int.go new file mode 100644 index 000000000..ffd0ce041 --- /dev/null +++ b/g/container/gtype/int.go @@ -0,0 +1,34 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync/atomic" +) + +type Int struct { + val int64 +} + +func NewInt(value...int) *Int { + if len(value) > 0 { + return &Int{val:int64(value[0])} + } + return &Int{} +} + +func (t *Int)Set(value int) { + atomic.StoreInt64(&t.val, int64(value)) +} + +func (t *Int)Get() int { + return int(atomic.LoadInt64(&t.val)) +} + +func (t *Int)Add(delta int) int { + return int(atomic.AddInt64(&t.val, int64(delta))) +} \ No newline at end of file diff --git a/g/container/gtype/int32.go b/g/container/gtype/int32.go new file mode 100644 index 000000000..fac7d1081 --- /dev/null +++ b/g/container/gtype/int32.go @@ -0,0 +1,34 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync/atomic" +) + +type Int32 struct { + val int32 +} + +func NewInt32(value...int32) *Int32 { + if len(value) > 0 { + return &Int32{val:value[0]} + } + return &Int32{} +} + +func (t *Int32)Set(value int32) { + atomic.StoreInt32(&t.val, value) +} + +func (t *Int32)Get() int32 { + return atomic.LoadInt32(&t.val) +} + +func (t *Int32)Add(delta int32) int32 { + return atomic.AddInt32(&t.val, delta) +} \ No newline at end of file diff --git a/g/container/gtype/int64.go b/g/container/gtype/int64.go new file mode 100644 index 000000000..35b24f5e2 --- /dev/null +++ b/g/container/gtype/int64.go @@ -0,0 +1,34 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync/atomic" +) + +type Int64 struct { + val int64 +} + +func NewInt64(value...int64) *Int64 { + if len(value) > 0 { + return &Int64{val:value[0]} + } + return &Int64{} +} + +func (t *Int64)Set(value int64) { + atomic.StoreInt64(&t.val, value) +} + +func (t *Int64)Get() int64 { + return atomic.LoadInt64(&t.val) +} + +func (t *Int64)Add(delta int64) int64 { + return atomic.AddInt64(&t.val, delta) +} \ No newline at end of file diff --git a/g/container/gtype/interface.go b/g/container/gtype/interface.go new file mode 100644 index 000000000..6d2e7ca0f --- /dev/null +++ b/g/container/gtype/interface.go @@ -0,0 +1,36 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync" +) + +type Interface struct { + mu sync.RWMutex + val interface{} +} + +func NewInterface(value...interface{}) *Interface { + if len(value) > 0 { + return &Interface{val:value[0]} + } + return &Interface{} +} + +func (t *Interface)Set(value interface{}) { + t.mu.Lock() + t.val = value + t.mu.Unlock() +} + +func (t *Interface)Get() interface{} { + t.mu.RLock() + b := t.val + t.mu.RUnlock() + return b +} diff --git a/g/container/gtype/string.go b/g/container/gtype/string.go new file mode 100644 index 000000000..a4fddc837 --- /dev/null +++ b/g/container/gtype/string.go @@ -0,0 +1,36 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync" +) + +type String struct { + mu sync.RWMutex + val string +} + +func NewString(value...string) *String { + if len(value) > 0 { + return &String{val:value[0]} + } + return &String{} +} + +func (t *String)Set(value string) { + t.mu.Lock() + t.val = value + t.mu.Unlock() +} + +func (t *String)Get() string { + t.mu.RLock() + s := t.val + t.mu.RUnlock() + return s +} diff --git a/g/container/gtype/uint.go b/g/container/gtype/uint.go new file mode 100644 index 000000000..5b9e75096 --- /dev/null +++ b/g/container/gtype/uint.go @@ -0,0 +1,34 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync/atomic" +) + +type Uint struct { + val uint64 +} + +func NewUint(value...uint) *Uint { + if len(value) > 0 { + return &Uint{val:uint64(value[0])} + } + return &Uint{} +} + +func (t *Uint)Set(value uint) { + atomic.StoreUint64(&t.val, uint64(value)) +} + +func (t *Uint)Get() uint { + return uint(atomic.LoadUint64(&t.val)) +} + +func (t *Uint)Add(delta uint) int { + return int(atomic.AddUint64(&t.val, uint64(delta))) +} \ No newline at end of file diff --git a/g/container/gtype/uint32.go b/g/container/gtype/uint32.go new file mode 100644 index 000000000..acf575eaf --- /dev/null +++ b/g/container/gtype/uint32.go @@ -0,0 +1,34 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync/atomic" +) + +type Uint32 struct { + val uint32 +} + +func NewUint32(value...uint32) *Uint32 { + if len(value) > 0 { + return &Uint32{val:value[0]} + } + return &Uint32{} +} + +func (t *Uint32)Set(value uint32) { + atomic.StoreUint32(&t.val, value) +} + +func (t *Uint32)Get() uint32 { + return atomic.LoadUint32(&t.val) +} + +func (t *Uint32)Add(delta uint32) uint32 { + return atomic.AddUint32(&t.val, delta) +} \ No newline at end of file diff --git a/g/container/gtype/uint64.go b/g/container/gtype/uint64.go new file mode 100644 index 000000000..a62e528fc --- /dev/null +++ b/g/container/gtype/uint64.go @@ -0,0 +1,34 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gtype + +import ( + "sync/atomic" +) + +type Uint64 struct { + val uint64 +} + +func NewUint64(value...uint64) *Uint64 { + if len(value) > 0 { + return &Uint64{val:value[0]} + } + return &Uint64{} +} + +func (t *Uint64)Set(value uint64) { + atomic.StoreUint64(&t.val, value) +} + +func (t *Uint64)Get() uint64 { + return atomic.LoadUint64(&t.val) +} + +func (t *Uint64)Add(delta uint64) uint64 { + return atomic.AddUint64(&t.val, delta) +} \ No newline at end of file