update Channel.go

This commit is contained in:
tursom 2023-04-19 21:08:12 +08:00
parent c749131351
commit c7e46ba377
14 changed files with 365 additions and 33 deletions

View File

@ -9,11 +9,13 @@ package concurrent
type (
Lock interface {
Lock()
TryLock() bool
Unlock()
}
RWLock interface {
Lock
RLock()
TryRLock() bool
RUnlock()
}
)

View File

@ -29,6 +29,25 @@ func NewReentrantLock() *ReentrantLock {
return res
}
func (rt *ReentrantLock) TryLock() bool {
id := GetGoroutineID()
rt.lock.Lock()
defer rt.lock.Unlock()
if rt.host == id {
rt.recursion++
return true
}
if rt.recursion == 0 {
rt.host = id
rt.recursion = 1
return true
}
return false
}
func (rt *ReentrantLock) Lock() {
id := GetGoroutineID()
rt.lock.Lock()

View File

@ -48,6 +48,26 @@ func (rt *ReentrantRWLock) Lock() {
rt.rlock.Lock()
}
func (rt *ReentrantRWLock) TryLock() bool {
id := GetGoroutineID()
rt.lock.Lock()
defer rt.lock.Unlock()
if rt.host == id {
rt.recursion++
return true
}
if rt.recursion == 0 {
rt.host = id
rt.recursion = 1
rt.rlock.Lock()
return true
}
return false
}
func (rt *ReentrantRWLock) Unlock() {
rt.lock.Lock()
defer rt.lock.Unlock()
@ -70,6 +90,13 @@ func (rt *ReentrantRWLock) RLock() {
rt.rlock.RLock()
}
func (rt *ReentrantRWLock) TryRLock() bool {
if rt.host == GetGoroutineID() {
return true
}
return rt.rlock.TryRLock()
}
func (rt *ReentrantRWLock) RUnlock() {
if rt.host == GetGoroutineID() {
return

View File

@ -31,7 +31,7 @@ func TestMessageQueue_Subscribe(t *testing.T) {
}()
for true {
msg := subscribe.Receive()
msg, _ := subscribe.Receive()
fmt.Println(id, msg)
}
}()

View File

@ -23,8 +23,104 @@ func (a Array[T]) Array() []T {
return a
}
func FromRawInt8Array(arr []int8) Int8Array {
return *(*Int8Array)(unsafe.Pointer(&arr))
}
func FromRawInt16Array(arr []int16) Int16Array {
return *(*Int16Array)(unsafe.Pointer(&arr))
}
func FromRawInt32Array(arr []int32) Int32Array {
return *(*Int32Array)(unsafe.Pointer(&arr))
}
func FromRawInt64Array(arr []int64) Int64Array {
return *(*Int64Array)(unsafe.Pointer(&arr))
}
func FromRawUInt8Array(arr []uint8) UInt8Array {
return *(*UInt8Array)(unsafe.Pointer(&arr))
}
func FromRawUInt16Array(arr []uint16) UInt16Array {
return *(*UInt16Array)(unsafe.Pointer(&arr))
}
func FromRawUInt32Array(arr []uint32) UInt32Array {
return *(*UInt32Array)(unsafe.Pointer(&arr))
}
func FromRawUInt64Array(arr []uint64) UInt64Array {
return *(*UInt64Array)(unsafe.Pointer(&arr))
}
func FromRawFloat32Array(arr []float32) Float32Array {
return *(*Float32Array)(unsafe.Pointer(&arr))
}
func FromRawFloat64Array(arr []float64) Float64Array {
return *(*Float64Array)(unsafe.Pointer(&arr))
}
func FromRawComplex64Array(arr []complex64) Complex64Array {
return *(*Complex64Array)(unsafe.Pointer(&arr))
}
func FromRawComplex128Array(arr []complex128) Complex128Array {
return *(*Complex128Array)(unsafe.Pointer(&arr))
}
func (a UInt8Array) Bytes() []byte {
return *(*[]byte)(unsafe.Pointer(&a))
return a.Raw()
}
func (a Int8Array) Raw() []int8 {
return *(*[]int8)(unsafe.Pointer(&a))
}
func (a Int16Array) Raw() []int16 {
return *(*[]int16)(unsafe.Pointer(&a))
}
func (a Int32Array) Raw() []int32 {
return *(*[]int32)(unsafe.Pointer(&a))
}
func (a Int64Array) Raw() []int64 {
return *(*[]int64)(unsafe.Pointer(&a))
}
func (a UInt8Array) Raw() []uint8 {
return *(*[]uint8)(unsafe.Pointer(&a))
}
func (a UInt16Array) Raw() []uint16 {
return *(*[]uint16)(unsafe.Pointer(&a))
}
func (a UInt32Array) Raw() []uint32 {
return *(*[]uint32)(unsafe.Pointer(&a))
}
func (a UInt64Array) Raw() []uint64 {
return *(*[]uint64)(unsafe.Pointer(&a))
}
func (a Float32Array) Raw() []float32 {
return *(*[]float32)(unsafe.Pointer(&a))
}
func (a Float64Array) Raw() []float64 {
return *(*[]float64)(unsafe.Pointer(&a))
}
func (a Complex64Array) Raw() []complex64 {
return *(*[]complex64)(unsafe.Pointer(&a))
}
func (a Complex128Array) Raw() []complex128 {
return *(*[]complex128)(unsafe.Pointer(&a))
}
func (a Int8Array) BitLength() uint {
@ -91,34 +187,66 @@ func (a UInt64Array) GetBit(index uint) (ok bool) {
return GetBit(a[index/64], index%64)
}
func (a Int8Array) SetBit(index uint, up bool) (old bool) {
func (a Int8Array) SetBit(index uint, up bool) {
SetBit(&a[index/8], index%8, up)
}
func (a Int16Array) SetBit(index uint, up bool) {
SetBit(&a[index/16], index%16, up)
}
func (a Int32Array) SetBit(index uint, up bool) {
SetBit(&a[index/32], index%32, up)
}
func (a Int64Array) SetBit(index uint, up bool) {
SetBit(&a[index/64], index%64, up)
}
func (a UInt8Array) SetBit(index uint, up bool) {
SetBit(&a[index/8], index%8, up)
}
func (a UInt16Array) SetBit(index uint, up bool) {
SetBit(&a[index/16], index%16, up)
}
func (a UInt32Array) SetBit(index uint, up bool) {
SetBit(&a[index/32], index%32, up)
}
func (a UInt64Array) SetBit(index uint, up bool) {
SetBit(&a[index/64], index%64, up)
}
func (a Int8Array) SwapBit(index uint, up bool) (old bool) {
return SwapBit(&a[index/8], index%8, up)
}
func (a Int16Array) SetBit(index uint, up bool) (old bool) {
func (a Int16Array) SwapBit(index uint, up bool) (old bool) {
return SwapBit(&a[index/16], index%16, up)
}
func (a Int32Array) SetBit(index uint, up bool) (old bool) {
func (a Int32Array) SwapBit(index uint, up bool) (old bool) {
return SwapBit(&a[index/32], index%32, up)
}
func (a Int64Array) SetBit(index uint, up bool) (old bool) {
func (a Int64Array) SwapBit(index uint, up bool) (old bool) {
return SwapBit(&a[index/64], index%64, up)
}
func (a UInt8Array) SetBit(index uint, up bool) (old bool) {
func (a UInt8Array) SwapBit(index uint, up bool) (old bool) {
return SwapBit(&a[index/8], index%8, up)
}
func (a UInt16Array) SetBit(index uint, up bool) (old bool) {
func (a UInt16Array) SwapBit(index uint, up bool) (old bool) {
return SwapBit(&a[index/16], index%16, up)
}
func (a UInt32Array) SetBit(index uint, up bool) (old bool) {
func (a UInt32Array) SwapBit(index uint, up bool) (old bool) {
return SwapBit(&a[index/32], index%32, up)
}
func (a UInt64Array) SetBit(index uint, up bool) (old bool) {
func (a UInt64Array) SwapBit(index uint, up bool) (old bool) {
return SwapBit(&a[index/64], index%64, up)
}

View File

@ -9,7 +9,8 @@ package lang
type (
BitSet interface {
BitLength() uint
SetBit(index uint, up bool) (old bool)
SetBit(index uint, up bool)
SwapBit(index uint, up bool) (old bool)
GetBit(index uint) (ok bool)
}
)

View File

@ -19,8 +19,9 @@ type (
ReceiveChannel[T any] interface {
Close()
// RCh raw channel
RCh() <-chan T
Receive() T
Receive() (T, bool)
TryReceive() (T, bool)
ReceiveTimeout(timeout time.Duration) (T, bool)
}
@ -102,8 +103,9 @@ func (ch RawChannel[T]) RCh() <-chan T {
return ch
}
func (ch RawChannel[T]) Receive() T {
return <-ch
func (ch RawChannel[T]) Receive() (T, bool) {
value, ok := <-ch
return value, ok
}
func (ch RawChannel[T]) TryReceive() (T, bool) {

View File

@ -6,7 +6,9 @@
package lang
import "time"
import (
"time"
)
type (
convChannel[T1, T2 any] struct {
@ -71,8 +73,13 @@ func (c *convChannel[T1, T2]) RCh() <-chan T2 {
return nil
}
func (c *convChannel[T1, T2]) Receive() T2 {
return c.recvConv(c.channel.Receive())
func (c *convChannel[T1, T2]) Receive() (T2, bool) {
value, ok := c.channel.Receive()
if !ok {
return Nil[T2](), false
}
return c.recvConv(value), true
}
func (c *convChannel[T1, T2]) TryReceive() (T2, bool) {
@ -141,8 +148,13 @@ func (c *convReceiveChannel[T1, T2]) RCh() <-chan T2 {
return nil
}
func (c *convReceiveChannel[T1, T2]) Receive() T2 {
return c.recvConv(c.channel.Receive())
func (c *convReceiveChannel[T1, T2]) Receive() (T2, bool) {
value, ok := c.channel.Receive()
if !ok {
return Nil[T2](), false
}
return c.recvConv(value), true
}
func (c *convReceiveChannel[T1, T2]) TryReceive() (T2, bool) {
@ -171,13 +183,13 @@ func (c *filterReceiveChannel[T]) RCh() <-chan T {
return nil
}
func (f *filterReceiveChannel[T]) Receive() T {
obj := f.ReceiveChannel.Receive()
func (f *filterReceiveChannel[T]) Receive() (T, bool) {
obj, _ := f.ReceiveChannel.Receive()
for !f.filter(obj) {
obj = f.ReceiveChannel.Receive()
obj, _ = f.ReceiveChannel.Receive()
}
return obj
return obj, false
}
func (f *filterReceiveChannel[T]) TryReceive() (T, bool) {

View File

@ -19,16 +19,34 @@ func GetBit[T int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 |
return p&location != 0
}
func SetBit[T int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 |
Int8 | Int16 | Int32 | Int64 | UInt8 | UInt16 | UInt32 | UInt64](p *T, index uint, new bool) {
location := T(1) << index
if new {
*p |= location
} else {
*p &= ^location
}
}
func UpBit[T int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 |
Int8 | Int16 | Int32 | Int64 | UInt8 | UInt16 | UInt32 | UInt64](p *T, index uint) {
*p |= T(1) << index
}
func DownBit[T int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 |
Int8 | Int16 | Int32 | Int64 | UInt8 | UInt16 | UInt32 | UInt64](p *T, index uint) {
*p &= ^(T(1) << index)
}
func SwapBit[T int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 |
Int8 | Int16 | Int32 | Int64 | UInt8 | UInt16 | UInt32 | UInt64](p *T, index uint, new bool) (old bool) {
location := T(1) << index
oldValue := *p
var newValue T
if new {
newValue = oldValue | location
*p = oldValue | location
} else {
newValue = oldValue & ^location
*p = oldValue & ^location
}
*p = newValue
return oldValue&location != 0
}

View File

@ -3,8 +3,6 @@ package unsafe
import (
"reflect"
"unsafe"
"github.com/tursom/GoCollections/lang"
)
type slice struct {
@ -13,6 +11,16 @@ type slice struct {
cap int
}
type iface struct {
tab *struct{}
data unsafe.Pointer
}
func Nil[T any]() T {
var n T
return n
}
func ForceCast[T any](v unsafe.Pointer) *T {
if v == nil {
return nil
@ -22,13 +30,13 @@ func ForceCast[T any](v unsafe.Pointer) *T {
}
func Sizeof[T any]() uintptr {
return unsafe.Sizeof(lang.Nil[T]())
return unsafe.Sizeof(Nil[T]())
}
// AsBytes cast any slice as []byte with same pinter, real len and real cap
func AsBytes[T any](arr []T) []byte {
sarr := *ForceCast[slice](unsafe.Pointer(&arr))
typeAlign := reflect.TypeOf(lang.Nil[T]()).Align()
typeAlign := reflect.TypeOf(Nil[T]()).Align()
asBytes := unsafe.Pointer(&slice{
array: sarr.array,
len: sarr.len * typeAlign,
@ -38,6 +46,36 @@ func AsBytes[T any](arr []T) []byte {
return *ForceCast[[]byte](asBytes)
}
func AsBytes1[T any](value *T) []byte {
typeAlign := reflect.TypeOf(value).Align()
asBytes := unsafe.Pointer(&slice{
array: unsafe.Pointer(value),
len: typeAlign,
cap: typeAlign,
})
return *ForceCast[[]byte](asBytes)
}
func AsBytes2(value any) []byte {
typeAlign := reflect.TypeOf(value).Align()
asBytes := unsafe.Pointer(&slice{
array: InterfacePointer(value),
len: typeAlign,
cap: typeAlign,
})
return *ForceCast[[]byte](asBytes)
}
func InterfacePointer(i any) unsafe.Pointer {
return ForceCast[iface](unsafe.Pointer(&i)).data
}
func InterfaceForceCast[T any](i any) *T {
return ForceCast[T](ForceCast[iface](unsafe.Pointer(&i)).data)
}
// AsString cast bytes as string
func AsString(bytes []byte) string {
return *ForceCast[string](unsafe.Pointer(&bytes))

14
unsafe/unsafe_test.go Normal file
View File

@ -0,0 +1,14 @@
package unsafe
import (
"fmt"
"testing"
"unsafe"
)
func TestAsBytes1(t *testing.T) {
i := 1
var a any = i
bs := AsBytes2(i)
fmt.Println(i, bs, AsBytes1(&a), *(*int)(ForceCast[iface](unsafe.Pointer(&a)).data))
}

View File

@ -1,5 +1,6 @@
package bloom
import "C"
import (
"encoding/binary"
"io"

View File

@ -10,7 +10,9 @@ import (
"bytes"
"compress/gzip"
"fmt"
"math"
"testing"
"time"
)
func TestBloom_Contains(t *testing.T) {
@ -32,6 +34,51 @@ func TestBloom_Contains(t *testing.T) {
}
}
func TestBloom_miss(t *testing.T) {
//HashFunc = func(data []byte, seed uint32) uint32 {
// return murmur3.Sum32WithSeed(data, seed)
// // h1, _ := murmur3.Sum128WithSeed(data, seed)
// // return uint32(h1)
//}
var base uint = 1000_0000
bloom := NewBloom(base, 0.03)
t1 := time.Now()
for i := 0; i < int(base/1000); i++ {
bloom.Add([]byte(fmt.Sprintf("%d", i)))
}
counter := make([]uint, 256)
for _, value := range bloom.m {
counter[value]++
}
miss := 0
for i := base; i < base*2; i++ {
if bloom.Contains([]byte(fmt.Sprintf("%d", i))) {
miss += 1
}
}
t2 := time.Now()
fmt.Println(miss, float64(miss)/float64(base))
fmt.Println(counter)
var H float64
for _, c := range counter {
if c == 0 {
continue
}
p := float64(c) / float64(len(bloom.m))
H += -p * math.Log2(p)
}
fmt.Println(H / 8)
fmt.Println(t2.Sub(t1))
}
func gz(b []byte) []byte {
buffer := bytes.NewBuffer(nil)
@ -43,8 +90,8 @@ func gz(b []byte) []byte {
}
func TestCalcBitLength(t *testing.T) {
//fmt.Printf("%d\n", CalcBitLength(100_0000, 0.1)/8)
for i := 1; i < 63; i++ {
//fmt.Printf("%d\n", CalcBitLength(1024*1024*1024, 0.03)/8)
for i := 0; i < 63; i++ {
var n uint = 1 << i
numBytes := CalcBitLength(n, 0.1) / 8
fmt.Printf("%d: %d, %s / %s = %f\n",

23
util/bloom/hash.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include<stdint.h>
uint32_t hash(uint8_t* data, size_t size, uint32_t seed) {
uint32_t hash = seed;
switch (size % sizeof(uint32_t)) {
case 3:
hash = hash*31 ^ *data++;
case 2:
hash = hash*31 ^ *data++;
case 1:
hash = hash*31 ^ *data++;
}
int n = size / sizeof(uint32_t);
for (int i = 0; i < n; i++) {
hash = hash*31 ^ *(uint32_t*)data;
data += sizeof(uint32_t);
}
return hash;
}