mirror of
https://github.com/go-kratos/kratos.git
synced 2025-02-19 19:10:08 +02:00
parent
378d1ee3c7
commit
009cf68312
42
container/group/example_test.go
Normal file
42
container/group/example_test.go
Normal file
@ -0,0 +1,42 @@
|
||||
package group
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Counter struct {
|
||||
Value int
|
||||
}
|
||||
|
||||
func (c *Counter) Incr() {
|
||||
c.Value++
|
||||
}
|
||||
|
||||
func ExampleGroup_Get() {
|
||||
group := NewGroup(func() interface{} {
|
||||
fmt.Println("Only Once")
|
||||
return &Counter{}
|
||||
})
|
||||
|
||||
// Create a new Counter
|
||||
group.Get("pass").(*Counter).Incr()
|
||||
|
||||
// Get the created Counter again.
|
||||
group.Get("pass").(*Counter).Incr()
|
||||
// Output:
|
||||
// Only Once
|
||||
}
|
||||
|
||||
func ExampleGroup_Reset() {
|
||||
group := NewGroup(func() interface{} {
|
||||
return &Counter{}
|
||||
})
|
||||
|
||||
// Reset the new function and clear all created objects.
|
||||
group.Reset(func() interface{} {
|
||||
fmt.Println("reset")
|
||||
return &Counter{}
|
||||
})
|
||||
|
||||
// Create a new Counter
|
||||
group.Get("pass").(*Counter).Incr()
|
||||
// Output:reset
|
||||
}
|
64
container/group/group.go
Normal file
64
container/group/group.go
Normal file
@ -0,0 +1,64 @@
|
||||
// Package group provides a sample lazy load container.
|
||||
// The group only creating a new object not until the object is needed by user.
|
||||
// And it will cache all the objects to reduce the creation of object.
|
||||
package group
|
||||
|
||||
import "sync"
|
||||
|
||||
// Group is a lazy load container.
|
||||
type Group struct {
|
||||
new func() interface{}
|
||||
vals map[string]interface{}
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewGroup news a group container.
|
||||
func NewGroup(new func() interface{}) *Group {
|
||||
if new == nil {
|
||||
panic("container.group: can't assign a nil to the new function")
|
||||
}
|
||||
return &Group{
|
||||
new: new,
|
||||
vals: make(map[string]interface{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Get gets the object by the given key.
|
||||
func (g *Group) Get(key string) interface{} {
|
||||
g.RLock()
|
||||
v, ok := g.vals[key]
|
||||
if ok {
|
||||
g.RUnlock()
|
||||
return v
|
||||
}
|
||||
g.RUnlock()
|
||||
|
||||
// slowpath for group don`t have specified key value
|
||||
g.Lock()
|
||||
defer g.Unlock()
|
||||
v, ok = g.vals[key]
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
v = g.new()
|
||||
g.vals[key] = v
|
||||
return v
|
||||
}
|
||||
|
||||
// Reset resets the new function and deletes all existing objects.
|
||||
func (g *Group) Reset(new func() interface{}) {
|
||||
if new == nil {
|
||||
panic("container.group: can't assign a nil to the new function")
|
||||
}
|
||||
g.Lock()
|
||||
g.new = new
|
||||
g.Unlock()
|
||||
g.Clear()
|
||||
}
|
||||
|
||||
// Clear deletes all objects.
|
||||
func (g *Group) Clear() {
|
||||
g.Lock()
|
||||
g.vals = make(map[string]interface{})
|
||||
g.Unlock()
|
||||
}
|
65
container/group/group_test.go
Normal file
65
container/group/group_test.go
Normal file
@ -0,0 +1,65 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGroupGet(t *testing.T) {
|
||||
count := 0
|
||||
g := NewGroup(func() interface{} {
|
||||
count++
|
||||
return count
|
||||
})
|
||||
v := g.Get("key_0")
|
||||
assert.Equal(t, 1, v.(int))
|
||||
|
||||
v = g.Get("key_1")
|
||||
assert.Equal(t, 2, v.(int))
|
||||
|
||||
v = g.Get("key_0")
|
||||
assert.Equal(t, 1, v.(int))
|
||||
assert.Equal(t, 2, count)
|
||||
}
|
||||
|
||||
func TestGroupReset(t *testing.T) {
|
||||
g := NewGroup(func() interface{} {
|
||||
return 1
|
||||
})
|
||||
g.Get("key")
|
||||
call := false
|
||||
g.Reset(func() interface{} {
|
||||
call = true
|
||||
return 1
|
||||
})
|
||||
|
||||
length := 0
|
||||
for range g.vals {
|
||||
length++
|
||||
}
|
||||
|
||||
assert.Equal(t, 0, length)
|
||||
|
||||
g.Get("key")
|
||||
assert.Equal(t, true, call)
|
||||
}
|
||||
|
||||
func TestGroupClear(t *testing.T) {
|
||||
g := NewGroup(func() interface{} {
|
||||
return 1
|
||||
})
|
||||
g.Get("key")
|
||||
length := 0
|
||||
for range g.vals {
|
||||
length++
|
||||
}
|
||||
assert.Equal(t, 1, length)
|
||||
|
||||
g.Clear()
|
||||
length = 0
|
||||
for range g.vals {
|
||||
length++
|
||||
}
|
||||
assert.Equal(t, 0, length)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user