Skip to content

Commit 0901f94

Browse files
authored
Merge pull request #93 from chenyijun266846/perf_setnx
perf: add setnx2
2 parents e9a80ae + a47156d commit 0901f94

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

bucket.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,30 @@ func (b *bucket[T]) setnx(key string, value T, duration time.Duration, track boo
5959
return newItem
6060
}
6161

62+
func (b *bucket[T]) setnx2(key string, f func() T, duration time.Duration, track bool) (*Item[T], bool) {
63+
b.RLock()
64+
item := b.lookup[key]
65+
b.RUnlock()
66+
if item != nil {
67+
return item, true
68+
}
69+
70+
b.Lock()
71+
defer b.Unlock()
72+
73+
// check again under write lock
74+
item = b.lookup[key]
75+
if item != nil {
76+
return item, true
77+
}
78+
79+
expires := time.Now().Add(duration).UnixNano()
80+
newItem := newItem(key, f(), expires, track)
81+
82+
b.lookup[key] = newItem
83+
return newItem, false
84+
}
85+
6286
func (b *bucket[T]) set(key string, value T, duration time.Duration, track bool) (*Item[T], *Item[T]) {
6387
expires := time.Now().Add(duration).UnixNano()
6488
item := newItem(key, value, expires, track)

cache.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,22 @@ func (c *Cache[T]) Setnx(key string, value T, duration time.Duration) {
124124
c.bucket(key).setnx(key, value, duration, false)
125125
}
126126

127+
// Setnx2 set the value in the cache for the specified duration if not exists
128+
func (c *Cache[T]) Setnx2(key string, f func() T, duration time.Duration) *Item[T] {
129+
item, existing := c.bucket(key).setnx2(key, f, duration, false)
130+
// consistent with Get
131+
if existing && !item.Expired() {
132+
select {
133+
case c.promotables <- item:
134+
default:
135+
}
136+
// consistent with set
137+
} else if !existing {
138+
c.promotables <- item
139+
}
140+
return item
141+
}
142+
127143
// Replace the value if it exists, does not set if it doesn't.
128144
// Returns true if the item existed an was replaced, false otherwise.
129145
// Replace does not reset item's TTL

0 commit comments

Comments
 (0)