# \[ANN\] Caching.jl, yet another memoizer with more features

**URL:** <https://discourse.julialang.org/t/ann-caching-jl-yet-another-memoizer-with-more-features/21565>\
**Category:** Package Announcements\
**Created:** [March 7, 2019, 11:18am UTC](https://discourse.julialang.org/t/ann-caching-jl-yet-another-memoizer-with-more-features/21565 "2019-03-07T11:18:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![zgornel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zgornel/32/217487_2.png) [@zgornel](https://discourse.julialang.org/u/zgornel)\
**Post date:** [March 7, 2019, 11:18am UTC](https://discourse.julialang.org/t/ann-caching-jl-yet-another-memoizer-with-more-features/21565/1 "2019-03-07T11:18:42Z")

</div>

[Caching.jl](https://github.com/zgornel/Caching.jl) aims to provide a simple non-intrusive memoization mechanism with disk, compression, record and size limits support. While it’s not the fastest, it should pretty easy to use, understand and extend. It is still lacking in the documentation area however the examples provided in the package page cover most of the functionality.

Just for the record, a list of memoization packages I encountered so far in the Julia ecosystem (lots of good ideas in all for whomever is interested):

- [Caching.jl (1)](https://github.com/zgornel/Caching.jl) - the package in question
- [Caching.jl (2)](https://github.com/sebastianpech/Caching.jl) - funny enough, there was another that covers similar functionalities with the same name
- [LRUCache.jl](https://github.com/JuliaCollections/LRUCache.jl)
- [Memoize.jl (1)](https://github.com/JuliaCollections/Memoize.jl)
- [Memoize.jl (2)](https://github.com/colinfang/Memoize.jl)
- [LocalMemoize.jl](https://github.com/sunoru/LocalMemoize.jl)
- [Anamnesis.jl](https://github.com/ExpandingMan/Anamnesis.jl)

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [March 9, 2019, 7:06am UTC](https://discourse.julialang.org/t/ann-caching-jl-yet-another-memoizer-with-more-features/21565/2 "2019-03-09T07:06:54Z")

</div>

When your cache is full, how do you decide which entry to throw out?

Do you throw out  
(1) Random entry  
(2) Least Recently Used entry  
(3) Oldest (by creation timestamp) entry

---

<div class="post-metadata">

**Author:** ![zgornel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zgornel/32/217487_2.png) [@zgornel](https://discourse.julialang.org/u/zgornel)\
**Post date:** [March 9, 2019, 10:04am UTC](https://discourse.julialang.org/t/ann-caching-jl-yet-another-memoizer-with-more-features/21565/3 "2019-03-09T10:04:38Z")

</div>

(3) but not by timestamp, simply by call order; the history is preserved in a `Deque`. It the cache is full, the deque’s head is popped 😉 (`/src/cache.jl`, `line 131`)

---

<div class="post-metadata">

**Author:** ![lucasilvalves](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucasilvalves/32/24433_2.png) [@lucasilvalves](https://discourse.julialang.org/u/lucasilvalves)\
**Post date:** [July 25, 2023, 6:08pm UTC](https://discourse.julialang.org/t/ann-caching-jl-yet-another-memoizer-with-more-features/21565/4 "2023-07-25T18:08:23Z")

</div>

Hey! First of all, congratulations, this is a pretty useful package! Yet, I’m still facing a problem when trying to use the caching to keep data on disk. I’m using this to store a specific variable I need to use in a [Dash app](https://dash.plotly.com/julia).

```julia
using Dash, Caching

app = dash()

app.layout = #some code here

cache = @cache mem = x::Int -> x "cache_file.bin"

callback!(
        app,
        Output("dummy", "children"),
        Input("dados", "data")
    ) do dado_usuario
        pesquisas = jsontable(dado_usuario) |> DataFrame

        # Taking the greatest value of variable id_pesquisa
        # and caching it
        cache(isa(maximum(pesquisas.id_pesquisa), MethodError) ? 0 : maximum(pesquisas.id_pesquisa))
        @persist! cache

        return 0
    end

@syncache! cache "disk"

# I just want the last value, so I take the last array's element
n = collect(values(cache.cache))[end]

# Do some stuff n times
for itr in 1:n
    ...
end

```

I know I may be getting something wrong about the scope of the variables, but I thought that as long as I synced the cache variable, it would not be a problem.

Any ideas on how can I use the caching correctly in this case?

---

<div class="post-metadata">

**Author:** ![zgornel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zgornel/32/217487_2.png) [@zgornel](https://discourse.julialang.org/u/zgornel)\
**Post date:** [July 25, 2023, 7:27pm UTC](https://discourse.julialang.org/t/ann-caching-jl-yet-another-memoizer-with-more-features/21565/5 "2023-07-25T19:27:02Z")

</div>

Hi, I am having a bit of trouble understanding your issue.

From what I can see in the code, collecting the values from `cache.cache` does not guarantee that the last value is the _last_ in any way (dictionaries are not ordered so, when collecting values, the order does not make any sense).

If you want the last value written you should

- store the last key (i.e. `cache` input argument), return it with `callback!` and call `cache(last_value);`  
or,
- more dangerously, load the value from the addresses specified in `cache.offsets` (if using just persist, the file just grows incremetally with each stored entry and the order of calls is implicitly preserved).
