package model import ( "sync/atomic" "spark-server/internal/pkg/sensitive" ) // MatcherStore holds a hot-swappable sensitive.Matcher. type MatcherStore struct { ptr atomic.Pointer[sensitive.Matcher] byID map[int64]*WordRow } func NewMatcherStore() *MatcherStore { return &MatcherStore{byID: map[int64]*WordRow{}} } func (s *MatcherStore) Get() *sensitive.Matcher { if s == nil { return nil } return s.ptr.Load() } func (s *MatcherStore) Replace(rows []WordRow) { entries := make([]sensitive.Entry, 0, len(rows)) byID := make(map[int64]*WordRow, len(rows)) for i := range rows { r := rows[i] if r.Enabled != 1 || r.Word == "" { continue } byID[r.ID] = &rows[i] entries = append(entries, sensitive.Entry{ID: r.ID, Word: r.Word}) } m := sensitive.Build(entries) if s == nil { return } s.byID = byID s.ptr.Store(m) } func (s *MatcherStore) WordByID(id int64) *WordRow { if s == nil { return nil } return s.byID[id] }