From df241ebd4411c77d78b71f4980191f5687dfa364 Mon Sep 17 00:00:00 2001 From: Mohammad Alian Date: Thu, 9 Jan 2025 00:49:42 +0900 Subject: [PATCH 1/3] remove unnecessary mutext --- tags.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tags.go b/tags.go index e585228..268f920 100644 --- a/tags.go +++ b/tags.go @@ -1,23 +1,14 @@ package icache -import ( - "sync" -) - type tags[T any] struct { - rw sync.RWMutex pairs map[uint64]entries[T] } func (t *tags[T]) purge() { - t.rw.Lock() - defer t.rw.Unlock() t.pairs = make(map[uint64]entries[T]) } func (t *tags[T]) add(e *entry[T]) { - t.rw.Lock() - defer t.rw.Unlock() if e == nil || e.tags == nil { return } @@ -36,18 +27,12 @@ func (t *tags[T]) add(e *entry[T]) { func (t *tags[T]) dropTagIfNoOtherEntriesExist(tag uint64) { entries := t.getEntriesWithTags(tag) - t.rw.Lock() - defer t.rw.Unlock() if len(entries) == 0 { - t.pairs[tag] = nil delete(t.pairs, tag) } } func (t *tags[T]) getEntriesWithTags(tags ...uint64) entrySlice[T] { - t.rw.RLock() - defer t.rw.RUnlock() - var results entrySlice[T] for _, tag := range tags { entries, ok := t.pairs[tag] From e6bf71b6ca185092634e4cb0d745f399ecd32c66 Mon Sep 17 00:00:00 2001 From: Mohammad Alian Date: Thu, 9 Jan 2025 01:03:52 +0900 Subject: [PATCH 2/3] adjust locks --- pot.go | 25 ++----------------------- tags.go | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/pot.go b/pot.go index 5e795d6..00bf77d 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,9 +69,6 @@ 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 @@ -100,9 +91,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,9 +103,6 @@ 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 @@ -135,9 +120,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 +135,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 +145,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 +152,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 +161,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() diff --git a/tags.go b/tags.go index 268f920..ef39a59 100644 --- a/tags.go +++ b/tags.go @@ -1,14 +1,23 @@ package icache +import ( + "sync" +) + type tags[T any] struct { + rw sync.RWMutex pairs map[uint64]entries[T] } func (t *tags[T]) purge() { + t.rw.Lock() + defer t.rw.Unlock() t.pairs = make(map[uint64]entries[T]) } func (t *tags[T]) add(e *entry[T]) { + t.rw.Lock() + defer t.rw.Unlock() if e == nil || e.tags == nil { return } @@ -27,12 +36,19 @@ func (t *tags[T]) add(e *entry[T]) { func (t *tags[T]) dropTagIfNoOtherEntriesExist(tag uint64) { entries := t.getEntriesWithTags(tag) + t.rw.Lock() + defer t.rw.Unlock() if len(entries) == 0 { + t.pairs[tag] = nil delete(t.pairs, tag) } } func (t *tags[T]) getEntriesWithTags(tags ...uint64) entrySlice[T] { + + t.rw.RLock() + defer t.rw.RUnlock() + var results entrySlice[T] for _, tag := range tags { entries, ok := t.pairs[tag] From bfffdf01319d600ba48f5011d3f6c1644cc3f4e9 Mon Sep 17 00:00:00 2001 From: Mohammad Alian Date: Thu, 9 Jan 2025 01:47:18 +0900 Subject: [PATCH 3/3] remove entry mutex --- entry.go | 3 --- pot.go | 7 ------- shard.go | 2 -- tags.go | 2 -- 4 files changed, 14 deletions(-) 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 00bf77d..6ab8c6d 100644 --- a/pot.go +++ b/pot.go @@ -74,8 +74,6 @@ func (p *pot[T]) ExpireTime(key string) (t *time.Time, err error) { return nil, ErrNotFound } - e.rw.RLock() - defer e.rw.RUnlock() ti := time.UnixMilli(e.expiresAt) return &ti, nil } @@ -108,8 +106,6 @@ func (p *pot[T]) Get(key string) (v T, err error) { return v, ErrNotFound } - e.rw.RLock() - defer e.rw.RUnlock() if e.deleted { p.dropEntry(e) return v, ErrNotFound @@ -170,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 ef39a59..bf4599d 100644 --- a/tags.go +++ b/tags.go @@ -59,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