gosora/common/poll_cache.go

203 lines
3.7 KiB
Go

package common
import (
"sync"
"sync/atomic"
)
type PollCache interface {
Get(id int) (*Poll, error)
GetUnsafe(id int) (*Poll, error)
BulkGet(ids []int) (list []*Poll)
Set(item *Poll) error
Add(item *Poll) error
AddUnsafe(item *Poll) error
Remove(id int) error
RemoveUnsafe(id int) error
Flush()
Length() int
SetCapacity(capacity int)
GetCapacity() int
}
type MemoryPollCache struct {
items map[int]*Poll
length int64
capacity int
sync.RWMutex
}
// NewMemoryPollCache gives you a new instance of MemoryPollCache
func NewMemoryPollCache(capacity int) *MemoryPollCache {
return &MemoryPollCache{
items: make(map[int]*Poll),
capacity: capacity,
}
}
func (mus *MemoryPollCache) Get(id int) (*Poll, error) {
mus.RLock()
item, ok := mus.items[id]
mus.RUnlock()
if ok {
return item, nil
}
return item, ErrNoRows
}
func (mus *MemoryPollCache) BulkGet(ids []int) (list []*Poll) {
list = make([]*Poll, len(ids))
mus.RLock()
for i, id := range ids {
list[i] = mus.items[id]
}
mus.RUnlock()
return list
}
func (mus *MemoryPollCache) GetUnsafe(id int) (*Poll, error) {
item, ok := mus.items[id]
if ok {
return item, nil
}
return item, ErrNoRows
}
func (mus *MemoryPollCache) Set(item *Poll) error {
mus.Lock()
user, ok := mus.items[item.ID]
if ok {
mus.Unlock()
*user = *item
} else if int(mus.length) >= mus.capacity {
mus.Unlock()
return ErrStoreCapacityOverflow
} else {
mus.items[item.ID] = item
mus.Unlock()
atomic.AddInt64(&mus.length, 1)
}
return nil
}
func (mus *MemoryPollCache) Add(item *Poll) error {
if int(mus.length) >= mus.capacity {
return ErrStoreCapacityOverflow
}
mus.Lock()
mus.items[item.ID] = item
mus.length = int64(len(mus.items))
mus.Unlock()
return nil
}
func (mus *MemoryPollCache) AddUnsafe(item *Poll) error {
if int(mus.length) >= mus.capacity {
return ErrStoreCapacityOverflow
}
mus.items[item.ID] = item
mus.length = int64(len(mus.items))
return nil
}
func (mus *MemoryPollCache) Remove(id int) error {
mus.Lock()
_, ok := mus.items[id]
if !ok {
mus.Unlock()
return ErrNoRows
}
delete(mus.items, id)
mus.Unlock()
atomic.AddInt64(&mus.length, -1)
return nil
}
func (mus *MemoryPollCache) RemoveUnsafe(id int) error {
_, ok := mus.items[id]
if !ok {
return ErrNoRows
}
delete(mus.items, id)
atomic.AddInt64(&mus.length, -1)
return nil
}
func (mus *MemoryPollCache) Flush() {
mus.Lock()
mus.items = make(map[int]*Poll)
mus.length = 0
mus.Unlock()
}
// ! Is this concurrent?
// Length returns the number of users in the memory cache
func (mus *MemoryPollCache) Length() int {
return int(mus.length)
}
func (mus *MemoryPollCache) SetCapacity(capacity int) {
mus.capacity = capacity
}
func (mus *MemoryPollCache) GetCapacity() int {
return mus.capacity
}
type NullPollCache struct {
}
// NewNullPollCache gives you a new instance of NullPollCache
func NewNullPollCache() *NullPollCache {
return &NullPollCache{}
}
func (mus *NullPollCache) Get(id int) (*Poll, error) {
return nil, ErrNoRows
}
func (mus *NullPollCache) BulkGet(ids []int) (list []*Poll) {
return list
}
func (mus *NullPollCache) GetUnsafe(id int) (*Poll, error) {
return nil, ErrNoRows
}
func (mus *NullPollCache) Set(_ *Poll) error {
return nil
}
func (mus *NullPollCache) Add(item *Poll) error {
_ = item
return nil
}
func (mus *NullPollCache) AddUnsafe(item *Poll) error {
_ = item
return nil
}
func (mus *NullPollCache) Remove(id int) error {
return nil
}
func (mus *NullPollCache) RemoveUnsafe(id int) error {
return nil
}
func (mus *NullPollCache) Flush() {
}
func (mus *NullPollCache) Length() int {
return 0
}
func (mus *NullPollCache) SetCapacity(_ int) {
}
func (mus *NullPollCache) GetCapacity() int {
return 0
}