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