go.temporal.io/server@v1.23.0/common/collection/indexedtakelist.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package collection 26 27 // IndexedTakeList holds a set of values that can only be observed by being 28 // removed from the set. It is possible for this set to contain duplicate values 29 // as long as each value maps to a distinct index. 30 type ( 31 IndexedTakeList[K comparable, V any] struct { 32 values []kv[K, V] 33 } 34 35 kv[K comparable, V any] struct { 36 key K 37 value V 38 removed bool 39 } 40 ) 41 42 // NewIndexedTakeList constructs a new IndexedTakeSet by applying the provided 43 // indexer to each of the provided values. 44 func NewIndexedTakeList[K comparable, V any]( 45 values []V, 46 indexer func(V) K, 47 ) *IndexedTakeList[K, V] { 48 ret := &IndexedTakeList[K, V]{ 49 values: make([]kv[K, V], 0, len(values)), 50 } 51 for _, v := range values { 52 ret.values = append(ret.values, kv[K, V]{key: indexer(v), value: v}) 53 } 54 return ret 55 } 56 57 // Take finds a value in this set by its key and removes it, returning the 58 // value. 59 func (itl *IndexedTakeList[K, V]) Take(key K) (V, bool) { 60 var zero V 61 for i := 0; i < len(itl.values); i++ { 62 kv := &itl.values[i] 63 if kv.key != key { 64 continue 65 } 66 if kv.removed { 67 return zero, false 68 } 69 kv.removed = true 70 return kv.value, true 71 } 72 return zero, false 73 } 74 75 // TakeRemaining removes all remaining values from this set and returns them. 76 func (itl *IndexedTakeList[K, V]) TakeRemaining() []V { 77 out := make([]V, 0, len(itl.values)) 78 for i := 0; i < len(itl.values); i++ { 79 kv := &itl.values[i] 80 if !kv.removed { 81 out = append(out, kv.value) 82 } 83 } 84 itl.values = nil 85 return out 86 }