【golang】go-ConcurrentMap实现

用go实现ConcurrentMap

// 泛化的Map的接口类型
type GenericMap interface {
       // 获取给定键值对应的元素值。若没有对应元素值则返回nil。
       Get(key interface{}) interface{}
       // 添加键值对,并返回与给定键值对应的旧的元素值。若没有旧元素值则返回(nil, true)。
       Put(key interface{}, elem interface{}) (interface{}, bool)
       // 删除与给定键值对应的键值对,并返回旧的元素值。若没有旧元素值则返回nil。
       Remove(key interface{}) interface{}
       // 清除所有的键值对。
       Clear()
       // 获取键值对的数量。
       Len() int
       // 判断是否包含给定的键值。
       Contains(key interface{}) bool
       // 获取已排序的键值所组成的切片值。
       Keys() []interface{}
       // 获取已排序的元素值所组成的切片值。
       Elems() []interface{}
       // 获取已包含的键值对所组成的字典值。
       ToMap() map[interface{}]interface{}
       // 获取键的类型。
       KeyType() reflect.Type
       // 获取元素的类型。
       ElemType() reflect.Type
}
type ConcurrentMap interface {
       GenericMap
       String() string
}

type myConcurrentMap struct {
       m        map[interface{}]interface{}
       keyType  reflect.Type
       elemType reflect.Type
       rwmutex  sync.RWMutex
}

func (cmap *myConcurrentMap) Get(key interface{}) interface{} {
       cmap.rwmutex.RLock()
       defer cmap.rwmutex.RUnlock()
       return cmap.m[key]
}

func (cmap *myConcurrentMap) isAcceptablePair(k, e interface{}) bool {
       if k == nil || reflect.TypeOf(k) != cmap.keyType {
              return false
       }
       if e == nil || reflect.TypeOf(e) != cmap.elemType {
              return false
       }
       return true
}

func (cmap *myConcurrentMap) Put(key interface{}, elem interface{}) (interface{}, bool) {
       if !cmap.isAcceptablePair(key, elem) {
              return nil, false
       }
       cmap.rwmutex.Lock()
       defer cmap.rwmutex.Unlock()
       oldElem := cmap.m[key]
       cmap.m[key] = elem
       return oldElem, true
}

func (cmap *myConcurrentMap) Remove(key interface{}) interface{} {
       cmap.rwmutex.Lock()
       defer cmap.rwmutex.Unlock()
       oldElem := cmap.m[key]
       delete(cmap.m, key)
       return oldElem
}

func (cmap *myConcurrentMap) Clear() {
       cmap.rwmutex.Lock()
       defer cmap.rwmutex.Unlock()
       cmap.m = make(map[interface{}]interface{})
}

func (cmap *myConcurrentMap) Len() int {
       cmap.rwmutex.RLock()
       defer cmap.rwmutex.RUnlock()
       return len(cmap.m)
}

func (cmap *myConcurrentMap) Contains(key interface{}) bool {
       cmap.rwmutex.RLock()
       defer cmap.rwmutex.RUnlock()
       _, ok := cmap.m[key]
       return ok
}

func (cmap *myConcurrentMap) Keys() []interface{} {
       cmap.rwmutex.RLock()
       defer cmap.rwmutex.RUnlock()
       initialLen := len(cmap.m)
       keys := make([]interface{}, initialLen)
       index := 0
       for k, _ := range cmap.m {
              keys[index] = k
              index++
       }
       return keys
}

func (cmap *myConcurrentMap) Elems() []interface{} {
       cmap.rwmutex.RLock()
       defer cmap.rwmutex.RUnlock()
       initialLen := len(cmap.m)
       elems := make([]interface{}, initialLen)
       index := 0
       for _, v := range cmap.m {
              elems[index] = v
              index++
       }
       return elems
}

func (cmap *myConcurrentMap) ToMap() map[interface{}]interface{} {
       cmap.rwmutex.RLock()
       defer cmap.rwmutex.RUnlock()
       replica := make(map[interface{}]interface{})
       for k, v := range cmap.m {
              replica[k] = v
       }
       return replica
}

func (cmap *myConcurrentMap) KeyType() reflect.Type {
       return cmap.keyType
}

func (cmap *myConcurrentMap) ElemType() reflect.Type {
       return cmap.elemType
}

func (cmap *myConcurrentMap) String() string {
       var buf bytes.Buffer
       buf.WriteString("ConcurrentMap<")
       buf.WriteString(cmap.keyType.Kind().String())
       buf.WriteString(",")
       buf.WriteString(cmap.elemType.Kind().String())
       buf.WriteString(">{")
       first := true
       for k, v := range cmap.m {
              if first {
                     first = false
              } else {
                     buf.WriteString(" ")
              }
              buf.WriteString(fmt.Sprintf("%v", k))
              buf.WriteString(":")
              buf.WriteString(fmt.Sprintf("%v", v))
       }
       buf.WriteString("}")
       return buf.String()
}
func NewConcurrentMap(keyType, elemType reflect.Type) ConcurrentMap {
       return &myConcurrentMap{
              keyType:  keyType,
              elemType: elemType,
              m:        make(map[interface{}]interface{})}
}

func main() {
       //var cmap ConcurrentMap = &myConcurrentMap{
       //     m:        make(map[interface{}]interface{}),
       //     keyType:  reflect.TypeOf(int(2)),
       //     elemType: reflect.TypeOf(string(20))}
       cmap := NewConcurrentMap(reflect.TypeOf(int(2)), reflect.TypeOf(string(200)))
       fmt.Println(cmap)
       cmap.Put(112, "12")
       fmt.Println(cmap.String())
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值