Skip to content

Instantly share code, notes, and snippets.

@jaehue
Last active October 15, 2023 21:08
Show Gist options
  • Select an option

  • Save jaehue/5d1aaf76d082f98e8dc0 to your computer and use it in GitHub Desktop.

Select an option

Save jaehue/5d1aaf76d082f98e8dc0 to your computer and use it in GitHub Desktop.
Built-in map doesn't support concurrent. This is concurrent map using channel, without mutex.
package main
import "fmt"
type sharedMap struct {
m map[string]interface{}
c chan command
}
type command struct {
action int
key string
value interface{}
result chan<- interface{}
}
const (
set = iota
get
remove
count
)
func (sm sharedMap) Set(k string, v interface{}) {
sm.c <- command{action: set, key: k, value: v}
}
func (sm sharedMap) Get(k string) (interface{}, bool) {
callback := make(chan interface{})
sm.c <- command{action: get, key: k, result: callback}
result := (<-callback).([2]interface{})
return result[0], result[1].(bool)
}
func (sm sharedMap) Remove(k string) {
sm.c <- command{action: remove, key: k}
}
func (sm sharedMap) Count() int {
callback := make(chan interface{})
sm.c <- command{action: count, result: callback}
return (<-callback).(int)
}
func (sm sharedMap) run() {
for cmd := range sm.c {
switch cmd.action {
case set:
sm.m[cmd.key] = cmd.value
case get:
v, ok := sm.m[cmd.key]
cmd.result <- [2]interface{}{v, ok}
case remove:
delete(sm.m, cmd.key)
case count:
cmd.result <- len(sm.m)
}
}
}
func NewMap() sharedMap {
sm := sharedMap{
m: make(map[string]interface{}),
c: make(chan command),
}
go sm.run()
return sm
}
func main() {
m := NewMap()
m.Set("one", 1)
fmt.Println(m.Get("one"))
m.Set("one", "I")
fmt.Println(m.Get("one"))
m.Set("two", 2)
fmt.Println(m.Count())
m.Remove("one")
fmt.Println(m.Count())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment