Skip to content

Commit

Permalink
fix concurrency
Browse files Browse the repository at this point in the history
  • Loading branch information
latitov committed Jul 14, 2023
1 parent 64d2ee8 commit c90b6f3
Show file tree
Hide file tree
Showing 94 changed files with 31,988 additions and 26 deletions.
40 changes: 19 additions & 21 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func New[K comparable, V any](opts ...Option[K, V]) *Cache[K, V] {
// it to the cache and then returns it. If an item associated with the
// provided key already exists, the new item overwrites the existing one.
func (c *Cache[K, V]) Set(key K, value V) *Item[K, V] {
if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Lock()
defer c.CacheItems.Mu.Unlock()
}
Expand All @@ -87,7 +87,7 @@ func (c *Cache[K, V]) Set(key K, value V) *Item[K, V] {
// it to the cache and then returns it. If an item associated with the
// provided key already exists, the new item overwrites the existing one.
func (c *Cache[K, V]) SetWithTTL(key K, value V, ttl time.Duration) *Item[K, V] {
if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Lock()
defer c.CacheItems.Mu.Unlock()
}
Expand All @@ -100,7 +100,7 @@ func (c *Cache[K, V]) SetWithTTL(key K, value V, ttl time.Duration) *Item[K, V]
// provided key already exists, the new item overwrites the existing one.
// DOES NOT UPDATE EXPIRATIONS
func (c *Cache[K, V]) SetDontTouch(key K, value V) *Item[K, V] {
if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Lock()
defer c.CacheItems.Mu.Unlock()
}
Expand All @@ -113,7 +113,7 @@ func (c *Cache[K, V]) SetDontTouch(key K, value V) *Item[K, V] {
// provided key already exists, the new item overwrites the existing one.
// DOES NOT UPDATE EXPIRATIONS
func (c *Cache[K, V]) SetWithTTLDontTouch(key K, value V, ttl time.Duration) *Item[K, V] {
if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Lock()
defer c.CacheItems.Mu.Unlock()
}
Expand All @@ -133,11 +133,11 @@ func (c *Cache[K, V]) Get(key K, opts ...Option[K, V]) *Item[K, V] {

applyOptions(&getOpts, opts...)

if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Lock()
}
elem, isExistAndExpired := c.get(key, !getOpts.disableTouchOnHit)
if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Unlock()
}

Expand All @@ -163,14 +163,14 @@ func (c *Cache[K, V]) Get2(key K) (item *Item[K, V], isExistAndExpired bool) {
disableTouchOnHit: c.options.disableTouchOnHit,
}

if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Lock()
}

var elem *list.Element
elem, isExistAndExpired = c.get(key, !getOpts.disableTouchOnHit)

if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Unlock()
}

Expand All @@ -184,19 +184,19 @@ func (c *Cache[K, V]) Get2(key K) (item *Item[K, V], isExistAndExpired bool) {
return elem.Value.(*Item[K, V]), isExistAndExpired
}

func (c *Cache[K, V]) Transaction(f func(c *Cache[K, V])) {
func (c *Cache[K, V]) Transaction(transactionFunc func(c *Cache[K, V])) {
c.CacheItems.Mu.Lock()
defer c.CacheItems.Mu.Unlock()
c.options.lockingDisabledForTransaction = true
defer func() { c.options.lockingDisabledForTransaction = false }()
c.options.locklessWhileInTransaction = true
defer func() { c.options.locklessWhileInTransaction = false }()

f(c)
transactionFunc(c)
}

// Delete deletes an item from the cache. If the item associated with
// the key is not found, the method is no-op.
func (c *Cache[K, V]) Delete(key K) {
if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Lock()
defer c.CacheItems.Mu.Unlock()
}
Expand All @@ -211,21 +211,19 @@ func (c *Cache[K, V]) Delete(key K) {

// DeleteAll deletes all items from the cache.
func (c *Cache[K, V]) DeleteAll() {
if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Lock()
}
c.evict(EvictionReasonDeleted)
if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Unlock()
}
}

// DeleteExpired deletes all expired items from the cache.
func (c *Cache[K, V]) DeleteExpired() {
if !c.options.lockingDisabledForTransaction {
c.CacheItems.Mu.Lock()
defer c.CacheItems.Mu.Unlock()
}
c.CacheItems.Mu.Lock()
defer c.CacheItems.Mu.Unlock()

if c.CacheItems.expQueue.isEmpty() {
return
Expand All @@ -248,11 +246,11 @@ func (c *Cache[K, V]) DeleteExpired() {
// Its main purpose is to extend an item's expiration timestamp.
// If the item is not found, the method is no-op.
func (c *Cache[K, V]) Touch(key K) {
if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Lock()
}
c.get(key, true)
if !c.options.lockingDisabledForTransaction {
if !c.options.locklessWhileInTransaction {
c.CacheItems.Mu.Unlock()
}
}
Expand Down
10 changes: 5 additions & 5 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ func (fn optionFunc[K, V]) apply(opts *options[K, V]) {

// options holds all available cache configuration options.
type options[K comparable, V any] struct {
capacity uint64
ttl time.Duration
loader Loader[K, V]
disableTouchOnHit bool
lockingDisabledForTransaction bool
capacity uint64
ttl time.Duration
loader Loader[K, V]
disableTouchOnHit bool
locklessWhileInTransaction bool
}

// applyOptions applies the provided option values to the option struct.
Expand Down
15 changes: 15 additions & 0 deletions vendor/github.com/davecgh/go-spew/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

145 changes: 145 additions & 0 deletions vendor/github.com/davecgh/go-spew/spew/bypass.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions vendor/github.com/davecgh/go-spew/spew/bypasssafe.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c90b6f3

Please sign in to comment.