defers removed

This commit is contained in:
paddlesteamer 2020-07-30 17:13:55 +03:00
parent 6c67620aac
commit bf13e85b5e
1 changed files with 24 additions and 9 deletions

View File

@ -19,11 +19,13 @@ type Item struct {
// Returns true if the item has expired. // Returns true if the item has expired.
func (item *Item) Expired() bool { func (item *Item) Expired() bool {
item.mu.RLock() item.mu.RLock()
defer item.mu.RUnlock()
if item.Expiration == 0 { if item.Expiration == 0 {
item.mu.RUnlock()
return false return false
} }
item.mu.RUnlock()
return time.Now().UnixNano() > item.Expiration return time.Now().UnixNano() > item.Expiration
} }
@ -123,18 +125,20 @@ func (c *cache) Replace(k string, x interface{}, d time.Duration) error {
// whether the key was found. // whether the key was found.
func (c *cache) Get(k string) (interface{}, bool) { func (c *cache) Get(k string) (interface{}, bool) {
c.mu.RLock() c.mu.RLock()
defer c.mu.RUnlock()
// "Inlining" of get and Expired // "Inlining" of get and Expired
item, found := c.items[k] item, found := c.items[k]
if !found { if !found {
c.mu.RUnlock()
return nil, false return nil, false
} }
if item.Expired() { if item.Expired() {
c.mu.RUnlock()
return nil, false return nil, false
} }
c.mu.RUnlock()
return item.Object, true return item.Object, true
} }
@ -144,23 +148,26 @@ func (c *cache) Get(k string) (interface{}, bool) {
// whether the key was found. // whether the key was found.
func (c *cache) GetWithExpiration(k string) (interface{}, time.Time, bool) { func (c *cache) GetWithExpiration(k string) (interface{}, time.Time, bool) {
c.mu.RLock() c.mu.RLock()
defer c.mu.RUnlock()
// "Inlining" of get and Expired // "Inlining" of get and Expired
item, found := c.items[k] item, found := c.items[k]
if !found { if !found {
c.mu.RUnlock()
return nil, time.Time{}, false return nil, time.Time{}, false
} }
item.mu.RLock() item.mu.RLock()
defer item.mu.RUnlock()
if item.Expiration > 0 { if item.Expiration > 0 {
if time.Now().UnixNano() > item.Expiration { if time.Now().UnixNano() > item.Expiration {
item.mu.RUnlock()
c.mu.RUnlock()
return nil, time.Time{}, false return nil, time.Time{}, false
} }
// Return the item and the expiration time // Return the item and the expiration time
item.mu.RUnlock()
c.mu.RUnlock()
return item.Object, time.Unix(0, item.Expiration), true return item.Object, time.Unix(0, item.Expiration), true
} }
@ -175,20 +182,21 @@ func (c *cache) GetWithExpiration(k string) (interface{}, time.Time, bool) {
// whether the key was found. // whether the key was found.
func (c *cache) GetWithExpirationUpdate(k string, d time.Duration) (interface{}, bool) { func (c *cache) GetWithExpirationUpdate(k string, d time.Duration) (interface{}, bool) {
c.mu.RLock() c.mu.RLock()
defer c.mu.RUnlock()
item, found := c.items[k] item, found := c.items[k]
if !found { if !found {
c.mu.RUnlock()
return nil, false return nil, false
} }
// Don't call item.Expired() here since // Don't call item.Expired() here since
// we write lock item.Expiration // we write lock item.Expiration
item.mu.Lock() item.mu.Lock()
defer item.mu.Unlock()
if item.Expiration > 0 { if item.Expiration > 0 {
if time.Now().UnixNano() > item.Expiration { if time.Now().UnixNano() > item.Expiration {
item.mu.Unlock()
c.mu.RUnlock()
return nil, false return nil, false
} }
} }
@ -200,6 +208,8 @@ func (c *cache) GetWithExpirationUpdate(k string, d time.Duration) (interface{},
c.items[k].Expiration = time.Now().Add(d).UnixNano() c.items[k].Expiration = time.Now().Add(d).UnixNano()
} }
item.mu.Unlock()
c.mu.RUnlock()
return item.Object, true return item.Object, true
} }
@ -1005,11 +1015,13 @@ func (c *cache) Save(w io.Writer) (err error) {
} }
}() }()
c.mu.RLock() c.mu.RLock()
defer c.mu.RUnlock()
for _, v := range c.items { for _, v := range c.items {
gob.Register(v.Object) gob.Register(v.Object)
} }
err = enc.Encode(&c.items) err = enc.Encode(&c.items)
c.mu.RUnlock()
return return
} }
@ -1042,7 +1054,7 @@ func (c *cache) Load(r io.Reader) error {
err := dec.Decode(&items) err := dec.Decode(&items)
if err == nil { if err == nil {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock()
for k, v := range items { for k, v := range items {
ov, found := c.items[k] ov, found := c.items[k]
if !found || ov.Expired() { if !found || ov.Expired() {
@ -1050,6 +1062,7 @@ func (c *cache) Load(r io.Reader) error {
} }
} }
} }
c.mu.Unlock()
return err return err
} }
@ -1074,7 +1087,7 @@ func (c *cache) LoadFile(fname string) error {
// Copies all unexpired items in the cache into a new map and returns it. // Copies all unexpired items in the cache into a new map and returns it.
func (c *cache) Items() map[string]*Item { func (c *cache) Items() map[string]*Item {
c.mu.RLock() c.mu.RLock()
defer c.mu.RUnlock()
m := make(map[string]*Item, len(c.items)) m := make(map[string]*Item, len(c.items))
for k, v := range c.items { for k, v := range c.items {
// "Inlining" of Expired // "Inlining" of Expired
@ -1086,6 +1099,8 @@ func (c *cache) Items() map[string]*Item {
Expiration: v.Expiration, Expiration: v.Expiration,
} }
} }
c.mu.RUnlock()
return m return m
} }