Skip to content

Commit

Permalink
decreasing time accuracy for memory efficient
Browse files Browse the repository at this point in the history
  • Loading branch information
phuslu committed Jan 3, 2024
1 parent 700b76b commit 5cb1c19
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 33 deletions.
32 changes: 16 additions & 16 deletions cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,6 @@ func TestCacheEviction(t *testing.T) {
}
}

func TestCacheTouchGet(t *testing.T) {
l := newWithShards[string, int](1, 256)

l.SetWithTTL("foobar", 42, 400*time.Millisecond)

time.Sleep(200 * time.Millisecond)
if v, ok := l.TouchGet("foobar"); !ok || v != 42 {
t.Errorf("foobar should be set to 42: %v,", v)
}

time.Sleep(300 * time.Millisecond)
if v, ok := l.Get("foobar"); !ok || v != 42 {
t.Errorf("foobar should be still set to 42: %v,", v)
}
}

func TestCachePeek(t *testing.T) {
l := New[int, int](64)

Expand Down Expand Up @@ -136,6 +120,22 @@ func TestCachePeek(t *testing.T) {
}
}

func TestCacheTouchGet(t *testing.T) {
l := newWithShards[string, int](1, 256)

l.SetWithTTL("foobar", 42, 3*time.Second)

time.Sleep(2 * time.Second)
if v, ok := l.TouchGet("foobar"); !ok || v != 42 {
t.Errorf("foobar should be set to 42: %v,", v)
}

time.Sleep(2 * time.Second)
if v, ok := l.Get("foobar"); !ok || v != 42 {
t.Errorf("foobar should be still set to 42: %v,", v)
}
}

func BenchmarkCacheRand(b *testing.B) {
l := New[int64, int64](8192)

Expand Down
4 changes: 2 additions & 2 deletions list.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ package lru
type node[K comparable, V any] struct {
key K
value V
expires int64
ttl int64
expires uint32
ttl uint32
next uint32
prev uint32
}
Expand Down
27 changes: 12 additions & 15 deletions shard.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (s *shard[K, V]) Get(hash uint32, key K) (value V, ok bool) {
s.mu.Lock()

if index, exists := s.table.Get(hash, key); exists {
if expires := s.list.nodes[index].expires; expires == 0 || atomic.LoadInt64(&clock) < expires {
if expires := s.list.nodes[index].expires; expires == 0 || atomic.LoadUint32(&clock) < expires {
s.list.MoveToFront(index)
value = s.list.nodes[index].value
ok = true
Expand All @@ -46,9 +46,9 @@ func (s *shard[K, V]) TouchGet(hash uint32, key K) (value V, ok bool) {
s.list.MoveToFront(index)
value = s.list.nodes[index].value
ok = true
} else if now := atomic.LoadInt64(&clock); now < expires {
} else if now := atomic.LoadUint32(&clock); now < expires {
s.list.MoveToFront(index)
s.list.nodes[index].expires = atomic.LoadInt64(&clock) + s.list.nodes[index].ttl
s.list.nodes[index].expires = atomic.LoadUint32(&clock) + s.list.nodes[index].ttl
value = s.list.nodes[index].value
ok = true
} else {
Expand Down Expand Up @@ -86,8 +86,8 @@ func (s *shard[K, V]) Set(hash uint32, hashfun func(K) uint64, key K, value V, t
s.list.MoveToFront(index)
node.value = value
if ttl > 0 {
node.ttl = int64(ttl)
node.expires = atomic.LoadInt64(&clock) + int64(ttl)
node.ttl = uint32(ttl / time.Second)
node.expires = atomic.LoadUint32(&clock) + node.ttl
}
prev = previousValue
replaced = true
Expand All @@ -102,8 +102,8 @@ func (s *shard[K, V]) Set(hash uint32, hashfun func(K) uint64, key K, value V, t
node.key = key
node.value = value
if ttl > 0 {
node.ttl = int64(ttl)
node.expires = atomic.LoadInt64(&clock) + int64(ttl)
node.ttl = uint32(ttl / time.Second)
node.expires = atomic.LoadUint32(&clock) + node.ttl
}
s.table.Set(hash, key, index)
s.list.MoveToFront(index)
Expand Down Expand Up @@ -148,18 +148,15 @@ func newshard[K comparable, V any](size int) *shard[K, V] {
return s
}

var clock int64
var clock uint32

func init() {
atomic.StoreInt64(&clock, time.Now().UnixNano())
const unixBase = 1704067200 // 2024-01-01T00:00:00Z
atomic.StoreUint32(&clock, uint32(time.Now().Unix()-unixBase))
go func() {
for {
for i := 0; i < 9; i++ {
time.Sleep(100 * time.Millisecond)
atomic.AddInt64(&clock, int64(100*time.Millisecond))
}
time.Sleep(100 * time.Millisecond)
atomic.StoreInt64(&clock, time.Now().UnixNano())
time.Sleep(500 * time.Millisecond)
atomic.StoreUint32(&clock, uint32(time.Now().Unix()-unixBase))
}
}()
}
Expand Down

0 comments on commit 5cb1c19

Please sign in to comment.