...also adds a bounded custom event registry for cardinality control but I ran out of space in the commit message. Praise be to the long descriptions... Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ic205f69804c7fb24c39fa84abdd9546b6a6a6964
56 lines
1.3 KiB
Go
56 lines
1.3 KiB
Go
package aggregate
|
|
|
|
import "sync"
|
|
|
|
// Maintains a bounded set of allowed custom event names
|
|
type CustomEventRegistry struct {
|
|
mu sync.RWMutex
|
|
events map[string]struct{}
|
|
maxEvents int
|
|
overflowCount int
|
|
}
|
|
|
|
// Creates a registry with a maximum number of unique event names
|
|
func NewCustomEventRegistry(maxEvents int) *CustomEventRegistry {
|
|
return &CustomEventRegistry{
|
|
events: make(map[string]struct{}, maxEvents),
|
|
maxEvents: maxEvents,
|
|
}
|
|
}
|
|
|
|
// Add attempts to add an event name to the registry
|
|
// Returns the event name if accepted, "other" if rejected due to limit
|
|
func (r *CustomEventRegistry) Add(eventName string) string {
|
|
// Fast path: check with read lock first
|
|
r.mu.RLock()
|
|
if _, exists := r.events[eventName]; exists {
|
|
r.mu.RUnlock()
|
|
return eventName
|
|
}
|
|
r.mu.RUnlock()
|
|
|
|
// Slow path: acquire write lock to add
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
// Double-check after acquiring write lock
|
|
if _, exists := r.events[eventName]; exists {
|
|
return eventName
|
|
}
|
|
|
|
// Check limit
|
|
if len(r.events) >= r.maxEvents {
|
|
r.overflowCount++
|
|
return "other"
|
|
}
|
|
|
|
r.events[eventName] = struct{}{}
|
|
return eventName
|
|
}
|
|
|
|
// Returns the number of events rejected due to limit
|
|
func (r *CustomEventRegistry) OverflowCount() int {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
return r.overflowCount
|
|
}
|