github.com/15mga/kiwi@v0.0.2-0.20240324021231-b95d5c3ac751/ds/set_link.go (about) 1 package ds 2 3 import ( 4 "github.com/15mga/kiwi/util" 5 ) 6 7 type ( 8 setLinkOption[KT comparable, VT any] struct { 9 valToKey func(VT) KT 10 spawnElem func() *SetLinkElem[VT] 11 recycleElem func(*SetLinkElem[VT]) 12 } 13 DLinkOption[KT comparable, VT any] func(o *setLinkOption[KT, VT]) 14 ) 15 16 func SetLinkValToKey[KT comparable, VT any](valToKey func(VT) KT) DLinkOption[KT, VT] { 17 return func(o *setLinkOption[KT, VT]) { 18 o.valToKey = valToKey 19 } 20 } 21 22 func SetLinkSpawnElem[KT comparable, VT any](spawn func() *SetLinkElem[VT]) DLinkOption[KT, VT] { 23 return func(o *setLinkOption[KT, VT]) { 24 o.spawnElem = spawn 25 } 26 } 27 28 func SetLinkRecycleElem[KT comparable, VT any](recycle func(*SetLinkElem[VT])) DLinkOption[KT, VT] { 29 return func(o *setLinkOption[KT, VT]) { 30 o.recycleElem = recycle 31 } 32 } 33 34 func NewSetLink[KT comparable, VT any](cap int, opts ...DLinkOption[KT, VT]) *SetLink[KT, VT] { 35 opt := &setLinkOption[KT, VT]{ 36 spawnElem: func() *SetLinkElem[VT] { 37 return &SetLinkElem[VT]{} 38 }, 39 recycleElem: func(elem *SetLinkElem[VT]) {}, 40 } 41 for _, o := range opts { 42 o(opt) 43 } 44 return &SetLink[KT, VT]{ 45 option: opt, 46 keyToNode: make(map[KT]*SetLinkElem[VT], cap), 47 } 48 } 49 50 // SetLink 元素唯一双向链表 51 type SetLink[KT comparable, VT any] struct { 52 option *setLinkOption[KT, VT] 53 head *SetLinkElem[VT] 54 tail *SetLinkElem[VT] 55 keyToNode map[KT]*SetLinkElem[VT] 56 count int 57 } 58 59 func (l *SetLink[KT, VT]) Get(key KT) (VT, bool) { 60 v, ok := l.keyToNode[key] 61 if ok { 62 return v.Value, true 63 } 64 return util.Default[VT](), false 65 } 66 67 // Push 推入元素,如果已存在返回false 68 func (l *SetLink[KT, VT]) Push(val VT) bool { 69 key := l.option.valToKey(val) 70 _, ok := l.keyToNode[key] 71 if ok { 72 return false 73 } 74 l.push(key, val) 75 return true 76 } 77 78 func (l *SetLink[KT, VT]) push(key KT, val VT) { 79 node := l.option.spawnElem() 80 node.Value = val 81 l.keyToNode[key] = node 82 if l.count == 0 { 83 l.head = node 84 l.tail = node 85 } else { 86 node.prevNode = l.tail 87 l.tail.nextNode = node 88 l.tail = node 89 } 90 l.count++ 91 } 92 93 func (l *SetLink[KT, VT]) NewOrUpdate(key KT, update func(VT), new func() VT) (exist bool) { 94 v, ok := l.keyToNode[key] 95 if ok { 96 update(v.Value) 97 return true 98 } 99 l.push(key, new()) 100 return false 101 } 102 103 // Del 测试弹出一个符合条件的即停止 104 func (l *SetLink[KT, VT]) Del(test func(VT) bool) (VT, bool) { 105 for node := l.head; node != nil; node = node.nextNode { 106 if test(node.Value) { 107 v := node.Value 108 l.removeNode(node) 109 return v, true 110 } 111 } 112 return util.Default[VT](), false 113 } 114 115 func (l *SetLink[KT, VT]) Pop() (VT, bool) { 116 if l.count == 0 { 117 return util.Default[VT](), false 118 } 119 firstNode := l.head 120 v := firstNode.Value 121 l.head = firstNode.nextNode 122 if l.option.recycleElem != nil { 123 firstNode.Dispose() 124 l.option.recycleElem(firstNode) 125 } 126 delete(l.keyToNode, l.option.valToKey(v)) 127 return v, true 128 } 129 130 func (l *SetLink[KT, VT]) removeNode(node *SetLinkElem[VT]) { 131 if l.head == node { 132 if l.tail == node { 133 l.head = nil 134 l.tail = nil 135 } else { 136 l.head = node.nextNode 137 l.head.prevNode = nil 138 } 139 } else if l.tail == node { 140 prevNode := node.prevNode 141 prevNode.nextNode = nil 142 l.tail = prevNode 143 } else { 144 prevNode := node.prevNode 145 nextNode := node.nextNode 146 prevNode.nextNode = nextNode 147 nextNode.prevNode = prevNode 148 } 149 delete(l.keyToNode, l.option.valToKey(node.Value)) 150 l.count-- 151 if l.option.recycleElem != nil { 152 node.Dispose() 153 l.option.recycleElem(node) 154 } 155 } 156 157 func (l *SetLink[KT, VT]) Remove(val VT) { 158 l.RemoveByKey(l.option.valToKey(val)) 159 } 160 161 func (l *SetLink[KT, VT]) RemoveByKey(key KT) { 162 node, ok := l.keyToNode[key] 163 if !ok { 164 return 165 } 166 l.removeNode(node) 167 } 168 169 func (l *SetLink[KT, VT]) Iter(fn func(VT)) { 170 if l.count == 0 { 171 return 172 } 173 for n := l.head; n != nil; n = n.nextNode { 174 fn(n.Value) 175 } 176 } 177 178 func (l *SetLink[KT, VT]) Any(fn func(VT) bool) bool { 179 if l.count == 0 { 180 return false 181 } 182 for n := l.head; n != nil; n = n.nextNode { 183 if fn(n.Value) { 184 return true 185 } 186 } 187 return false 188 } 189 190 func (l *SetLink[KT, VT]) Values() []VT { 191 if l.count == 0 { 192 return nil 193 } 194 values := make([]VT, l.count) 195 i := 0 196 for n := l.head; n != nil; n = n.nextNode { 197 values[i] = n.Value 198 i++ 199 } 200 return values 201 } 202 203 func (l *SetLink[KT, VT]) Count() int { 204 return l.count 205 } 206 207 type SetLinkElem[T any] struct { 208 Value T 209 prevNode *SetLinkElem[T] 210 nextNode *SetLinkElem[T] 211 } 212 213 func (n *SetLinkElem[T]) Dispose() { 214 n.prevNode = nil 215 n.nextNode = nil 216 }