diff --git a/entry.go b/entry.go index 36a1614..a4d6e66 100644 --- a/entry.go +++ b/entry.go @@ -1,7 +1,5 @@ package icache -import "sync" - type entries[T any] map[uint64]*entry[T] type entrySlice[T any] []*entry[T] @@ -13,5 +11,4 @@ type entry[T any] struct { expiresAt int64 tags []uint64 deleted bool - rw sync.RWMutex } diff --git a/pot.go b/pot.go index 5e795d6..6ab8c6d 100644 --- a/pot.go +++ b/pot.go @@ -58,16 +58,10 @@ func (p *pot[T]) Purge() { } func (p *pot[T]) Len() int { - p.windowRW.RLock() - defer p.windowRW.RUnlock() - return p.shards.EntriesLen() } func (p *pot[T]) Exists(key string) (ok bool) { - p.windowRW.RLock() - defer p.windowRW.RUnlock() - k, shard := keyGen(key) exists := p.shards[shard].EntryExists(k) @@ -75,16 +69,11 @@ func (p *pot[T]) Exists(key string) (ok bool) { } func (p *pot[T]) ExpireTime(key string) (t *time.Time, err error) { - p.windowRW.RLock() - defer p.windowRW.RUnlock() - e, ok := p.getEntry(key) if !ok { return nil, ErrNotFound } - e.rw.RLock() - defer e.rw.RUnlock() ti := time.UnixMilli(e.expiresAt) return &ti, nil } @@ -100,9 +89,6 @@ func (p *pot[T]) getEntry(key string) (*entry[T], bool) { } func (p *pot[T]) GetByTag(tag string) ([]T, error) { - p.windowRW.RLock() - defer p.windowRW.RUnlock() - entries := p.tags.getEntriesWithTags(tagKeyGen(tag)...) if len(entries) == 0 { return nil, ErrNotFound @@ -115,16 +101,11 @@ func (p *pot[T]) GetByTag(tag string) ([]T, error) { } func (p *pot[T]) Get(key string) (v T, err error) { - p.windowRW.RLock() - defer p.windowRW.RUnlock() - e, ok := p.getEntry(key) if !ok { return v, ErrNotFound } - e.rw.RLock() - defer e.rw.RUnlock() if e.deleted { p.dropEntry(e) return v, ErrNotFound @@ -135,9 +116,6 @@ func (p *pot[T]) Get(key string) (v T, err error) { func (p *pot[T]) Set(key string, v T, tags ...string) { expireTime := time.Now().Add(p.ttl).UnixNano() - p.windowRW.Lock() - defer p.windowRW.Unlock() - k, shard := keyGen(key) e, found := p.shards[shard].GetEntry(k) if found { @@ -153,7 +131,9 @@ func (p *pot[T]) Set(key string, v T, tags ...string) { } if p.ttl > 0 { + p.windowRW.Lock() p.window = append(p.window, e) + p.windowRW.Unlock() } p.tags.add(e) @@ -161,8 +141,6 @@ func (p *pot[T]) Set(key string, v T, tags ...string) { } func (p *pot[T]) DropTags(tags ...string) { - p.windowRW.Lock() - defer p.windowRW.Unlock() entriesToDrop := p.tags.getEntriesWithTags(tagKeyGen(tags...)...) for _, e := range entriesToDrop { p.dropEntry(e) @@ -170,8 +148,6 @@ func (p *pot[T]) DropTags(tags ...string) { } func (p *pot[T]) Drop(keys ...string) { - p.windowRW.Lock() - defer p.windowRW.Unlock() for _, key := range keys { if e, ok := p.getEntry(key); ok { p.dropEntry(e) @@ -181,7 +157,6 @@ func (p *pot[T]) Drop(keys ...string) { func (p *pot[T]) dropExpiredEntries(at time.Time) { now := at.UnixNano() - p.windowRW.Lock() defer p.windowRW.Unlock() @@ -191,15 +166,12 @@ func (p *pot[T]) dropExpiredEntries(at time.Time) { expiredWindows++ continue } - e.rw.Lock() if e.expiresAt >= now { // not expired yet - e.rw.Unlock() break } e.deleted = true p.dropEntry(e) expiredWindows++ - e.rw.Unlock() } if expiredWindows > 0 { remaining := len(p.window) - expiredWindows diff --git a/shard.go b/shard.go index 920fdde..79e9576 100644 --- a/shard.go +++ b/shard.go @@ -38,8 +38,6 @@ func (s *shard[T]) EntryExists(key uint64) bool { if !ok || e == nil { return false } - e.rw.RLock() - defer e.rw.RUnlock() return !e.deleted } diff --git a/tags.go b/tags.go index e585228..bf4599d 100644 --- a/tags.go +++ b/tags.go @@ -45,6 +45,7 @@ func (t *tags[T]) dropTagIfNoOtherEntriesExist(tag uint64) { } func (t *tags[T]) getEntriesWithTags(tags ...uint64) entrySlice[T] { + t.rw.RLock() defer t.rw.RUnlock() @@ -58,11 +59,9 @@ func (t *tags[T]) getEntriesWithTags(tags ...uint64) entrySlice[T] { if e == nil { continue } - e.rw.RLock() if !e.deleted { results = append(results, e) } - e.rw.RUnlock() } } return results