Skip to content

Commit

Permalink
实现routineLocal
Browse files Browse the repository at this point in the history
  • Loading branch information
lvyahui8 committed Jul 30, 2024
1 parent cb9d2e4 commit 615cfab
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
55 changes: 55 additions & 0 deletions ellyn_common/gls/routine_local.go
Original file line number Diff line number Diff line change
@@ -1 +1,56 @@
package gls

import (
"github.com/lvyahui8/ellyn/ellyn_common/collections"
"sync/atomic"
)

var m = collections.NewConcurrentMap(2048, func(key interface{}) int {
return int(key.(uint64))
})

var localId int64 = 0

type routineLocal struct {
id int64
}

func NewRoutineLocal() *routineLocal {
return &routineLocal{
id: atomic.AddInt64(&localId, 1),
}
}

func (rl *routineLocal) Set(val interface{}) {
goId := GetGoId()
tableVal, ok := m.Load(goId)
var table map[int64]interface{}
if !ok {
table = make(map[int64]interface{})
m.Store(goId, table)
} else {
table = tableVal.(map[int64]interface{})
}
table[rl.id] = val
}

func (rl *routineLocal) Get() (interface{}, bool) {
goId := GetGoId()
tableVal, ok := m.Load(goId)
if !ok {
return nil, false
}
table := tableVal.(map[int64]interface{})
res, ok := table[rl.id]
return res, ok
}

func (rl *routineLocal) Clear() {
goId := GetGoId()
tableVal, ok := m.Load(goId)
if !ok {
return
}
table := tableVal.(map[int64]interface{})
delete(table, rl.id)
}
40 changes: 40 additions & 0 deletions ellyn_common/gls/routine_local_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package gls

import (
"github.com/stretchr/testify/require"
"sync"
"testing"
)

func TestRoutineLocalBasic(t *testing.T) {
local := NewRoutineLocal()
local.Set(1)
val, ok := local.Get()
require.True(t, ok)
require.Equal(t, 1, val)
local.Clear()
val, ok = local.Get()
require.False(t, ok)
require.Nil(t, val)
}

func TestRoutineLocalConcurrent(t *testing.T) {
local := NewRoutineLocal()
local.Set(1)
w := sync.WaitGroup{}
w.Add(1)
go func() {
defer w.Done()
val, ok := local.Get()
require.False(t, ok)
require.Nil(t, val)
local.Set(100)
val, ok = local.Get()
require.True(t, ok)
require.Equal(t, 100, val)
}()
w.Wait()
val, ok := local.Get()
require.True(t, ok)
require.Equal(t, 1, val)
}

0 comments on commit 615cfab

Please sign in to comment.