1
0
mirror of https://github.com/alice-lg/alice-lg.git synced 2024-05-11 05:55:03 +00:00

68 lines
1.2 KiB
Go
Raw Normal View History

2022-11-14 19:37:37 +01:00
package pools
import "sync"
2022-11-16 11:12:09 +01:00
// StringPool is a pool for strings.
// This will most likely be a pool for IP addresses.
2022-11-16 11:12:09 +01:00
type StringPool struct {
2022-11-14 19:37:37 +01:00
values map[string]*string
2022-11-14 19:37:37 +01:00
counter map[string]uint
top uint
2022-11-14 19:37:37 +01:00
2022-11-25 11:37:19 +01:00
sync.RWMutex
2022-11-14 19:37:37 +01:00
}
2022-11-16 11:12:09 +01:00
// NewStringPool creates a new string pool
func NewStringPool() *StringPool {
return &StringPool{
values: map[string]*string{},
counter: map[string]uint{},
2022-11-14 19:37:37 +01:00
}
}
// Acquire a pointer to a string value
2022-11-16 11:12:09 +01:00
func (p *StringPool) Acquire(s string) *string {
2022-11-14 19:37:37 +01:00
p.Lock()
defer p.Unlock()
// Deduplicate value
ptr, ok := p.values[s]
if !ok {
p.values[s] = &s
ptr = &s
}
p.counter[s] = p.top
2022-11-14 19:37:37 +01:00
return ptr
}
2022-11-25 11:37:19 +01:00
// Get retrieves a pointer to a string, if present.
// Otherwise returns nil.
func (p *StringPool) Get(s string) *string {
p.RLock()
defer p.RUnlock()
// Get value
ptr, ok := p.values[s]
if !ok {
return nil
}
return ptr
}
2022-11-14 19:37:37 +01:00
// GarbageCollect releases all values, which have not been seen
// again.
2022-11-16 11:12:09 +01:00
func (p *StringPool) GarbageCollect() uint {
2022-11-14 19:37:37 +01:00
p.Lock()
defer p.Unlock()
var released uint = 0
for k, cnt := range p.counter {
if cnt < p.top {
delete(p.counter, k)
delete(p.values, k)
released++
}
}
p.top++ // Next generation
2022-11-14 19:37:37 +01:00
return released
}