Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
rushuinet committed Apr 7, 2021
1 parent 1a3eaf6 commit 5b2fa8d
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 15 deletions.
16 changes: 1 addition & 15 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
.idea/*
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,31 @@
# gls
goroutine local storage

# demo
```
package main
import (
"fmt"
"github.com/go-basic/gls"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(idx int) {
defer wg.Done()
defer gls.Clean()
defer func() {
fmt.Printf("%d: number = %d\n", idx, gls.Get("number"))
}()
gls.Set("number", idx+100)
}(i)
}
wg.Wait()
}
```
24 changes: 24 additions & 0 deletions examples/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"fmt"
"github.com/go-basic/gls"
"sync"
)

func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(idx int) {
defer wg.Done()
defer gls.Clean()

defer func() {
fmt.Printf("%d: number = %d\n", idx, gls.Get("number"))
}()
gls.Set("number", idx+100)
}(i)
}
wg.Wait()
}
55 changes: 55 additions & 0 deletions gls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package gls

import (
"fmt"
"runtime"
"strconv"
"strings"
"sync"
)

var gls struct {
m map[int64]map[interface{}]interface{}
sync.RWMutex
}

func init() {
gls.m = make(map[int64]map[interface{}]interface{})
}

func GetGoId() int64 {
var (
buf [64]byte
n = runtime.Stack(buf[:], false)
stk = strings.TrimPrefix(string(buf[:n]), "goroutine ")
)
idField := strings.Fields(stk)[0]
id, err := strconv.Atoi(idField)
if err != nil {
panic(fmt.Errorf("can not get goroutine id: %v", err))
}
return int64(id)
}

func Get(key interface{}) interface{} {
gls.RLock()
defer gls.RUnlock()
goId := GetGoId()
return gls.m[goId][key]
}

func Set(key interface{}, v interface{}) {
gls.Lock()
defer gls.Unlock()
goId := GetGoId()
if _, ok := gls.m[goId][key]; !ok {
gls.m[goId] = make(map[interface{}]interface{})
}
gls.m[goId][key] = v
}

func Clean() {
gls.Lock()
defer gls.Unlock()
delete(gls.m, GetGoId())
}
51 changes: 51 additions & 0 deletions gls_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package gls

import (
"fmt"
"strconv"
"testing"
)

var key = "test"

func GO(fn func()) {
go fn()
}

func TestGls(t *testing.T) {
GO(func() {
defer Clean()
Set(key, "aaa")
testPrint()
})
GO(func() {
defer Clean()
Set(key, "bbb")
testPrint()
})
GO(func() {
defer Clean()
Set(key, "ccc")
testPrint()
})
}


func BenchmarkGls(b *testing.B) {
for i := 0; i < b.N; i++ {
GO(func() {
defer Clean()
Set(key, "ccc"+strconv.FormatInt(GetGoId(), 10))
testGet()
})
}
}

func testPrint() {
fmt.Println(Get(key), GetGoId())
}

func testGet() {
Get(key)
}

3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/go-basic/gls

go 1.15

0 comments on commit 5b2fa8d

Please sign in to comment.