github.com/chain5j/chain5j-pkg@v1.0.7/collection/maps/linked_hashmap/linked_hashmap.go (about)

     1  // Package linkedHashMap
     2  //
     3  // @author: xwc1125
     4  package linkedHashMap
     5  
     6  import (
     7  	"container/list"
     8  	"sync"
     9  
    10  	"github.com/chain5j/logger"
    11  )
    12  
    13  type Node struct {
    14  	node *list.Element
    15  	val  interface{}
    16  }
    17  
    18  type LinkedHashMap struct {
    19  	linklistLock *sync.RWMutex
    20  	linklist     *list.List
    21  	hashmap      *sync.Map
    22  }
    23  
    24  func NewLinkedHashMap() *LinkedHashMap {
    25  	return &LinkedHashMap{
    26  		linklist:     list.New(),
    27  		linklistLock: new(sync.RWMutex),
    28  		hashmap:      new(sync.Map),
    29  	}
    30  }
    31  
    32  func (m *LinkedHashMap) Lock() {
    33  	m.linklistLock.Lock()
    34  }
    35  
    36  func (m *LinkedHashMap) Unlock() {
    37  	m.linklistLock.Unlock()
    38  }
    39  
    40  func (m *LinkedHashMap) RLock() {
    41  	m.linklistLock.RLock()
    42  }
    43  
    44  func (m *LinkedHashMap) RUnlock() {
    45  	m.linklistLock.RUnlock()
    46  }
    47  
    48  // Add 添加
    49  func (m *LinkedHashMap) Add(key interface{}, val interface{}) bool {
    50  	_, isExists := m.hashmap.Load(key)
    51  	if isExists {
    52  		return false
    53  	}
    54  
    55  	m.Lock()
    56  	linkListNode := m.linklist.PushBack(key)
    57  	m.Unlock()
    58  	m.hashmap.Store(key, &Node{
    59  		node: linkListNode,
    60  		val:  val,
    61  	})
    62  
    63  	return true
    64  }
    65  func (m *LinkedHashMap) AddFront(key interface{}, val interface{}) bool {
    66  	_, isExists := m.hashmap.Load(key)
    67  	if isExists {
    68  		return false
    69  	}
    70  
    71  	m.Lock()
    72  	linkListNode := m.linklist.PushFront(key)
    73  	m.Unlock()
    74  	m.hashmap.Store(key, &Node{
    75  		node: linkListNode,
    76  		val:  val,
    77  	})
    78  
    79  	return true
    80  }
    81  
    82  // Get 获取数据
    83  func (m *LinkedHashMap) Get(key interface{}) (interface{}, bool) {
    84  	node, isExists := m.hashmap.Load(key)
    85  	if !isExists {
    86  		return nil, false
    87  	}
    88  
    89  	return &node.(*Node).val, true
    90  }
    91  
    92  // Exist 判断是否存在
    93  func (m *LinkedHashMap) Exist(key interface{}) bool {
    94  	_, isExists := m.hashmap.Load(key)
    95  	return isExists
    96  }
    97  
    98  // Remove 删除
    99  func (m *LinkedHashMap) Remove(key interface{}) {
   100  	node, isExists := m.hashmap.Load(key)
   101  	if !isExists {
   102  		return
   103  	}
   104  
   105  	m.linklistLock.Lock()
   106  	m.hashmap.Delete(key)
   107  	m.linklistLock.Unlock()
   108  	m.linklist.Remove(node.(*Node).node)
   109  	return
   110  }
   111  
   112  // Len 获取len
   113  func (m *LinkedHashMap) Len() int {
   114  	return m.linklist.Len()
   115  }
   116  
   117  // =========批量处理=========
   118  
   119  // BatchAdd 批量添加
   120  func (m *LinkedHashMap) BatchAdd(kvs ...KV) {
   121  	if kvs == nil || len(kvs) == 0 {
   122  		return
   123  	}
   124  	var (
   125  		noExistKVs = make([]KV, 0)
   126  	)
   127  
   128  	for _, kv := range kvs {
   129  		_, isExists := m.hashmap.Load(kv.Key)
   130  		if !isExists {
   131  			noExistKVs = append(noExistKVs, kv)
   132  		} else {
   133  			logger.Warn("hashmap exist key", "key", kv.Key)
   134  		}
   135  	}
   136  	if len(noExistKVs) == 0 {
   137  		return
   138  	}
   139  
   140  	m.linklistLock.Lock()
   141  	defer m.linklistLock.Unlock()
   142  	for _, kv := range noExistKVs {
   143  		linkListNode := m.linklist.PushBack(kv.Key)
   144  		m.hashmap.Store(kv.Key, &Node{
   145  			node: linkListNode,
   146  			val:  kv.Val,
   147  		})
   148  	}
   149  	return
   150  }
   151  
   152  // GetLinkList 获取linklist
   153  func (m *LinkedHashMap) GetLinkList() *list.List {
   154  	return m.linklist
   155  }