diff --git a/.travis.yml b/.travis.yml index c8b80d3..6a07755 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ os: - linux - osx julia: - - 1.1 + - 1.2 - 1.5 notifications: email: false diff --git a/README.md b/README.md index 27c1ca5..09201cd 100644 --- a/README.md +++ b/README.md @@ -10,17 +10,31 @@ Easy memoization for Julia. using Memoize @memoize function x(a) println("Running") - a + 2a end ``` ``` julia> x(1) Running -1 +2 + +julia> memoize_cache(x) +IdDict{Any,Any} with 1 entry: + (1,) => 2 + +julia> x(1) +2 + +julia> empty!(memoize_cache(x)) +IdDict{Any,Any}() + +julia> x(1) +Running +2 julia> x(1) -1 +2 ``` By default, Memoize.jl uses an [`IdDict`](https://docs.julialang.org/en/v1/base/collections/#Base.IdDict) as a cache, but it's also possible to specify the type of the cache. If you want to cache vectors based on the values they contain, you probably want this: @@ -33,7 +47,7 @@ using Memoize end ``` -You can also specify the full function call for constructing the dictionary. For example, to use LRUCache.jl: +You can also specify the full function call for constructing the dictionary. For example, to use LRUCache.jl: ```julia using Memoize diff --git a/src/Memoize.jl b/src/Memoize.jl index d6d7098..6406c58 100644 --- a/src/Memoize.jl +++ b/src/Memoize.jl @@ -1,6 +1,8 @@ module Memoize using MacroTools: isexpr, combinedef, namify, splitarg, splitdef -export @memoize +export @memoize, memoize_cache + +cache_name(f) = Symbol("##", f, "_memoized_cache") macro memoize(args...) if length(args) == 1 @@ -49,7 +51,7 @@ macro memoize(args...) end end - fcachename = Symbol("##", f, "_memoized_cache") + fcachename = cache_name(f) mod = __module__ fcache = isdefined(mod, fcachename) ? getfield(mod, fcachename) : @@ -76,4 +78,12 @@ macro memoize(args...) end) end + +function memoize_cache(f::Function) + # This will fail in certain circumstances (eg. @memoize Base.sin(::MyNumberType) = ...) but I don't think there's + # a clean answer here, because we can already have multiple caches for certain functions, if the methods are + # defined in different modules. + getproperty(parentmodule(f), cache_name(f)) +end + end diff --git a/test/runtests.jl b/test/runtests.jl index 2604d0d..d9639ed 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -29,6 +29,12 @@ end @test simple(6) == 6 @test run == 2 +empty!(memoize_cache(simple)) +@test simple(6) == 6 +@test run == 3 +@test simple(6) == 6 +@test run == 3 + run = 0 @memoize function typed(a::Int) global run += 1 @@ -295,7 +301,6 @@ end @test vararg_func((1,1), (1,2)) == (1,1) @test run == 2 - module MemoizeTest using Test using Memoize @@ -318,7 +323,20 @@ end @test custom_dict(1) == 1 @test run == 2 -end +end # module + +using .MemoizeTest +using .MemoizeTest: custom_dict + +empty!(memoize_cache(custom_dict)) +@test custom_dict(1) == 1 +@test MemoizeTest.run == 3 +@test custom_dict(1) == 1 +@test MemoizeTest.run == 3 + +empty!(memoize_cache(MemoizeTest.custom_dict)) +@test custom_dict(1) == 1 +@test MemoizeTest.run == 4 run = 0 @memoize Dict{Tuple{String},Int}() function dict_call(a::String)::Int @@ -333,3 +351,4 @@ end @test run == 2 @test dict_call("bb") == 2 @test run == 2 +