package cache func NewCache() *Cache { c := &Cache{} c.state.Store(&mappings{ s2c: make(map[string]string), c2s: make(map[string]string), }) return c } func (c *Cache) Set(serverId, channelId string) { c.mu.Lock() defer c.mu.Unlock() current := c.state.Load() next := current.clone() if oldCh, ok := next.s2c[serverId]; ok && oldCh != channelId { delete(next.c2s, oldCh) } if oldSrv, ok := next.c2s[channelId]; ok && oldSrv != serverId { delete(next.s2c, oldSrv) } next.s2c[serverId] = channelId next.c2s[channelId] = serverId c.state.Store(next) } func (c *Cache) GetByServerId(serverId string) (string, bool) { m := c.state.Load() val, ok := m.s2c[serverId] return val, ok } func (c *Cache) GetByChannelId(channelId string) (string, bool) { m := c.state.Load() val, ok := m.c2s[channelId] return val, ok } func (c *Cache) RemoveByServerId(serverId string) { c.mu.Lock() defer c.mu.Unlock() current := c.state.Load() if _, ok := current.s2c[serverId]; !ok { return } next := current.clone() if channelId, ok := next.s2c[serverId]; ok { delete(next.s2c, serverId) delete(next.c2s, channelId) } c.state.Store(next) } func (c *Cache) RemoveByChannelId(channelId string) { c.mu.Lock() defer c.mu.Unlock() current := c.state.Load() if _, ok := current.c2s[channelId]; !ok { return } next := current.clone() if serverId, ok := next.c2s[channelId]; ok { delete(next.c2s, channelId) delete(next.s2c, serverId) } c.state.Store(next) } func (m *mappings) clone() *mappings { newM := &mappings{ s2c: make(map[string]string, len(m.s2c)), c2s: make(map[string]string, len(m.c2s)), } for k, v := range m.s2c { newM.s2c[k] = v } for k, v := range m.c2s { newM.c2s[k] = v } return newM }