mirror of
https://github.com/werbenhu/eventbus.git
synced 2025-09-26 20:41:48 +08:00
code optimization
code optimization
This commit is contained in:
28
cowmap.go
28
cowmap.go
@@ -13,6 +13,7 @@ type CowMap struct {
|
|||||||
readable atomic.Value
|
readable atomic.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewCowMap creates a new CowMap instance
|
||||||
func NewCowMap() *CowMap {
|
func NewCowMap() *CowMap {
|
||||||
m := make(tmap)
|
m := make(tmap)
|
||||||
c := &CowMap{}
|
c := &CowMap{}
|
||||||
@@ -20,7 +21,8 @@ func NewCowMap() *CowMap {
|
|||||||
return c
|
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 {
|
func (c *CowMap) clone() tmap {
|
||||||
m := make(tmap)
|
m := make(tmap)
|
||||||
for k, v := range c.readable.Load().(tmap) {
|
for k, v := range c.readable.Load().(tmap) {
|
||||||
@@ -29,30 +31,32 @@ func (c *CowMap) clone() tmap {
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load returns the value stored in the map for a key, or nil if no
|
// Load returns the value stored in the map for a given key,
|
||||||
// value is present.
|
// or nil if the key is not present.
|
||||||
// The ok result indicates whether value was found in the map.
|
// The ok result indicates whether the value was found in the map.
|
||||||
func (c *CowMap) Load(key any) (value any, ok bool) {
|
func (c *CowMap) Load(key any) (value any, ok bool) {
|
||||||
value, ok = c.readable.Load().(tmap)[key]
|
value, ok = c.readable.Load().(tmap)[key]
|
||||||
return
|
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 {
|
func (c *CowMap) Len() int {
|
||||||
return len(c.readable.Load().(tmap))
|
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) {
|
func (c *CowMap) Store(key, value any) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
|
|
||||||
copy := c.clone()
|
copy := c.clone() // create a copy of the map
|
||||||
copy[key] = value
|
copy[key] = value // add the new key-value pair to the copy
|
||||||
c.readable.Store(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) {
|
func (c *CowMap) Delete(key any) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
@@ -63,8 +67,8 @@ func (c *CowMap) Delete(key any) {
|
|||||||
c.readable.Store(copy)
|
c.readable.Store(copy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Range calls f sequentially for each key and value present in the map.
|
// Range calls the provided function for each key-value pair in the map,
|
||||||
// If f returns false, range stops the iteration.
|
// stopping the iteration if the function returns false
|
||||||
func (c *CowMap) Range(f func(key, value any) bool) {
|
func (c *CowMap) Range(f func(key, value any) bool) {
|
||||||
for k, v := range c.readable.Load().(tmap) {
|
for k, v := range c.readable.Load().(tmap) {
|
||||||
if !f(k, v) {
|
if !f(k, v) {
|
||||||
|
@@ -19,6 +19,8 @@ func (e err) Error() string {
|
|||||||
return e.Msg
|
return e.Msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Global variables that represent common errors that may be
|
||||||
|
// returned by the eventbus functions.
|
||||||
var (
|
var (
|
||||||
ErrHandlerIsNotFunc = err{Code: 10000, Msg: "handler is not a function"}
|
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"}
|
ErrHandlerParamNum = err{Code: 10001, Msg: "the number of parameters of the handler must be two"}
|
||||||
|
13
eventbus.go
13
eventbus.go
@@ -5,7 +5,7 @@ import (
|
|||||||
"sync"
|
"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 {
|
type channel struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
bufferSize int
|
bufferSize int
|
||||||
@@ -16,7 +16,9 @@ type channel struct {
|
|||||||
stopCh chan any
|
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 {
|
func newChannel(topic string, bufferSize int) *channel {
|
||||||
var ch chan any
|
var ch chan any
|
||||||
if bufferSize <= 0 {
|
if bufferSize <= 0 {
|
||||||
@@ -35,7 +37,9 @@ func newChannel(topic string, bufferSize int) *channel {
|
|||||||
return c
|
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() {
|
func (c *channel) loop() {
|
||||||
topic := reflect.ValueOf(c.topic)
|
topic := reflect.ValueOf(c.topic)
|
||||||
for {
|
for {
|
||||||
@@ -48,6 +52,9 @@ func (c *channel) loop() {
|
|||||||
typ := handler.Type()
|
typ := handler.Type()
|
||||||
|
|
||||||
if param == nil {
|
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()
|
payload = reflect.New(typ.In(1)).Elem()
|
||||||
} else {
|
} else {
|
||||||
payload = reflect.ValueOf(param)
|
payload = reflect.ValueOf(param)
|
||||||
|
Reference in New Issue
Block a user