LRUCache.jl icon indicating copy to clipboard operation
LRUCache.jl copied to clipboard

A type `TTLCache` may be helpful dealing with network stuffs

Open hammerfunctor opened this issue 4 years ago • 3 comments

I found it in python package cachetools, and it seems not that hard to implement it.

hammerfunctor avatar Mar 24 '21 16:03 hammerfunctor

I did not know about this, but indeed, that would be feasible. As is often the case, the interface might be the hardest part. How would you propose to set the lifetime of objects that are added to the cache via the various operations (setindex!, get!, push!, …)

Jutho avatar Mar 24 '21 16:03 Jutho

I did not know about this, but indeed, that would be feasible. As is often the case, the interface might be the hardest part. How would you propose to set the lifetime of objects that are added to the cache via the various operations (setindex!, get!, push!, …)

Like this:

struct TTLCache{K,V}
  ttl::TimePeriod
  cache::LRU{K,Tuple{TimePeriod,V}}
  TTLCache{K,V}(ttl)=new(ttl,LRU{K,Tuple{TimePeriod,V}}())
end
utime() = unix2timedate(time())
setindex!(ttlcache::TTLCache, k, v) = setindex!(ttlcache.cache,k,(utime(),v))
function get!(ttlcache::TTLCache,k,v)
  cache = getfield(ttlcache,:cache)
  if haskey(cache,k) && utime()-(ptimeAndCache=get(cache,k))[1]<ttlcache.ttl
    return ptimeAndCache[2]
  else
    setindex!(cache,k,(utime(),v))
    return v
  end
end

Hope this impl is not too bad

hammerfunctor avatar Mar 25 '21 01:03 hammerfunctor

I've done some jobs, now the code works as I want


using LRUCache
import LRUCache: get!
using Dates
utime() = unix2datetime(time())

mutable struct TValue{V}
  t::DateTime
  v::V
end
struct TTLCache{K,V}
  ttl:: TimePeriod
  cache:: LRU{K,TValue{V}}
  TTLCache(t::TimePeriod,m::Int64,::Type{K},::Type{V}) where{K,V} = new{K,V}(
    t,
    LRU{K,TValue{V}}(maxsize=m)
  )
end

function get!(ttlcache::TTLCache,k,v)
  cache = getfield(ttlcache,:cache)
  if haskey(cache,k)
    tv = getindex(cache,k)
    if utime()-getfield(tv,:t)<getfield(ttlcache,:ttl)
      return getfield(tv,:v)
    end
  end
  getfield(get!(cache,k,TValue(utime(),v)), :v)
end

function get!(f::Function,ttlcache::TTLCache,k)
  cache = getfield(ttlcache,:cache)
  if haskey(cache,k)
    tv = getindex(cache,k)
    if utime()-getfield(tv,:t)<getfield(ttlcache,:ttl)
      return getfield(tv,:v)
    end
  end
  getfield(get!(cache,k,TValue(utime(),f())), :v)
end

const lru = TTLCache(Second(5),3,Int64,String)
function foo()
  println("running")
  "dsad"
end
function foo_cache(x::Int64)
  get!(lru, x) do
    foo()
  end
end

hammerfunctor avatar Mar 25 '21 05:03 hammerfunctor