github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/maps/treemap/treemap.go (about) 1 // Package treemap implements a map backed by red-black tree. 2 // 3 // Elements are ordered by key in the map. 4 // 5 // Structure is not thread safe. 6 // 7 // Reference: http://en.wikipedia.org/wiki/Associative_array 8 package treemap 9 10 import ( 11 "fmt" 12 "strings" 13 14 "github.com/songzhibin97/go-baseutils/base/bcomparator" 15 "github.com/songzhibin97/go-baseutils/structure/maps" 16 "github.com/songzhibin97/go-baseutils/structure/trees/redblacktree" 17 ) 18 19 // Assert Map implementation 20 var _ maps.Map[int, any] = (*Map[int, any])(nil) 21 22 // Map holds the elements in a red-black tree 23 type Map[K, V any] struct { 24 tree *redblacktree.Tree[K, V] 25 zeroK K 26 zeroV V 27 } 28 29 // NewWith instantiates a tree map with the custom comparator. 30 func NewWith[K, V any](comparator bcomparator.Comparator[K]) *Map[K, V] { 31 return &Map[K, V]{tree: redblacktree.NewWith[K, V](comparator)} 32 } 33 34 // NewWithIntComparator instantiates a tree map with the IntComparator, i.e. keys are of type int. 35 func NewWithIntComparator[V any]() *Map[int, V] { 36 return &Map[int, V]{tree: redblacktree.NewWithIntComparator[V]()} 37 } 38 39 // NewWithStringComparator instantiates a tree map with the StringComparator, i.e. keys are of type string. 40 func NewWithStringComparator[V any]() *Map[string, V] { 41 return &Map[string, V]{tree: redblacktree.NewWithStringComparator[V]()} 42 } 43 44 // Put inserts key-value pair into the map. 45 // Key should adhere to the comparator's type assertion, otherwise method panics. 46 func (m *Map[K, V]) Put(key K, value V) { 47 m.tree.Put(key, value) 48 } 49 50 // Get searches the element in the map by key and returns its value or nil if key is not found in tree. 51 // Second return parameter is true if key was found, otherwise false. 52 // Key should adhere to the comparator's type assertion, otherwise method panics. 53 func (m *Map[K, V]) Get(key K) (value V, found bool) { 54 return m.tree.Get(key) 55 } 56 57 // Remove removes the element from the map by key. 58 // Key should adhere to the comparator's type assertion, otherwise method panics. 59 func (m *Map[K, V]) Remove(key K) { 60 m.tree.Remove(key) 61 } 62 63 // Empty returns true if map does not contain any elements 64 func (m *Map[K, V]) Empty() bool { 65 return m.tree.Empty() 66 } 67 68 // Size returns number of elements in the map. 69 func (m *Map[K, V]) Size() int { 70 return m.tree.Size() 71 } 72 73 // Keys returns all keys in-order 74 func (m *Map[K, V]) Keys() []K { 75 return m.tree.Keys() 76 } 77 78 // Values returns all values in-order based on the key. 79 func (m *Map[K, V]) Values() []V { 80 return m.tree.Values() 81 } 82 83 // Clear removes all elements from the map. 84 func (m *Map[K, V]) Clear() { 85 m.tree.Clear() 86 } 87 88 // Min returns the minimum key and its value from the tree map. 89 // Returns nil, nil if map is empty. 90 func (m *Map[K, V]) Min() (key K, value V) { 91 if node := m.tree.Left(); node != nil { 92 return node.Key, node.Value 93 } 94 return m.zeroK, m.zeroV 95 } 96 97 // Max returns the maximum key and its value from the tree map. 98 // Returns nil, nil if map is empty. 99 func (m *Map[K, V]) Max() (key K, value V) { 100 if node := m.tree.Right(); node != nil { 101 return node.Key, node.Value 102 } 103 return m.zeroK, m.zeroV 104 } 105 106 // Floor finds the floor key-value pair for the input key. 107 // In case that no floor is found, then both returned values will be nil. 108 // It's generally enough to check the first value (key) for nil, which determines if floor was found. 109 // 110 // Floor key is defined as the largest key that is smaller than or equal to the given key. 111 // A floor key may not be found, either because the map is empty, or because 112 // all keys in the map are larger than the given key. 113 // 114 // Key should adhere to the comparator's type assertion, otherwise method panics. 115 func (m *Map[K, V]) Floor(key K) (foundkey K, foundvalue V) { 116 node, found := m.tree.Floor(key) 117 if found { 118 return node.Key, node.Value 119 } 120 return m.zeroK, m.zeroV 121 } 122 123 // Ceiling finds the ceiling key-value pair for the input key. 124 // In case that no ceiling is found, then both returned values will be nil. 125 // It's generally enough to check the first value (key) for nil, which determines if ceiling was found. 126 // 127 // Ceiling key is defined as the smallest key that is larger than or equal to the given key. 128 // A ceiling key may not be found, either because the map is empty, or because 129 // all keys in the map are smaller than the given key. 130 // 131 // Key should adhere to the comparator's type assertion, otherwise method panics. 132 func (m *Map[K, V]) Ceiling(key K) (foundkey K, foundvalue V) { 133 node, found := m.tree.Ceiling(key) 134 if found { 135 return node.Key, node.Value 136 } 137 return m.zeroK, m.zeroV 138 } 139 140 // String returns a string representation of container 141 func (m *Map[K, V]) String() string { 142 bf := strings.Builder{} 143 bf.WriteString("TreeMap\nmap[") 144 it := m.Iterator() 145 for it.Next() { 146 bf.WriteString(fmt.Sprintf("(%v:%v) ", it.Key(), it.Value())) 147 } 148 bf.WriteString("]") 149 return bf.String() 150 } 151 152 // UnmarshalJSON @implements json.Unmarshaler 153 func (m *Map[K, V]) UnmarshalJSON(bytes []byte) error { 154 return m.tree.UnmarshalJSON(bytes) 155 } 156 157 // MarshalJSON @implements json.Marshaler 158 func (m *Map[K, V]) MarshalJSON() ([]byte, error) { 159 return m.tree.MarshalJSON() 160 }