github.com/djordje200179/extendedlibrary/datastructures@v1.7.1-0.20240227175559-d09520a92dd4/maps/linkmap/wrapper.go (about) 1 package linkmap 2 3 import ( 4 "github.com/djordje200179/extendedlibrary/datastructures/iter" 5 "github.com/djordje200179/extendedlibrary/datastructures/maps" 6 "github.com/djordje200179/extendedlibrary/datastructures/maps/hashmap" 7 "github.com/djordje200179/extendedlibrary/misc" 8 ) 9 10 // Order represents the order of the nodes in the map. 11 type Order bool 12 13 const ( 14 FIFO Order = false // FIFO represents the first-in-first-out order. 15 LRU = true // LRU represents the least-recently-used order. 16 ) 17 18 // Wrapper is a map that keeps track of the order of the nodes. 19 type Wrapper[K, V any] struct { 20 m maps.Map[K, *Node[K, V]] 21 22 head, tail *Node[K, V] 23 order Order 24 25 capacity int 26 } 27 28 // From returns a new Wrapper that wraps the given map. 29 func From[K, V any](m maps.Map[K, *Node[K, V]], capacity int, order Order) *Wrapper[K, V] { 30 wrapper := &Wrapper[K, V]{ 31 m: m, 32 33 order: order, 34 capacity: capacity, 35 } 36 37 for it := m.Iterator(); it.Valid(); it.Move() { 38 node := it.Get().Second 39 if wrapper.head == nil { 40 wrapper.head = node 41 } else { 42 wrapper.tail = node 43 } 44 } 45 46 return wrapper 47 } 48 49 // NewHashmap returns a new Wrapper around a empty hashmap. 50 func NewHashmap[K comparable, V any](capacity int, order Order) *Wrapper[K, V] { 51 m := hashmap.NewWithCapacity[K, *Node[K, V]](capacity) 52 wrapper := &Wrapper[K, V]{ 53 m: m, 54 55 order: order, 56 capacity: capacity, 57 } 58 59 return wrapper 60 } 61 62 func (w *Wrapper[K, V]) moveToFront(node *Node[K, V]) { 63 if node.prev != nil { 64 node.prev.next = node.next 65 } else { 66 w.head = node.next 67 } 68 69 if node.next != nil { 70 node.next.prev = node.prev 71 } else { 72 w.tail = node.prev 73 } 74 75 if w.head == nil { 76 w.head = node 77 } else { 78 w.tail.next = node 79 node.prev = w.tail 80 } 81 w.tail = node 82 } 83 84 // Size returns the number of entries in the map. 85 func (w *Wrapper[K, V]) Size() int { 86 return w.m.Size() 87 } 88 89 // Contains returns true if the map contains the given key. 90 func (w *Wrapper[K, V]) Contains(key K) bool { 91 return w.m.Contains(key) 92 } 93 94 // TryGet returns the value associated with the given key. 95 // If the key is not in the map, the zero value and false is returned. 96 // If the order is LRU, the entry is moved to the front. 97 func (w *Wrapper[K, V]) TryGet(key K) (V, bool) { 98 node, ok := w.m.TryGet(key) 99 if !ok { 100 var zero V 101 return zero, false 102 } 103 104 if w.order == LRU { 105 w.moveToFront(node) 106 } 107 108 return node.Value, true 109 } 110 111 // Get returns the value associated with the given key. 112 // Panics if the key is not in the map. 113 // If the order is LRU, the entry is moved to the front. 114 func (w *Wrapper[K, V]) Get(key K) V { 115 node := w.m.Get(key) 116 117 if w.order == LRU { 118 w.moveToFront(node) 119 } 120 121 return node.Value 122 } 123 124 // GetRef returns a reference to the value associated with the given key. 125 // Panics if the key is not in the map. 126 // If the order is LRU, the entry is moved to the front. 127 func (w *Wrapper[K, V]) GetRef(key K) *V { 128 node := w.m.Get(key) 129 130 if w.order == LRU { 131 w.moveToFront(node) 132 } 133 134 return &node.Value 135 } 136 137 // Set sets the value associated with the given key. 138 // Entry is moved to the front of the map. 139 // If the map is full, the last entry is removed. 140 func (w *Wrapper[K, V]) Set(key K, value V) { 141 node, ok := w.m.TryGet(key) 142 if ok { 143 node.Value = value 144 145 if w.order == LRU { 146 w.moveToFront(node) 147 } 148 149 return 150 } 151 152 if w.capacity > 0 && w.m.Size() == w.capacity { 153 firstNode := w.head 154 155 w.head = firstNode.next 156 if w.head != nil { 157 w.head.prev = nil 158 } else { 159 w.tail = nil 160 } 161 162 w.m.Remove(firstNode.key) 163 } 164 165 node = &Node[K, V]{key: key, Value: value} 166 167 if w.head == nil { 168 w.head = node 169 } else { 170 w.tail.next = node 171 node.prev = w.tail 172 } 173 w.tail = node 174 175 w.m.Set(key, node) 176 } 177 178 // Remove removes the entry with the given key. 179 // If the key is not in the map, nothing happens. 180 func (w *Wrapper[K, V]) Remove(key K) { 181 node, ok := w.m.TryGet(key) 182 if !ok { 183 return 184 } 185 186 if node.prev != nil { 187 node.prev.next = node.next 188 } else { 189 w.head = node.next 190 } 191 192 if node.next != nil { 193 node.next.prev = node.prev 194 } else { 195 w.tail = node.prev 196 } 197 198 w.m.Remove(key) 199 } 200 201 // Clear removes all entries from the map. 202 func (w *Wrapper[K, V]) Clear() { 203 w.m.Clear() 204 205 w.head = nil 206 w.tail = nil 207 } 208 209 // Clone returns a copy of the wrapper and 210 // of the underlying map. 211 func (w *Wrapper[K, V]) Clone() maps.Map[K, V] { 212 clonedMap := w.m.Clone() 213 214 var clonedHead, clonedTail *Node[K, V] 215 for oldIt, newIt := w.m.Iterator(), clonedMap.MapIterator(); oldIt.Valid(); oldIt.Move() { 216 oldNode := oldIt.Get().Second 217 218 newNode := oldNode.Clone() 219 if clonedHead == nil { 220 clonedHead = newNode 221 } else { 222 clonedTail.next = newNode 223 newNode.prev = clonedTail 224 } 225 clonedTail = newNode 226 227 newIt.SetValue(newNode) 228 229 newIt.Move() 230 } 231 232 return &Wrapper[K, V]{ 233 m: clonedMap, 234 235 head: clonedHead, 236 tail: clonedTail, 237 capacity: w.capacity, 238 order: w.order, 239 } 240 } 241 242 // Iterator returns an iter.Iterator over the entries in the map. 243 func (w *Wrapper[K, V]) Iterator() iter.Iterator[misc.Pair[K, V]] { 244 return w.MapIterator() 245 } 246 247 // MapIterator returns a iterator over the entries in the map. 248 func (w *Wrapper[K, V]) MapIterator() maps.Iterator[K, V] { 249 return &Iterator[K, V]{wrapper: w, curr: w.head} 250 } 251 252 // Stream2 streams over the entries in the Map. 253 func (w *Wrapper[K, V]) Stream2(yield func(K, V) bool) { 254 for it := w.MapIterator(); it.Valid(); it.Move() { 255 if !yield(it.Key(), it.Value()) { 256 break 257 } 258 } 259 } 260 261 // RefsStream2 streams keys and references to values of the Map 262 func (w *Wrapper[K, V]) RefsStream2(yield func(K, *V) bool) { 263 for it := w.MapIterator(); it.Valid(); it.Move() { 264 if !yield(it.Key(), it.ValueRef()) { 265 break 266 } 267 } 268 }