github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/actor/pidset.go (about) 1 package actor 2 3 type PIDSet struct { 4 pids []*PID 5 lookup map[pidKey]int 6 } 7 8 // pidKey is used as a key in the lookup map to avoid allocations. 9 type pidKey struct { 10 address string 11 id string 12 } 13 14 func (p *PIDSet) key(pid *PID) pidKey { 15 return pidKey{address: pid.Address, id: pid.Id} 16 } 17 18 // NewPIDSet returns a new PIDSet with the given pids. 19 func NewPIDSet(pids ...*PID) *PIDSet { 20 p := &PIDSet{} 21 for _, pid := range pids { 22 p.Add(pid) 23 } 24 return p 25 } 26 27 func (p *PIDSet) ensureInit() { 28 if p.lookup == nil { 29 p.lookup = make(map[pidKey]int) 30 } 31 } 32 33 func (p *PIDSet) indexOf(v *PID) int { 34 if idx, ok := p.lookup[p.key(v)]; ok { 35 return idx 36 } 37 38 return -1 39 } 40 41 func (p *PIDSet) Contains(v *PID) bool { 42 _, ok := p.lookup[p.key(v)] 43 return ok 44 } 45 46 // Add adds the element v to the set. 47 func (p *PIDSet) Add(v *PID) { 48 p.ensureInit() 49 if p.Contains(v) { 50 return 51 } 52 53 p.pids = append(p.pids, v) 54 p.lookup[p.key(v)] = len(p.pids) - 1 55 } 56 57 // Remove removes v from the set and returns true if them element existed. 58 func (p *PIDSet) Remove(v *PID) bool { 59 p.ensureInit() 60 i := p.indexOf(v) 61 if i == -1 { 62 return false 63 } 64 65 delete(p.lookup, p.key(v)) 66 if i < len(p.pids)-1 { 67 lastPID := p.pids[len(p.pids)-1] 68 69 p.pids[i] = lastPID 70 p.lookup[p.key(lastPID)] = i 71 } 72 73 p.pids = p.pids[:len(p.pids)-1] 74 75 return true 76 } 77 78 // Len returns the number of elements in the set. 79 func (p *PIDSet) Len() int { 80 return len(p.pids) 81 } 82 83 // Clear removes all the elements in the set. 84 func (p *PIDSet) Clear() { 85 p.pids = p.pids[:0] 86 p.lookup = make(map[pidKey]int) 87 } 88 89 // Empty reports whether the set is empty. 90 func (p *PIDSet) Empty() bool { 91 return p.Len() == 0 92 } 93 94 // Values returns all the elements of the set as a slice. 95 func (p *PIDSet) Values() []*PID { 96 return p.pids 97 } 98 99 // ForEach invokes f for every element of the set. 100 func (p *PIDSet) ForEach(f func(i int, pid *PID)) { 101 for i, pid := range p.pids { 102 f(i, pid) 103 } 104 } 105 106 func (p *PIDSet) Get(index int) *PID { 107 return p.pids[index] 108 } 109 110 func (p *PIDSet) Clone() *PIDSet { 111 return NewPIDSet(p.pids...) 112 }