github.com/godaddy-x/freego@v1.0.156/utils/concurrent/map.go (about)

     1  package concurrent
     2  
     3  import (
     4  	"errors"
     5  	"sync"
     6  )
     7  
     8  type Map struct {
     9  	lock sync.RWMutex
    10  	data map[string]interface{}
    11  }
    12  
    13  func NewMap() *Map {
    14  	return &Map{data: map[string]interface{}{}}
    15  }
    16  
    17  func (self *Map) Get(key string, callfun func(key string) (interface{}, error)) (interface{}, error) {
    18  	if len(key) == 0 {
    19  		return nil, errors.New("get key is nil")
    20  	}
    21  	if callfun == nil {
    22  		return nil, errors.New("get callfun is nil")
    23  	}
    24  	var b bool
    25  	var v interface{}
    26  	var err error
    27  	//self.lock.RLock()
    28  	if v, b = self.data[key]; !b {
    29  		//self.lock.RUnlock()
    30  		self.lock.Lock()
    31  		if v, b = self.data[key]; !b {
    32  			v, err = callfun(key)
    33  			if v != nil && err == nil {
    34  				self.data[key] = v
    35  			}
    36  		}
    37  		self.lock.Unlock()
    38  	} else {
    39  		//self.lock.RUnlock()
    40  	}
    41  	return v, err
    42  }
    43  
    44  func (self *Map) Del(key string, callfun func(key string) (interface{}, error)) error {
    45  	var b bool
    46  	var err error
    47  	self.lock.RLock()
    48  	if _, b = self.data[key]; b {
    49  		self.lock.RUnlock()
    50  		self.lock.Lock()
    51  		if _, b = self.data[key]; b {
    52  			if callfun != nil {
    53  				_, err = callfun(key)
    54  			}
    55  			if err == nil {
    56  				delete(self.data, key)
    57  			}
    58  		}
    59  		self.lock.Unlock()
    60  	} else {
    61  		self.lock.RUnlock()
    62  	}
    63  	return err
    64  }
    65  
    66  func (self *Map) Set(key string, callfun func(key string) (interface{}, error)) (interface{}, error) {
    67  	if len(key) == 0 {
    68  		return nil, errors.New("set key is nil")
    69  	}
    70  	if callfun == nil {
    71  		return nil, errors.New("set callfun is nil")
    72  	}
    73  	self.lock.Lock()
    74  	v, err := callfun(key)
    75  	if v != nil && err == nil {
    76  		self.data[key] = v
    77  	}
    78  	self.lock.Unlock()
    79  	return v, err
    80  }