github.com/tursom/GoCollections@v0.3.10/collections/Map.go (about) 1 /* 2 * Copyright (c) 2022 tursom. All rights reserved. 3 * Use of this source code is governed by a GPL-3 4 * license that can be found in the LICENSE file. 5 */ 6 7 package collections 8 9 import ( 10 "fmt" 11 "strings" 12 13 "github.com/tursom/GoCollections/exceptions" 14 "github.com/tursom/GoCollections/lang" 15 ) 16 17 type ( 18 MapLooper[K lang.Object, V any] interface { 19 Loop(func(K, V) exceptions.Exception) exceptions.Exception 20 } 21 22 Map[K lang.Object, V any] interface { 23 MapLooper[K, V] 24 Get(k K) (V, bool, exceptions.Exception) 25 } 26 27 MutableMap[K lang.Object, V any] interface { 28 Map[K, V] 29 Put(k K, v V) (bool, exceptions.Exception) 30 Remove(k K) (V, bool, exceptions.Exception) 31 } 32 33 MapNodeFinder[K lang.Object, V any] interface { 34 findNode(k K, createIfNotExist bool) (node, prev MapNode[K, V]) 35 } 36 37 MapSlotFinder[K lang.Object, V any] interface { 38 FindSlot(k K) (root MapNode[K, V]) 39 } 40 41 MapNode[K lang.Object, V any] interface { 42 GetKey() K 43 GetValue() V 44 SetValue(value V) 45 CreateNext(key K) MapNode[K, V] 46 GetNext() MapNode[K, V] 47 RemoveNext() 48 } 49 50 SimpleMapNode[K lang.Object, V any] struct { 51 lang.BaseObject 52 key K 53 value V 54 next *SimpleMapNode[K, V] 55 } 56 57 NodeMap[K lang.Object, V any] struct { 58 lang.BaseObject 59 MapNodeFinder MapNodeFinder[K, V] 60 } 61 62 MapNodeFinderBySlot[K lang.Object, V any] struct { 63 lang.BaseObject 64 slotFinder MapSlotFinder[K, V] 65 } 66 ) 67 68 func NewMapNodeFinderBySlot[K lang.Object, V any](slotFinder MapSlotFinder[K, V]) MapNodeFinder[K, V] { 69 return &MapNodeFinderBySlot[K, V]{slotFinder: slotFinder} 70 } 71 72 func MapToString[K lang.Object, V any](m MapLooper[K, V]) lang.String { 73 builder := strings.Builder{} 74 builder.WriteString("{") 75 _ = m.Loop(func(k K, v V) exceptions.Exception { 76 if builder.Len() != 1 { 77 builder.WriteString(", ") 78 } 79 builder.WriteString(k.String()) 80 builder.WriteString(": ") 81 if ov, ok := lang.TryCast[lang.Object](v); ok { 82 builder.WriteString(ov.String()) 83 } else { 84 builder.WriteString(fmt.Sprint(v)) 85 } 86 return nil 87 }) 88 builder.WriteString("}") 89 return lang.NewString(builder.String()) 90 } 91 92 func (g *NodeMap[K, V]) findNode(k K, createIfNotExist bool) (node, prev MapNode[K, V]) { 93 return g.MapNodeFinder.findNode(k, createIfNotExist) 94 } 95 96 func (g *NodeMap[K, V]) Put(k K, v V) (bool, exceptions.Exception) { 97 node, _ := g.findNode(k, true) 98 node.SetValue(v) 99 return true, nil 100 } 101 102 func (g *NodeMap[K, V]) Get(k K) (V, bool, exceptions.Exception) { 103 node, _ := g.findNode(k, false) 104 if node == nil { 105 return g.nil() 106 } else { 107 return node.GetValue(), true, nil 108 } 109 } 110 111 func (g *NodeMap[K, V]) Remove(k K) (V, bool, exceptions.Exception) { 112 node, prev := g.findNode(k, false) 113 if node == nil { 114 return g.nil() 115 } else { 116 if prev != nil { 117 prev.RemoveNext() 118 } 119 return node.GetValue(), true, nil 120 } 121 } 122 123 func (g *NodeMap[K, V]) nil() (V, bool, exceptions.Exception) { 124 return lang.Nil[V](), false, nil 125 } 126 127 func (m *MapNodeFinderBySlot[K, V]) findNode(k K, createIfNotExist bool) (node, prev MapNode[K, V]) { 128 prev = m.slotFinder.FindSlot(k) 129 if prev != nil { 130 node = prev.GetNext() 131 for node != nil { 132 if node.GetKey().Equals(k) { 133 return 134 } 135 prev = node 136 node = node.GetNext() 137 } 138 } 139 if createIfNotExist { 140 node = prev.CreateNext(k) 141 } 142 return 143 } 144 145 func (s *SimpleMapNode[K, V]) String() string { 146 return "SimpleMapNode{key: " + s.key.String() + ", value: " + fmt.Sprint(s.value) + "}" 147 } 148 149 func (s *SimpleMapNode[K, V]) GetKey() K { 150 return s.key 151 } 152 153 func (s *SimpleMapNode[K, V]) GetValue() V { 154 return s.value 155 } 156 157 func (s *SimpleMapNode[K, V]) SetValue(value V) { 158 s.value = value 159 } 160 161 func (s *SimpleMapNode[K, V]) CreateNext(key K) MapNode[K, V] { 162 s.next = &SimpleMapNode[K, V]{key: key, next: s.next} 163 return s.next 164 } 165 166 func (s *SimpleMapNode[K, V]) GetNext() MapNode[K, V] { 167 if s.next == nil { 168 return nil 169 } 170 return s.next 171 } 172 173 func (s *SimpleMapNode[K, V]) RemoveNext() { 174 if s.next != nil { 175 s.next = s.next.next 176 } 177 }