Last active
May 11, 2018 06:58
-
-
Save bmishra/a0cb24c0f8f2b86ab17c2040b87de973 to your computer and use it in GitHub Desktop.
Revisions
-
Binayak Mishra revised this gist
May 11, 2018 . 1 changed file with 19 additions and 9 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -25,10 +25,17 @@ type cacheItem struct { // Error variables var ( ErrNoSuchKey = errors.New("No such cache item") ErrItemExpired = errors.New("Expired cache item") ) // commands const ( cmdGet = "GET" cmdSet = "SET" cmdExpire = "EXPIRE" ) // Cache simple in-memory cache type Cache struct{ requests chan request } @@ -42,28 +49,30 @@ func New() *Cache { // Get fetch a value from cache, returns error if key is missing func (c *Cache) Get(key string) (interface{}, error) { response := make(chan result) c.requests <- request{cmdGet, key, nil, 0, response} res := <-response return res.value, res.err } // Set sets a key value pair into the cache func (c *Cache) Set(key string, val interface{}, ttl int64) (interface{}, error) { response := make(chan result) c.requests <- request{cmdSet, key, val, ttl, response} res := <-response return res.value, res.err } // Expire remove an item from cache func (c *Cache) Expire(key string) { response := make(chan result) c.requests <- request{cmdExpire, key, nil, 0, response} } func (c *Cache) server() { cache := make(map[string]interface{}) for req := range c.requests { switch req.cmd { case cmdSet: item := cacheItem{ value: req.val, } @@ -73,17 +82,18 @@ func (c *Cache) server() { } cache[req.key] = item req.response <- result{1, nil} case cmdGet: e := cache[req.key] if e == nil { req.response <- result{nil, ErrNoSuchKey} } else if e.(cacheItem).expiry > 0 && time.Now().Unix() > e.(cacheItem).expiry { req.response <- result{nil, ErrItemExpired} c.Expire(req.key) } else { req.response <- result{e.(cacheItem).value, nil} } case cmdExpire: e := cache[req.key] if e != nil { delete(cache, req.key) -
Binayak Mishra created this gist
May 9, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,93 @@ package cache import ( "errors" "time" ) type request struct { cmd string key string val interface{} ttl int64 // seconds response chan<- result } type result struct { value interface{} err error } type cacheItem struct { value interface{} expiry int64 } // Error variables var ( ErrNoSuchKey = errors.New("No such key") ErrItemExpired = errors.New("Expired cache item") ) // Cache simple in-memory cache type Cache struct{ requests chan request } // New init new Cache func New() *Cache { cache := &Cache{requests: make(chan request)} go cache.server() return cache } // Get fetch a value from cache, returns error if key is missing func (c *Cache) Get(key string) (interface{}, error) { response := make(chan result) c.requests <- request{"GET", key, nil, 0, response} res := <-response return res.value, res.err } // Set sets a key value pair into the cache func (c *Cache) Set(key string, val interface{}, ttl int64) { response := make(chan result) c.requests <- request{"SET", key, val, ttl, response} } // Expire remove an item from cache func (c *Cache) Expire(key string) { response := make(chan result) c.requests <- request{"EXPIRE", key, nil, 0, response} } func (c *Cache) server() { cache := make(map[string]interface{}) for req := range c.requests { switch req.cmd { case "SET": item := cacheItem{ value: req.val, } if req.ttl > 0 { item.expiry = time.Now().Unix() + req.ttl } cache[req.key] = item case "GET": e := cache[req.key] if e == nil { req.response <- result{nil, ErrNoSuchKey} } else if e.(cacheItem).expiry > 0 && time.Now().Unix() > e.(cacheItem).expiry { req.response <- result{nil, ErrItemExpired} delete(cache, req.key) } else { req.response <- result{e.(cacheItem).value, nil} } case "EXPIRE": e := cache[req.key] if e != nil { delete(cache, req.key) } } } }