easymap/segment.go

288 lines
5.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package easymap ...
//
// Description : 分段存储的map并发行更好,分段数量为 1 将退化成普通的
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-02-23 10:47 下午
package easymap
import (
"encoding/json"
"errors"
"fmt"
"git.zhangdeman.cn/zhangdeman/util"
"git.zhangdeman.cn/zhangdeman/serialize"
)
// NewSegment 获取分段map实例
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:05 下午 2021/2/24
func NewSegment(segmentCnt int) (EasyMap, error) {
if segmentCnt <= 0 {
return nil, segmentError()
}
em := &segment{
common: &common{},
segment: segmentCnt,
}
em.dataTable = make([]map[interface{}]interface{}, segmentCnt)
for i := 0; i < segmentCnt; i++ {
em.dataTable[i] = make(map[interface{}]interface{})
}
em.common.initLock()
return em, nil
}
type segment struct {
common *common
dataTable []map[interface{}]interface{}
segment int
}
func (s *segment) Get(key interface{}) (interface{}, bool) {
segmentIndex := util.Hash.GetHashIDMod(key, s.segment)
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 {
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) {
var (
val uint
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetUint8(key interface{}) (uint8, error) {
var (
val uint8
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetUint16(key interface{}) (uint16, error) {
var (
val uint16
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetUint32(key interface{}) (uint32, error) {
var (
val uint32
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetUint64(key interface{}) (uint64, error) {
var (
val uint64
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetInt(key interface{}) (int, error) {
var (
val int
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetInt8(key interface{}) (int8, error) {
var (
val int8
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetInt16(key interface{}) (int16, error) {
var (
val int16
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetInt32(key interface{}) (int32, error) {
var (
val int32
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetInt64(key interface{}) (int64, error) {
var (
val int64
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetFloat32(key interface{}) (float32, error) {
var (
val float32
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetFloat64(key interface{}) (float64, error) {
var (
val float64
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetBool(key interface{}) (bool, error) {
var (
val bool
err error
)
err = s.GetWithReceiver(key, &val)
return val, err
}
func (s *segment) GetString(key interface{}) (string, error) {
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][key] = value
}
func (s *segment) Del(key interface{}) {
segmentIndex := util.Hash.GetHashIDMod(key, s.segment)
s.common.Lock()
defer s.common.Unlock()
delete(s.dataTable[segmentIndex], key)
}
func (s *segment) Exist(key interface{}) bool {
_, 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] {
result[k] = v
}
}
return result
}
// GetAllForMapKeyString ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 9:48 下午 2021/9/15
func (s *segment) GetAllForMapKeyString() map[string]interface{} {
fullData := s.GetAll()
finalData := make(map[string]interface{})
for k, v := range fullData {
finalData[fmt.Sprintf("%v", k)] = v
}
return finalData
}
// Iterator ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:32 2023/3/7
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] {
if !handleFunc(k, v) {
isBreak = true
break
}
}
if isBreak {
break
}
}
}
// ToStruct ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:42 2023/8/10
func (s *segment) ToStruct(receiver interface{}) error {
if nil == receiver {
return errors.New("receiver is nil")
}
mapData := s.GetAll()
byteData, err := json.Marshal(mapData)
if nil != err {
return err
}
return serialize.JSON.UnmarshalWithNumber(byteData, receiver)
}
// ToString 转字符串
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 20:44 2023/8/15
func (s *segment) ToString() string {
mapData := s.GetAllForMapKeyString()
return serialize.JSON.MarshalForString(mapData)
}