github.com/15mga/kiwi@v0.0.2-0.20240324021231-b95d5c3ac751/worker/share.go (about)

     1  package worker
     2  
     3  import (
     4  	"github.com/15mga/kiwi/util"
     5  	"unsafe"
     6  )
     7  
     8  var (
     9  	_Share *fnShare
    10  )
    11  
    12  func Share() *fnShare {
    13  	return _Share
    14  }
    15  
    16  func InitShare() {
    17  	if _Share != nil {
    18  		return
    19  	}
    20  	_Share = &fnShare{
    21  		count:   int64(_ParallelNum),
    22  		workers: make([]*FnWorker, _ParallelNum),
    23  	}
    24  	_Share.mask = _Share.count - 1
    25  	for i := 0; i < _ParallelNum; i++ {
    26  		w := NewFnWorker()
    27  		w.Start()
    28  		_Share.workers[i] = w
    29  	}
    30  }
    31  
    32  type fnShare struct {
    33  	workers []*FnWorker
    34  	count   int64
    35  	mask    int64
    36  	c       int64
    37  }
    38  
    39  func (s *fnShare) Push(key string, fn util.FnAnySlc, params ...any) {
    40  	s.workers[FnvStr(key)&s.mask].Push(fn, params...)
    41  }
    42  
    43  func (s *fnShare) Dispose() {
    44  	for _, worker := range s.workers {
    45  		worker.Dispose()
    46  	}
    47  }
    48  
    49  var (
    50  	offset64 int64 = -3750763034362895579
    51  	prime64  int64 = 1099511628211
    52  )
    53  
    54  func FnvStr(key string) int64 {
    55  	bytes := util.StrToBytes(key)
    56  	var hash = offset64
    57  	for i := 0; i < len(bytes); i++ {
    58  		hash ^= int64(bytes[i])
    59  		hash *= prime64
    60  	}
    61  	return hash
    62  }
    63  
    64  func FnvBytes(bytes []byte) int64 {
    65  	var hash = offset64
    66  	for i := 0; i < len(bytes); i++ {
    67  		hash ^= int64(bytes[i])
    68  		hash *= prime64
    69  	}
    70  	return hash
    71  }
    72  
    73  func FnvInt64(v int64) int64 {
    74  	var hash = offset64
    75  	bytes := util.Int64ToBytes(v)
    76  	for i := 0; i < len(bytes); i++ {
    77  		hash ^= int64(bytes[i])
    78  		hash *= prime64
    79  	}
    80  	return hash
    81  }
    82  
    83  //go:noescape
    84  //go:linkname memhash runtime.memhash
    85  func memhash(p unsafe.Pointer, h, s uintptr) uintptr
    86  
    87  type stringStruct struct {
    88  	str unsafe.Pointer
    89  	len int
    90  }
    91  
    92  func MemHash(data []byte) int64 {
    93  	ss := (*stringStruct)(unsafe.Pointer(&data))
    94  	return int64(memhash(ss.str, 0, uintptr(ss.len)))
    95  }
    96  
    97  func MemHashString(str string) int64 {
    98  	ss := (*stringStruct)(unsafe.Pointer(&str))
    99  	return int64(memhash(ss.str, 0, uintptr(ss.len)))
   100  }