diff --git a/abstruct.go b/abstruct.go index 662f035..0a36f42 100644 --- a/abstruct.go +++ b/abstruct.go @@ -13,7 +13,7 @@ package easymap // // Date : 9:56 下午 2021/2/23 type EasyMap interface { - Get(key interface{}) (interface{}, error) + Get(key interface{}) (interface{}, bool) GetWithReceiver(key interface{}, dest interface{}) error GetUint(key interface{}) (uint, error) GetUint8(key interface{}) (uint8, error) diff --git a/common.go b/common.go index 7204609..33f563e 100644 --- a/common.go +++ b/common.go @@ -7,36 +7,7 @@ // Date : 2023-12-14 15:51 package easymap -import "git.zhangdeman.cn/zhangdeman/util" - -// GetShardAndKeyFunc 获取数据所处分片以及key -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 15:55 2023/12/14 -type GetShardAndKeyFunc func(interface{}) (int, interface{}) - -// DefaultGetShardAndKeyFunc 默认实现 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 15:57 2023/12/14 -func DefaultGetShardAndKeyFunc(key interface{}) GetShardAndKeyFunc { - return func(key interface{}) (int, interface{}) { - return -1, key - } -} - -// GetShardAndKeyFuncWithShardCount 获取数据分片和key -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 15:59 2023/12/14 -func GetShardAndKeyFuncWithShardCount(shardCnt int, key interface{}) GetShardAndKeyFunc { - return func(key interface{}) (int, interface{}) { - return util.Hash.GetHashIDMod(key, shardCnt), key - } -} +import "sync" // common 公共基础结构 // @@ -44,6 +15,53 @@ func GetShardAndKeyFuncWithShardCount(shardCnt int, key interface{}) GetShardAnd // // Date : 15:52 2023/12/14 type common struct { - data map[interface{}]interface{} // 输入数据 - GetShardAndKeyFunc GetShardAndKeyFunc // 获取分片以及key的函数 + lock *sync.RWMutex // 数据锁 +} + +// initLock ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 21:25 2023/12/24 +func (c *common) initLock() { + c.lock = &sync.RWMutex{} +} + +// Lock ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 21:27 2023/12/24 +func (c *common) Lock() { + if nil == c.lock { + + } + c.lock.Lock() +} + +// Unlock ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 21:27 2023/12/24 +func (c *common) Unlock() { + c.lock.Unlock() +} + +// RLock ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 21:43 2023/12/24 +func (c *common) RLock() { + c.lock.RLock() +} + +// RUnlock ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 21:43 2023/12/24 +func (c *common) RUnlock() { + c.lock.RUnlock() } diff --git a/go.mod b/go.mod index d6f7a5e..895e780 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,8 @@ toolchain go1.21.5 require git.zhangdeman.cn/zhangdeman/util v0.0.0-20231014142840-445c6407db92 require ( + git.zhangdeman.cn/zhangdeman/consts v0.0.0-20230815040024-2b12dd51d19b // indirect + git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20231224125439-01f39b6ea08d // indirect github.com/BurntSushi/toml v1.3.2 // indirect github.com/Jeffail/gabs v1.4.0 // indirect github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect diff --git a/go.sum b/go.sum index ff8ef8f..d93a4dc 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,7 @@ +git.zhangdeman.cn/zhangdeman/consts v0.0.0-20230815040024-2b12dd51d19b h1:C7KftnLh7dOqzNRs5dn/9yqMDvuqMn5RCglvV6bY758= +git.zhangdeman.cn/zhangdeman/consts v0.0.0-20230815040024-2b12dd51d19b/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= +git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20231224125439-01f39b6ea08d h1:TV0BCQQewBEtLsv3i9gXkxLFd5A5bWBTiNd3D/I5o4Q= +git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20231224125439-01f39b6ea08d/go.mod h1:w7kG4zyTJ1uPFaTWhze+OQuaUBINT2XnDxpyiM6ctc0= git.zhangdeman.cn/zhangdeman/util v0.0.0-20230810063945-842592611562 h1:wo0r4mexqkPzQ1SZOw5z8A7FJ3ne1G6A/qWR3iaqlhw= git.zhangdeman.cn/zhangdeman/util v0.0.0-20230810063945-842592611562/go.mod h1:trYFOShINaQBvinQrH4A0G2kfL22Y2lygEcAiGDt/sc= git.zhangdeman.cn/zhangdeman/util v0.0.0-20230811070456-d6a489d5860b h1:vnmxYrNdX6f5sEVjjkM1fIR+i32kHJ4g9DJqug9KKek= diff --git a/segment.go b/segment.go index c418791..8485b61 100644 --- a/segment.go +++ b/segment.go @@ -8,12 +8,12 @@ package easymap import ( - "bytes" "encoding/json" "errors" "fmt" - "git.zhangdeman.cn/zhangdeman/util" + + "git.zhangdeman.cn/zhangdeman/serialize" ) // NewSegment 获取分段map实例 @@ -21,124 +21,199 @@ import ( // Author : go_developer@163.com<白茶清欢> // // Date : 11:05 下午 2021/2/24 -func NewSegment(segmentCnt int, withLock bool) (EasyMap, error) { +func NewSegment(segmentCnt int) (EasyMap, error) { if segmentCnt <= 0 { return nil, segmentError() } em := &segment{ + common: &common{}, segment: segmentCnt, } - em.dataTable = make([]EasyMap, segmentCnt) + em.dataTable = make([]map[interface{}]interface{}, segmentCnt) for i := 0; i < segmentCnt; i++ { - em.dataTable[i] = NewNormal(withLock) + em.dataTable[i] = make(map[interface{}]interface{}) } + em.common.initLock() return em, nil } type segment struct { - dataTable []EasyMap + common *common + dataTable []map[interface{}]interface{} segment int } -func (s *segment) Get(key interface{}) (interface{}, error) { +func (s *segment) Get(key interface{}) (interface{}, bool) { segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].Get(key) + s.common.RLock() + defer s.common.RUnlock() + data, exist := s.dataTable[segmentIndex][key] + return data, exist } func (s *segment) GetWithReceiver(key interface{}, dest interface{}) error { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetWithReceiver(key, dest) + if nil == dest { + return errors.New("dest is nil") + } + val, exist := s.Get(key) + if !exist { + return fmt.Errorf("key %v not exist", key) + } + if nil == val { + return errors.New("value is nil") + } + return util.ConvertAssign(dest, val) } func (s *segment) GetUint(key interface{}) (uint, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetUint(key) + var ( + val uint + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetUint8(key interface{}) (uint8, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetUint8(key) + var ( + val uint8 + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetUint16(key interface{}) (uint16, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetUint16(key) + var ( + val uint16 + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetUint32(key interface{}) (uint32, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetUint32(key) + var ( + val uint32 + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetUint64(key interface{}) (uint64, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetUint64(key) + var ( + val uint64 + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetInt(key interface{}) (int, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetInt(key) + var ( + val int + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetInt8(key interface{}) (int8, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetInt8(key) + var ( + val int8 + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetInt16(key interface{}) (int16, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetInt16(key) + var ( + val int16 + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetInt32(key interface{}) (int32, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetInt32(key) + var ( + val int32 + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetInt64(key interface{}) (int64, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetInt64(key) + var ( + val int64 + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetFloat32(key interface{}) (float32, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetFloat32(key) + var ( + val float32 + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetFloat64(key interface{}) (float64, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetFloat64(key) + var ( + val float64 + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetBool(key interface{}) (bool, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetBool(key) + var ( + val bool + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) GetString(key interface{}) (string, error) { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].GetString(key) + var ( + val string + err error + ) + err = s.GetWithReceiver(key, &val) + return val, err } func (s *segment) Set(key interface{}, value interface{}) { segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - s.dataTable[segmentIndex].Set(key, value) + s.dataTable[segmentIndex][key] = value } func (s *segment) Del(key interface{}) { segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - s.dataTable[segmentIndex].Del(key) + s.common.Lock() + defer s.common.Unlock() + delete(s.dataTable[segmentIndex], key) } func (s *segment) Exist(key interface{}) bool { - segmentIndex := util.Hash.GetHashIDMod(key, s.segment) - return s.dataTable[segmentIndex].Exist(key) + _, exist := s.Get(key) + return exist } func (s *segment) GetAll() map[interface{}]interface{} { result := make(map[interface{}]interface{}) + s.common.RLock() + defer s.common.RUnlock() for i := 0; i < s.segment; i++ { - for k, v := range s.dataTable[i].GetAll() { + for k, v := range s.dataTable[i] { result[k] = v } } @@ -168,9 +243,11 @@ func (s *segment) Iterator(handleFunc IteratorFunc) { if nil == handleFunc { return } + s.common.Lock() + s.common.Unlock() isBreak := false for i := 0; i < s.segment; i++ { - for k, v := range s.dataTable[i].GetAll() { + for k, v := range s.dataTable[i] { if !handleFunc(k, v) { isBreak = true break @@ -196,9 +273,7 @@ func (s *segment) ToStruct(receiver interface{}) error { if nil != err { return err } - decoder := json.NewDecoder(bytes.NewReader(byteData)) - decoder.UseNumber() - return decoder.Decode(receiver) + return serialize.JSON.UnmarshalWithNumber(byteData, receiver) } // ToString 转字符串 @@ -208,6 +283,5 @@ func (s *segment) ToStruct(receiver interface{}) error { // Date : 20:44 2023/8/15 func (s *segment) ToString() string { mapData := s.GetAllForMapKeyString() - byteData, _ := json.Marshal(mapData) - return string(byteData) + return serialize.JSON.MarshalForString(mapData) }