Ctx added
This commit is contained in:
parent
bb7cc9739c
commit
178411f148
105
ctx/ctx.go
Normal file
105
ctx/ctx.go
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
package ctx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewCtx(parent Ctx) Ctx {
|
||||||
|
c := &defaultCtx{
|
||||||
|
parent: parent,
|
||||||
|
}
|
||||||
|
c.attributes = make(map[interface{}]interface{})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type Ctx interface {
|
||||||
|
Parent() Ctx
|
||||||
|
SetAttribute(key interface{}, value interface{})
|
||||||
|
GetAttribute(key interface{}) (value interface{})
|
||||||
|
RemoveAttribute(key interface{})
|
||||||
|
ContainsAttribute(key interface{}) (exist bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
type defaultCtx struct {
|
||||||
|
parent Ctx
|
||||||
|
attributes map[interface{}]interface{}
|
||||||
|
|
||||||
|
mtx sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dc *defaultCtx) Parent() Ctx {
|
||||||
|
return dc.parent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dc *defaultCtx) SetAttribute(key interface{}, value interface{}) {
|
||||||
|
dc.checkInitialized()
|
||||||
|
|
||||||
|
if key == nil {
|
||||||
|
panic("nil key")
|
||||||
|
}
|
||||||
|
if !reflect.TypeOf(key).Comparable() {
|
||||||
|
panic("key is not comparable")
|
||||||
|
}
|
||||||
|
|
||||||
|
dc.mtx.Lock()
|
||||||
|
defer dc.mtx.Unlock()
|
||||||
|
|
||||||
|
dc.attributes[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dc *defaultCtx) GetAttribute(key interface{}) (value interface{}) {
|
||||||
|
dc.checkInitialized()
|
||||||
|
|
||||||
|
dc.mtx.RLock()
|
||||||
|
defer dc.mtx.RUnlock()
|
||||||
|
|
||||||
|
if _, ok := dc.attributes[key]; ok {
|
||||||
|
return dc.attributes[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
if nil == dc.parent {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return dc.parent.GetAttribute(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dc *defaultCtx) RemoveAttribute(key interface{}) {
|
||||||
|
dc.checkInitialized()
|
||||||
|
|
||||||
|
dc.mtx.Lock()
|
||||||
|
defer dc.mtx.Unlock()
|
||||||
|
|
||||||
|
if _, ok := dc.attributes[key]; ok {
|
||||||
|
delete(dc.attributes, key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if nil == dc.parent {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dc.parent.RemoveAttribute(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dc *defaultCtx) ContainsAttribute(key interface{}) (exist bool) {
|
||||||
|
dc.checkInitialized()
|
||||||
|
|
||||||
|
dc.mtx.RLock()
|
||||||
|
defer dc.mtx.RUnlock()
|
||||||
|
|
||||||
|
if _, ok := dc.attributes[key]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if nil == dc.parent {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return dc.parent.ContainsAttribute(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dc *defaultCtx) checkInitialized() {
|
||||||
|
if nil == dc.attributes {
|
||||||
|
panic("Attribute Manager: must be initialized")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user