123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- package go_int32_handle
- import (
- "fmt"
- "github.com/gammazero/deque"
- "sync"
- )
- type Payload interface {
- }
- var ErrHandleExceedMax = fmt.Errorf("handle exceed max")
- type HandleManager[T Payload] struct {
- handles map[int32]T
- lock sync.RWMutex
- counter int32
- releasedHandles *deque.Deque[int32]
- max int32
- }
- // New returns a new handle manager, same as NewWithRange(0, 2147483647)
- func New[T Payload]() *HandleManager[T] {
- return &HandleManager[T]{
- handles: make(map[int32]T),
- releasedHandles: deque.New[int32](),
- counter: 0,
- lock: sync.RWMutex{},
- max: 2147483647,
- }
- }
- // NewWithRange returns a new handle manager.
- // `shouldAbove` is the first handle - 1. this should be greater than 0 or equal to 0.
- // `max` is the last handle. this should be greater than 0.
- func NewWithRange[T Payload](shouldAbove int32, max int32) *HandleManager[T] {
- return &HandleManager[T]{
- handles: make(map[int32]T),
- releasedHandles: deque.New[int32](),
- counter: shouldAbove,
- lock: sync.RWMutex{},
- max: max,
- }
- }
- func (hm *HandleManager[T]) getNewHandle() int32 {
- if hm.releasedHandles.Len() > 0 {
- return hm.releasedHandles.PopFront()
- } else {
- hm.counter = hm.counter + 1
- return hm.counter
- }
- }
- func (hm *HandleManager[T]) AllocateAndPut(value T) (int32, error) {
- hm.lock.Lock()
- defer hm.lock.Unlock()
- h := hm.getNewHandle()
- if h >= hm.max {
- return 0, ErrHandleExceedMax
- }
- _, ok := hm.handles[h]
- if ok {
- return 0, fmt.Errorf("internal error: failed to allocate handle: next val %d is already in use", h)
- }
- hm.handles[h] = value
- return h, nil
- }
- func (hm *HandleManager[T]) Get(h int32) (T, bool) {
- hm.lock.RLock()
- defer hm.lock.RUnlock()
- if h <= 0 {
- var emptyT T
- return emptyT, false
- }
- value, ok := hm.handles[h]
- return value, ok
- }
- func (hm *HandleManager[T]) Release(h int32) (T, bool) {
- hm.lock.Lock()
- defer hm.lock.Unlock()
- if h <= 0 {
- var emptyT T
- return emptyT, false
- }
- value, ok := hm.handles[h]
- if ok {
- delete(hm.handles, h)
- hm.releasedHandles.PushBack(h)
- }
- return value, ok
- }
- func (hm *HandleManager[T]) ReleaseSilently(h int32) {
- hm.lock.Lock()
- defer hm.lock.Unlock()
- if h <= 0 {
- return
- }
- _, ok := hm.handles[h]
- if ok {
- delete(hm.handles, h)
- hm.releasedHandles.PushBack(h)
- }
- }
- func (hm *HandleManager[T]) Count() int {
- hm.lock.RLock()
- defer hm.lock.RUnlock()
- return len(hm.handles)
- }
|