Skip to content

Commit

Permalink
addressing review comments
Browse files Browse the repository at this point in the history
Signed-off-by: Soule BA <[email protected]>
  • Loading branch information
souleb committed Jun 12, 2024
1 parent a1b16b1 commit eae3ead
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 11 deletions.
8 changes: 4 additions & 4 deletions cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ func (c *cache[T]) get(key string) (T, bool, error) {
recordRequest(c.metrics, StatusSuccess)
return res, false, nil
}
if item.expiresAt.UnixNano() > 0 {
if !item.expiresAt.IsZero() {
if item.expiresAt.Compare(time.Now()) < 0 {
c.mu.RUnlock()
recordRequest(c.metrics, StatusSuccess)
Expand Down Expand Up @@ -430,7 +430,7 @@ func (c *Cache[T]) GetExpiration(object T) (time.Time, error) {
recordRequest(c.metrics, StatusSuccess)
return time.Time{}, KeyError{object, ErrNotFound}
}
if item.expiresAt.UnixNano() > 0 {
if !item.expiresAt.IsZero() {
if item.expiresAt.Compare(time.Now()) < 0 {
c.mu.RUnlock()
recordRequest(c.metrics, StatusSuccess)
Expand Down Expand Up @@ -459,10 +459,10 @@ func (c *cache[T]) deleteExpired() {
c.sorted = true
}

t := time.Now().UnixNano()
t := time.Now()
index := sort.Search(len(c.items), func(i int) bool {
// smallest index with an expiration greater than t
return c.items[i].expiresAt.UnixNano() > t
return c.items[i].expiresAt.Compare(t) > 0
})

// delete the expired indexes
Expand Down
17 changes: 10 additions & 7 deletions cache/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ limitations under the License.

package cache

import "fmt"
import (
"errors"
"fmt"
)

var (
// ErrNotFound is returned when an item is not found in the cache.
ErrNotFound = fmt.Errorf("not found")
ErrAlreadyExists = fmt.Errorf("already exists")
ErrClosed = fmt.Errorf("cache closed")
ErrFull = fmt.Errorf("cache full")
ErrExpired = fmt.Errorf("key has expired")
ErrNoRegisterer = fmt.Errorf("no prometheus registerer provided")
ErrNotFound = errors.New("not found")
ErrAlreadyExists = errors.New("already exists")
ErrClosed = errors.New("cache closed")
ErrFull = errors.New("cache full")
ErrExpired = errors.New("key has expired")
ErrNoRegisterer = errors.New("no prometheus registerer provided")
)

// KeyError will be returned any time a KeyFunc gives an error; it includes the object
Expand Down
21 changes: 21 additions & 0 deletions cache/lru.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,26 @@ func (n *node[T]) addPrev(node *node[T]) {
// All methods are safe for concurrent use.
// All operations are O(1). The hash map lookup is O(1) and so is the doubly
// linked list insertion/deletion.
//
// The LRU is implemented as a doubly linked list, where the most recently accessed
// item is at the front of the list and the least recently accessed item is at
// the back. When an item is accessed, it is moved to the front of the list.
// When the cache is full, the least recently accessed item is removed from the
// back of the list.
//
// Cache
// ┌───────────────────────────────────────────────────┐
// │ │
// empty │ obj obj obj obj │ empty
// ┌───────┐ │ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │ ┌───────┐
// │ │ │ │ │ │ │ ... │ │ │ │ │ │ │
// │ HEAD │◄─┼─►│ │◄─►│ │◄───►│ │◄─►│ │◄─┼─►│ TAIL │
// │ │ │ │ │ │ │ │ │ │ │ │ │ │
// └───────┘ │ └───────┘ └───────┘ └───────┘ └───────┘ │ └───────┘
// │ │
// │ │
// └───────────────────────────────────────────────────┘
//
// A function to extract the key from the object must be provided.
// Use the NewLRU function to create a new cache that is ready to use.
type LRU[T any] struct {
Expand Down Expand Up @@ -165,6 +185,7 @@ func (c *LRU[T]) Delete(object T) error {

func (c *LRU[T]) delete(node *node[T]) {
node.prev.next, node.next.prev = node.next, node.prev
node.next, node.prev = nil, nil // avoid memory leaks
delete(c.cache, node.key)
}

Expand Down

0 comments on commit eae3ead

Please sign in to comment.