Skip to content

Commit

Permalink
Init commit of the simple ttl cache
Browse files Browse the repository at this point in the history
  • Loading branch information
DevGuyOps committed Mar 28, 2021
0 parents commit 224689e
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 0 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Simple TTL Cache
The Simple TTL Cache is an in memory cache with a set expiration time (TTL).

# Usage
```go
package main

import (
"time"

simplettlcache "github.com/GuySWatson/simple-ttl-cache"
)

func main() {
// Setup
simpleTTLCache := simplettlcache.SimpleTTLCache{}
simpleTTLCache.Init(time.Second * 3)

// Put object into cache
simpleTTLCache.Put("color", "red")

// Get object out of cache
simpleTTLCache.Get("color")

// Update object in the cache
simpleTTLCache.Update("color", 1234)
}
```
78 changes: 78 additions & 0 deletions cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package simplettlcache

import (
"sync"
"time"
)

type SimpleTTLCache struct {
assets map[string]*simpleTTLItem
mutex sync.Mutex
}

type simpleTTLItem struct {
value interface{}
lastAccess time.Time
}

func (s *SimpleTTLCache) Init(maxTTL time.Duration) {
s.assets = make(map[string]*simpleTTLItem)

go func() {
for now := range time.Tick(time.Second) {
s.mutex.Lock()

for k, v := range s.assets {
if now.Sub(v.lastAccess) > maxTTL {
delete(s.assets, k)
}
}

s.mutex.Unlock()
}
}()
}

func (s *SimpleTTLCache) Len() int {
return len(s.assets)
}

func (s *SimpleTTLCache) Put(k string, value interface{}) {
s.mutex.Lock()

item, ok := s.assets[k]
if !ok {
item = &simpleTTLItem{
value: value,
}
s.assets[k] = item
}

item.lastAccess = time.Now()

s.mutex.Unlock()
}

func (s *SimpleTTLCache) Get(k string) (v interface{}) {
s.mutex.Lock()

if item, ok := s.assets[k]; ok {
v = item.value
item.lastAccess = time.Now()
}

s.mutex.Unlock()
return
}

func (s *SimpleTTLCache) Update(k string, value interface{}) {
s.mutex.Lock()

item, ok := s.assets[k]
if ok {
item.value = value
item.lastAccess = time.Now()
}

s.mutex.Unlock()
}
60 changes: 60 additions & 0 deletions cache_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package simplettlcache

import (
"testing"
"time"
)

func TestSimpleTTLCache(t *testing.T) {
key := "a1"

// Setup cache for test
simpleTTLCache := SimpleTTLCache{}
simpleTTLCache.Init(time.Second * 3)

// Put item in cache and check it exists
simpleTTLCache.Put(key, "red")
if simpleTTLCache.Get(key) != "red" {
t.Error("Item missing from cache")
}

// Sleep to test TTL works
time.Sleep(time.Second * 4)
if simpleTTLCache.Get(key) != nil {
t.Error("Should be empty")
}
}

func TestSimpleTTLCacheLen(t *testing.T) {
key := "b2"

// Setup cache for test
simpleTTLCache := SimpleTTLCache{}
simpleTTLCache.Init(time.Second * 3)

// Put item in cache and check length
simpleTTLCache.Put(key, "apple")
if simpleTTLCache.Len() != 1 {
t.Error("Len of cache is wrong")
}
}

func TestSimpleTTLCacheUpdate(t *testing.T) {
key := "b2"

// Setup cache for test
simpleTTLCache := SimpleTTLCache{}
simpleTTLCache.Init(time.Second * 3)

// Put item in cache and check it exists
simpleTTLCache.Put(key, "apple")
if simpleTTLCache.Get(key) != "apple" {
t.Error("Item missing from cache")
}

// Update item in cache and check it changed
simpleTTLCache.Update(key, "banana")
if simpleTTLCache.Get(key) != "banana" {
t.Error("Item update failed")
}
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/GuySWatson/simple-ttl-cache

go 1.15

0 comments on commit 224689e

Please sign in to comment.