Skip to content

Commit

Permalink
refactor: metrics initialization changes
Browse files Browse the repository at this point in the history
Instead of initializing the metrics structure and working with it directly, I decided to create the metrics interface with two main implementations.
First one is realMetrics that would be working only if metrics enabled and gathers metrics information.
And another one is noMetrics, which is dummy implemenation and does nothing serious.
The refactoring is being made with the goal of removing checking for nil variable constantly.
  • Loading branch information
WIttyJudge committed Mar 10, 2024
1 parent 3e72185 commit 146cc30
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 48 deletions.
46 changes: 13 additions & 33 deletions incache.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type Cache struct {
eventHandlers *eventHandlers

config Config
metrics *metrics
metrics metrics
}

// New creates new instance of the cache.
Expand All @@ -46,7 +46,11 @@ func New(conf ...configFunc) *Cache {
eventHandlers: newEventHandlers(),

config: config,
metrics: newMetrics(),
metrics: newNoMetrics(),
}

if config.enableMetrics {
cache.metrics = newRealMetrics()
}

if config.cleanupInterval > 0 {
Expand Down Expand Up @@ -232,7 +236,7 @@ func (c *Cache) Has(key string) bool {
}

// Metrics returns collected cache metrics.
func (c *Cache) Metrics() *metrics {
func (c *Cache) Metrics() metrics {
c.mu.RLock()
defer c.mu.RUnlock()

Expand All @@ -244,7 +248,7 @@ func (c *Cache) ResetMetrics() {
c.mu.Lock()
defer c.mu.Unlock()

*c.metrics = *newMetrics()
c.metrics.reset()
}

func (c *Cache) OnInsertion(fn func(key string, value interface{})) {
Expand All @@ -270,7 +274,7 @@ func (c *Cache) set(key string, value interface{}, ttl time.Duration) {

c.config.debugf("[set] key: '%s', item: %+v", key, item)

c.metricsIncrInsertions()
c.metrics.incrementInsertions()
}

func (c *Cache) get(key string) interface{} {
Expand All @@ -283,18 +287,18 @@ func (c *Cache) get(key string) interface{} {
if value == nil {
c.config.debugf("[get] no value was found for the key: '%s'", key)

c.metricsIncrMisses()
c.metrics.incrementMisses()
return nil
}

if item.Expired() {
c.config.debugf("[get] received value for the key: '%s' is expired", key)

c.metricsIncrMisses()
c.metrics.incrementMisses()
return nil
}

c.metricsIncrHits()
c.metrics.incrementHits()

c.config.debugf("[get] key: '%s', value: %+v", key, value)

Expand All @@ -312,29 +316,5 @@ func (c *Cache) evict(key string) {
delete(c.expirationsQueue, key)

c.config.debugf("[evict] key: '%s'", key)
c.metricsIncrEvictions()
}

func (c *Cache) metricsIncrInsertions() {
if c.config.enableMetrics {
c.metrics.incrInsertions()
}
}

func (c *Cache) metricsIncrHits() {
if c.config.enableMetrics {
c.metrics.incrHits()
}
}

func (c *Cache) metricsIncrMisses() {
if c.config.enableMetrics {
c.metrics.incrMisses()
}
}

func (c *Cache) metricsIncrEvictions() {
if c.config.enableMetrics {
c.metrics.incrEvictions()
}
c.metrics.incrementEvictions()
}
14 changes: 14 additions & 0 deletions incache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,20 @@ func TestMetrics(t *testing.T) {
assert.EqualValues(t, 1, metrics.Evictions())
}

func TestNoMetricsType(t *testing.T) {
cache := New()
metrics := cache.Metrics()

assert.IsType(t, &noMetrics{}, metrics)
}

func TestRealMetricsType(t *testing.T) {
cache := New(WithMetrics())
metrics := cache.Metrics()

assert.IsType(t, &realMetrics{}, metrics)
}

func TestResetMetrics(t *testing.T) {
cache := New(WithMetrics())
metrics := cache.Metrics()
Expand Down
68 changes: 53 additions & 15 deletions metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,22 @@ package incache

import "sync/atomic"

type metrics interface {
Insertions() uint64
Hits() uint64
Misses() uint64
Evictions() uint64

reset()

incrementInsertions()
incrementHits()
incrementMisses()
incrementEvictions()
}

// Metrics stores cache statistics
type metrics struct {
type realMetrics struct {
// Shows how many times items were inserted into cache.
insertions uint64

Expand All @@ -17,42 +31,66 @@ type metrics struct {
evictions uint64
}

func newMetrics() *metrics {
return &metrics{}
func newRealMetrics() *realMetrics {
return &realMetrics{}
}

// Get collected insertions.
func (m *metrics) Insertions() uint64 {
func (m *realMetrics) Insertions() uint64 {
return atomic.LoadUint64(&m.insertions)
}

// Get collected hits.
func (m *metrics) Hits() uint64 {
func (m *realMetrics) Hits() uint64 {
return atomic.LoadUint64(&m.hits)
}

// Get collected misses.
func (m *metrics) Misses() uint64 {
func (m *realMetrics) Misses() uint64 {
return atomic.LoadUint64(&m.misses)
}

// Get collected evictions.
func (m *metrics) Evictions() uint64 {
func (m *realMetrics) Evictions() uint64 {
return atomic.LoadUint64(&m.evictions)
}

func (m *metrics) incrInsertions() {
atomic.AddUint64(&m.insertions, 1)
func (m *realMetrics) reset() {
m.insertions = 0
m.hits = 0
m.misses = 0
m.evictions = 0
}

func (m *realMetrics) incrementInsertions() {
m.insertions += 1
}

func (m *metrics) incrHits() {
atomic.AddUint64(&m.hits, 1)
func (m *realMetrics) incrementHits() {
m.hits += 1
}

func (m *metrics) incrMisses() {
atomic.AddUint64(&m.misses, 1)
func (m *realMetrics) incrementMisses() {
m.misses += 1
}

func (m *metrics) incrEvictions() {
atomic.AddUint64(&m.evictions, 1)
func (m *realMetrics) incrementEvictions() {
m.evictions += 1
}

// Dummy metrics implementation that is used if metrics is disabled.
type noMetrics struct{}

func newNoMetrics() *noMetrics { return &noMetrics{} }

func (m *noMetrics) Insertions() uint64 { return 0 }
func (m *noMetrics) Hits() uint64 { return 0 }
func (m *noMetrics) Misses() uint64 { return 0 }
func (m *noMetrics) Evictions() uint64 { return 0 }

func (m *noMetrics) reset() {}

func (m *noMetrics) incrementInsertions() {}
func (m *noMetrics) incrementHits() {}
func (m *noMetrics) incrementMisses() {}
func (m *noMetrics) incrementEvictions() {}

0 comments on commit 146cc30

Please sign in to comment.