123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- //@File multimap.go
- //@Time 2022/05/12
- //@Author #Suyghur,
- package treemap
- import (
- "ylink/comm/ds/rbtree"
- "ylink/comm/utils/comparator"
- "ylink/comm/utils/sync"
- "ylink/comm/utils/visitor"
- )
- // MultiMap uses RbTress for internal data structure, and keys can bee repeated.
- type MultiMap struct {
- tree *rbtree.RbTree
- keyCmp comparator.Comparator
- locker sync.Locker
- }
- //NewMultiMap creates a new MultiMap
- func NewMultiMap(opts ...Option) *MultiMap {
- option := Options{
- keyCmp: defaultKeyComparator,
- locker: defaultLocker,
- }
- for _, opt := range opts {
- opt(&option)
- }
- return &MultiMap{tree: rbtree.New(rbtree.WithKeyComparator(option.keyCmp)),
- keyCmp: option.keyCmp,
- locker: option.locker,
- }
- }
- //Insert inserts a key-value to the MultiMap
- func (mm *MultiMap) Insert(key, value interface{}) {
- mm.locker.Lock()
- defer mm.locker.Unlock()
- mm.tree.Insert(key, value)
- }
- //Get returns the first node's value by the passed key if the key is in the MultiMap, otherwise returns nil
- func (mm *MultiMap) Get(key interface{}) interface{} {
- mm.locker.RLock()
- defer mm.locker.RUnlock()
- node := mm.tree.FindNode(key)
- if node != nil {
- return node.Value()
- }
- return nil
- }
- //Erase erases the key in the MultiMap
- func (mm *MultiMap) Erase(key interface{}) {
- mm.locker.Lock()
- defer mm.locker.Unlock()
- for {
- node := mm.tree.FindNode(key)
- if node == nil {
- break
- }
- mm.tree.Delete(node)
- }
- }
- //Find finds the node by the passed key in the MultiMap and returns its iterator
- func (mm *MultiMap) Find(key interface{}) *MapIterator {
- mm.locker.RLock()
- defer mm.locker.RUnlock()
- node := mm.tree.FindNode(key)
- return &MapIterator{node: node}
- }
- //LowerBound find the first node that its key is equal or greater than the passed key in the MultiMap, and returns its iterator
- func (mm *MultiMap) LowerBound(key interface{}) *MapIterator {
- mm.locker.RLock()
- defer mm.locker.RUnlock()
- node := mm.tree.FindLowerBoundNode(key)
- return &MapIterator{node: node}
- }
- //UpperBound find the first node that its key is greater than the passed key in the MultiMap, and returns its iterator
- func (mm *MultiMap) UpperBound(key interface{}) *MapIterator {
- mm.locker.RLock()
- defer mm.locker.RUnlock()
- node := mm.tree.FindUpperBoundNode(key)
- return &MapIterator{node: node}
- }
- //Begin returns the first node's iterator
- func (mm *MultiMap) Begin() *MapIterator {
- mm.locker.RLock()
- defer mm.locker.RUnlock()
- return &MapIterator{node: mm.tree.First()}
- }
- //First returns the first node's iterator
- func (mm *MultiMap) First() *MapIterator {
- mm.locker.RLock()
- defer mm.locker.RUnlock()
- return &MapIterator{node: mm.tree.First()}
- }
- //Last returns the last node's iterator
- func (mm *MultiMap) Last() *MapIterator {
- mm.locker.RLock()
- defer mm.locker.RUnlock()
- return &MapIterator{node: mm.tree.Last()}
- }
- //Clear clears the MultiMap
- func (mm *MultiMap) Clear() {
- mm.locker.Lock()
- defer mm.locker.Unlock()
- mm.tree.Clear()
- }
- // Contains returns true if the passed value is in the MultiMap. otherwise returns false.
- func (mm *MultiMap) Contains(value interface{}) bool {
- mm.locker.RLock()
- defer mm.locker.RUnlock()
- if mm.tree.Find(value) != nil {
- return true
- }
- return false
- }
- // Size returns the amount of elements in the MultiMap
- func (mm *MultiMap) Size() int {
- mm.locker.RLock()
- defer mm.locker.RUnlock()
- return mm.tree.Size()
- }
- // Traversal traversals elements in the MultiMap, it will not stop until to the end of the MultiMap or the visitor returns false
- func (mm *MultiMap) Traversal(visitor visitor.KvVisitor) {
- mm.locker.RLock()
- defer mm.locker.RUnlock()
- mm.tree.Traversal(visitor)
- }
|