code optimization

code optimization
This commit is contained in:
werben
2023-04-23 16:43:13 +08:00
parent c046ae5a30
commit 69948955e1
3 changed files with 28 additions and 15 deletions

View File

@@ -13,6 +13,7 @@ type CowMap struct {
readable atomic.Value
}
// NewCowMap creates a new CowMap instance
func NewCowMap() *CowMap {
m := make(tmap)
c := &CowMap{}
@@ -20,7 +21,8 @@ func NewCowMap() *CowMap {
return c
}
// clone create a copy of the map
// clone creates a copy of the map by iterating over the original map
// and copying its key-value pairs to the new map
func (c *CowMap) clone() tmap {
m := make(tmap)
for k, v := range c.readable.Load().(tmap) {
@@ -29,30 +31,32 @@ func (c *CowMap) clone() tmap {
return m
}
// Load returns the value stored in the map for a key, or nil if no
// value is present.
// The ok result indicates whether value was found in the map.
// Load returns the value stored in the map for a given key,
// or nil if the key is not present.
// The ok result indicates whether the value was found in the map.
func (c *CowMap) Load(key any) (value any, ok bool) {
value, ok = c.readable.Load().(tmap)[key]
return
}
// Len returns how many values stored in the map.
// Len returns the number of key-value pairs stored in the map
func (c *CowMap) Len() int {
return len(c.readable.Load().(tmap))
}
// Store sets the value for a key.
// Store sets the value for a given key by creating a new copy of the map
// and adding the new key-value pair to it
func (c *CowMap) Store(key, value any) {
c.mu.Lock()
defer c.mu.Unlock()
copy := c.clone()
copy[key] = value
c.readable.Store(copy)
copy := c.clone() // create a copy of the map
copy[key] = value // add the new key-value pair to the copy
c.readable.Store(copy) // update the atomic value with the new copy
}
// Delete deletes the value for a key.
// Delete removes a key-value pair from the map by creating a new copy of the map
// and deleting the specified key from it
func (c *CowMap) Delete(key any) {
c.mu.Lock()
defer c.mu.Unlock()
@@ -63,8 +67,8 @@ func (c *CowMap) Delete(key any) {
c.readable.Store(copy)
}
// Range calls f sequentially for each key and value present in the map.
// If f returns false, range stops the iteration.
// Range calls the provided function for each key-value pair in the map,
// stopping the iteration if the function returns false
func (c *CowMap) Range(f func(key, value any) bool) {
for k, v := range c.readable.Load().(tmap) {
if !f(k, v) {

View File

@@ -19,6 +19,8 @@ func (e err) Error() string {
return e.Msg
}
// Global variables that represent common errors that may be
// returned by the eventbus functions.
var (
ErrHandlerIsNotFunc = err{Code: 10000, Msg: "handler is not a function"}
ErrHandlerParamNum = err{Code: 10001, Msg: "the number of parameters of the handler must be two"}

View File

@@ -5,7 +5,7 @@ import (
"sync"
)
// channel is the box of a topic and handlers. a topic corresponds to a channel
// channel is a struct representing a topic and its associated handlers.
type channel struct {
sync.RWMutex
bufferSize int
@@ -16,7 +16,9 @@ type channel struct {
stopCh chan any
}
// newChannel create a channle for a topic
// newChannel creates a new channel with a specified topic and buffer size.
// It initializes the handlers map with NewCowMap function and
// starts a goroutine c.loop() to continuously listen to messages in the channel.
func newChannel(topic string, bufferSize int) *channel {
var ch chan any
if bufferSize <= 0 {
@@ -35,7 +37,9 @@ func newChannel(topic string, bufferSize int) *channel {
return c
}
// loop loops forever, receiving published message from the channel, transfer payload to subscriber by calling handlers
// loop listens to the channel and calls handlers with payload.
// It receives messages from the channel and then iterates over the handlers
// in the handlers map to call them with the payload.
func (c *channel) loop() {
topic := reflect.ValueOf(c.topic)
for {
@@ -48,6 +52,9 @@ func (c *channel) loop() {
typ := handler.Type()
if param == nil {
// If the parameter passed to the handler is nil,
// it initializes a new payload element based on the
// type of the second parameter of the handler using the reflect package.
payload = reflect.New(typ.In(1)).Elem()
} else {
payload = reflect.ValueOf(param)