JuliaCollections / LRUCache.jl

An implementation of an LRU Cache in Julia
Other
56 stars 23 forks source link

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

Open hammerfunctor opened 3 years ago

hammerfunctor commented 3 years ago

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

Jutho commented 3 years ago

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!, …)

hammerfunctor commented 3 years ago

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 commented 3 years ago

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