diff --git a/README.md b/README.md index 298ae55..4c9d656 100644 --- a/README.md +++ b/README.md @@ -478,6 +478,70 @@ func Encode(b []byte) string ``` +### 高性能 Hash 方法及生成器 + +见: [xhash](xhash) + +
+ DOC + +```go +package xhash // import "github.com/fufuok/utils/xhash" + +func AddBytes32(h uint32, b []byte) uint32 +func AddBytes64(h uint64, b []byte) uint64 +func AddString32(h uint32, s string) uint32 +func AddString64(h uint64, s string) uint64 +func AddUint32(h, u uint32) uint32 +func AddUint64(h uint64, u uint64) uint64 +func Djb33(s string) uint32 +func FnvHash(s string) uint64 +func FnvHash32(s string) uint32 +func GenHasher[K comparable]() func(K) uintptr +func GenHasher64[K comparable]() func(K) uint64 +func GenSeedHasher64[K comparable]() func(maphash.Seed, K) uint64 +func Hash(b []byte, h hash.Hash) []byte +func HashBytes(b ...[]byte) string +func HashBytes32(b ...[]byte) uint32 +func HashBytes64(b ...[]byte) uint64 +func HashSeedString(seed maphash.Seed, s string) uint64 +func HashSeedUint64(seed maphash.Seed, n uint64) uint64 +func HashString(s ...string) string +func HashString32(s ...string) uint32 +func HashString64(s ...string) uint64 +func HashUint32(u uint32) uint32 +func HashUint64(u uint64) uint64 +func Hmac(b []byte, key []byte, h func() hash.Hash) []byte +func HmacSHA1(b, key []byte) []byte +func HmacSHA1Hex(s, key string) string +func HmacSHA256(b, key []byte) []byte +func HmacSHA256Hex(s, key string) string +func HmacSHA512(b, key []byte) []byte +func HmacSHA512Hex(s, key string) string +func MD5(b []byte) []byte +func MD5BytesHex(bs []byte) string +func MD5Hex(s string) string +func MD5Reader(r io.Reader) (string, error) +func MD5Sum(filename string) (string, error) +func MemHash(s string) uint64 +func MemHash32(s string) uint32 +func MemHashb(b []byte) uint64 +func MemHashb32(b []byte) uint32 +func MustMD5Sum(filename string) string +func Sha1(b []byte) []byte +func Sha1Hex(s string) string +func Sha256(b []byte) []byte +func Sha256Hex(s string) string +func Sha512(b []byte) []byte +func Sha512Hex(s string) string +func Sum32(s string) uint32 +func Sum64(s string) uint64 +func SumBytes32(bs []byte) uint32 +func SumBytes64(bs []byte) uint64 +type Hashable interface{ ... } +``` +
+ ### 可排序全局唯一 ID 生成器 比 UUID 更快, 更短 @@ -1036,8 +1100,8 @@ func main() { bus := sched.New() // 默认并发数: runtime.NumCPU() for i := 0; i < 30; i++ { bus.Add(1) - bus.RunWithArgs(func(n interface{}) { - count.Add(int64(n.(int))) + bus.RunWithArgs(func(n ...interface{}) { + count.Add(int64(n[0].(int))) }, i) } bus.Wait() diff --git a/ntp/ntpdate.go b/ntp/ntpdate.go index b8a67b4..6484663 100644 --- a/ntp/ntpdate.go +++ b/ntp/ntpdate.go @@ -113,8 +113,8 @@ func HostPreferred(hosts []string) *HostResponse { s := sched.New() for _, host := range hosts { s.Add(1) - s.RunWithArgs(func(v interface{}) { - host := v.(string) + s.RunWithArgs(func(v ...interface{}) { + host := v[0].(string) if resp := GetResponse(host); resp != nil { m.Store(host, resp) } diff --git a/sched/DOC.md b/sched/DOC.md index a68438c..d89d920 100644 --- a/sched/DOC.md +++ b/sched/DOC.md @@ -17,7 +17,7 @@ import "github.com/fufuok/utils/sched" - [func (p *Pool) IsRunning() bool](<#func-pool-isrunning>) - [func (p *Pool) Release()](<#func-pool-release>) - [func (p *Pool) Run(f ...func())](<#func-pool-run>) - - [func (p *Pool) RunWithArgs(f func(args interface{}), args interface{})](<#func-pool-runwithargs>) + - [func (p *Pool) RunWithArgs(f func(args ...interface{}), args ...interface{})](<#func-pool-runwithargs>) - [func (p *Pool) Running() uint64](<#func-pool-running>) - [func (p *Pool) Wait()](<#func-pool-wait>) - [func (p *Pool) WaitAndRelease()](<#func-pool-waitandrelease>) @@ -94,7 +94,7 @@ Run runs f in the current pool. ### func \(\*Pool\) RunWithArgs ```go -func (p *Pool) RunWithArgs(f func(args interface{}), args interface{}) +func (p *Pool) RunWithArgs(f func(args ...interface{}), args ...interface{}) ``` ### func \(\*Pool\) Running diff --git a/sched/README.md b/sched/README.md index 6a488f8..24269fa 100644 --- a/sched/README.md +++ b/sched/README.md @@ -30,12 +30,12 @@ import ( ) func main() { - var count xsync.Counter + count := xsync.NewCounter() bus := sched.New() // 默认并发数: runtime.NumCPU() for i := 0; i < 30; i++ { bus.Add(1) - bus.RunWithArgs(func(n interface{}) { - count.Add(int64(n.(int))) + bus.RunWithArgs(func(n ...interface{}) { + count.Add(int64(n[0].(int))) }, i) } bus.Wait() diff --git a/sched/examples/main.go b/sched/examples/main.go index de386ad..f9a1a67 100644 --- a/sched/examples/main.go +++ b/sched/examples/main.go @@ -9,12 +9,12 @@ import ( ) func main() { - var count xsync.Counter + count := xsync.NewCounter() bus := sched.New() // 默认并发数: runtime.NumCPU() for i := 0; i < 30; i++ { bus.Add(1) - bus.RunWithArgs(func(n interface{}) { - count.Add(int64(n.(int))) + bus.RunWithArgs(func(n ...interface{}) { + count.Add(int64(n[0].(int))) }, i) } bus.Wait() diff --git a/sched/sched.go b/sched/sched.go index b827a0e..5a015af 100644 --- a/sched/sched.go +++ b/sched/sched.go @@ -20,8 +20,8 @@ type Pool struct { type funcdata struct { fn func() - fg func(interface{}) - ar interface{} + fg func(...interface{}) + ar []interface{} } // Option is a scheduler option. @@ -68,7 +68,7 @@ func New(opts ...Option) *Pool { if d.fn != nil { d.fn() } else { - d.fg(d.ar) + d.fg(d.ar...) } p.complete() } @@ -85,7 +85,7 @@ func (p *Pool) Run(f ...func()) { } } -func (p *Pool) RunWithArgs(f func(args interface{}), args interface{}) { +func (p *Pool) RunWithArgs(f func(args ...interface{}), args ...interface{}) { p.tasks <- funcdata{fg: f, ar: args} } diff --git a/sched/sched_test.go b/sched/sched_test.go index 79252ca..dac2e64 100644 --- a/sched/sched_test.go +++ b/sched/sched_test.go @@ -16,15 +16,33 @@ func TestSched(t *testing.T) { s.Add(10) sum := uint32(0) for i := 0; i < 10; i++ { - s.RunWithArgs(func(n interface{}) { - atomic.AddUint32(&sum, uint32(n.(int))) - }, i) + s.RunWithArgs(func(n ...interface{}) { + atomic.AddUint32(&sum, uint32(n[0].(int))) + atomic.AddUint32(&sum, -uint32(n[1].(int))) + }, i, i) + } + s.Wait() + if sum != 0 { + t.Fatalf("wrong sum, expect: %d, want %d", 0, sum) + } + + s.Add(10) + sum = uint32(0) + for i := 0; i < 10; i++ { + ii := uint32(i) + s.RunWithArgs(func(_ ...interface{}) { + atomic.AddUint32(&sum, ii) + }) } s.Wait() if sum != 45 { t.Fatalf("wrong sum, expect: %d, want %d", 45, sum) } + if s.Running() != 0 { + t.Fatalf("wrong counter inside the pool") + } + s.Add(10) sum = uint32(0) for i := 0; i < 10; i++ { @@ -87,8 +105,8 @@ func BenchmarkSched(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - l.RunWithArgs(func(x interface{}) { - _ = x + l.RunWithArgs(func(x ...interface{}) { + _ = x[0] }, 42) } l.Wait()