1

Suppose the following example:

library(xfun)
cp <- tempdir()
g <- function(x) x %% 2L

for(x in 1:2) {
  i <- cache_rds(g(x), file = "my_cache.rds", dir = paste0(cp, "/"), hash = list(x))
  print(list.files(cp, pattern = "my_cache.*\\.rds$"))
}
## Cache invalidated because x changes
# [1] "my_cache_f943c721ec5f66ac177ff5e146dc3f20.rds"
# [1] "my_cache_8d5bfb3a0b52e4a1e370feefa397cdea.rds"

## Cache stable if x does not change
i <- cache_rds(g(x), file = "my_cache.rds", dir = paste0(cp, "/"), hash = list(x))
print(list.files(cp, pattern = "my_cache.*\\.rds$"))
# [1] "my_cache_8d5bfb3a0b52e4a1e370feefa397cdea.rds"

## if we change definiton of g cache is not invalidated
g <- function(x) x + 1
i <- cache_rds(g(x), file = "my_cache.rds", dir = paste0(cp, "/"), hash = list(x))
print(list.files(cp, pattern = "my_cache.*\\.rds$"))
# [1] "my_cache_8d5bfb3a0b52e4a1e370feefa397cdea.rds"

## thus we need to add it to the hash
i <- cache_rds(g(x), file = "my_cache.rds", dir = paste0(cp, "/"), hash = list(x, g))
print(list.files(cp, pattern = "my_cache.*\\.rds$"))
# [1] "my_cache_6f873e4f042ac7d6879224ed9310af1b.rds"

## but now it changes every(!) time
i <- cache_rds(g(x), file = "my_cache.rds", dir = paste0(cp, "/"), hash = list(x, g))
print(list.files(cp, pattern = "my_cache.*\\.rds$"))
# [1] "my_cache_9b179bd66c0e8fe8f1194d62f2c2bafb.rds"

I am trying to make the invalidation of the cache depending on the definition of the external function g. Thus, I need to include it in the hash argument, but this causes the hash to invalidate with every call.

The only idea I have is to use deparse(g) to take a dependency on the code of g which works as expected:

i <- cache_rds(g(x), file = "my_cache.rds", dir = paste0(cp, "/"), 
   hash = list(x, deparse(g)))
print(list.files(cp, pattern = "my_cache.*\\.rds$"))
# [1] "my_cache_e33367d1a6af1356010fe6a24bcbe563.rds"

i <- cache_rds(g(x), file = "my_cache.rds", dir = paste0(cp, "/"), 
   hash = list(x, deparse(g)))
print(list.files(cp, pattern = "my_cache.*\\.rds$"))
# [1] "my_cache_e33367d1a6af1356010fe6a24bcbe563.rds"

g <- function(x) {
  x
}
i <- cache_rds(g(x), file = "my_cache.rds", dir = paste0(cp, "/"), 
   hash = list(x, deparse(g)))
print(list.files(cp, pattern = "my_cache.*\\.rds$"))
# [1] "my_cache_84d8f7e4a7980ae6b2b26d1e01779259.rds"

but this feels a bit hackish. I was thus wondering what the canonical way would be to invalidate the cache based on the definition of an external function.

4
  • 1
    When you use hash = list(x, g), does it change every time? Or just the first few times? Commented Oct 7 at 14:48
  • @MrFlick it changes every time, list(x, g) does not resolve it. Commented Oct 7 at 16:05
  • What version of R are you running? Are you using RStudio or R directly? Commented Oct 7 at 17:03
  • Martin Fowler warned there'd be days like this. suggests cache_exec, perhaps. But is hash <- list(rlang::hash(1), rlang::hash(g)) infeasible where 1 could be i? Commented Oct 7 at 19:37

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.