Skip to content

Commit

Permalink
use lazy-loading for local variables in code, i.e., load them from ca…
Browse files Browse the repository at this point in the history
…che only when they are used in the future
  • Loading branch information
yihui committed May 8, 2024
1 parent 825afa4 commit 977bc1a
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 9 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: xfun
Type: Package
Title: Supporting Functions for Packages Maintained by 'Yihui Xie'
Version: 0.43.18
Version: 0.43.19
Authors@R: c(
person("Yihui", "Xie", role = c("aut", "cre", "cph"), email = "[email protected]", comment = c(ORCID = "0000-0003-0645-5666")),
person("Wush", "Wu", role = "ctb"),
Expand Down
19 changes: 13 additions & 6 deletions R/cache.R
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@
#' @param ... More arguments to control the behavior of caching (see
#' \sQuote{Details}).
#' @return If the cache is found, the cached value of the expression will be
#' loaded and returned (other local variables will also be loaded into the
#' current environment as a side-effect). If cache does not exist, the
#' loaded and returned (other local variables will also be lazy-loaded into
#' the current environment as a side-effect). If cache does not exist, the
#' expression is executed and its value is returned.
#' @export
#' @examples
Expand Down Expand Up @@ -153,7 +153,7 @@ cache_code = function(
id %in% ls_all(db)
} else {
db = list.files(id, full.names = TRUE)
hits = grepl('^[0-9a-z]{32}$', basename(db))
hits = grepl('^[0-9a-z]{32}([.][0-9]+)?$', basename(db))
if (base::isFALSE(config$keep)) file.remove(db[hits])
id = file.path(id, hash)
file_exists(id)
Expand All @@ -163,7 +163,10 @@ cache_code = function(
# I could implement lazy-loading here but I'm not sure if it's worth it
ret = if (mem_cache) db[[id]] else rw$load(id)
list2env(ret$hashes, dict) # update the hash dictionary
list2env(ret$values, envir) # copy cached objects into envir
# lazy-load cached objects into envir
.mapply(function(name, file) {
delayedAssign(name, if (mem_cache) ret$values[[name]] else rw$load(file), assign.env = envir)
}, list(names(ret$hashes), sprintf('%s.%d', id, seq_along(ret$hashes))), NULL)
found
return(ret$result)
}
Expand All @@ -190,12 +193,16 @@ cache_code = function(
'Variable(s) not found in the environment: ', paste(v2, collapse = ', ')
)
hashes = as.list(do.call(md5, vals <- mget(vars, envir)))
ret = list(result = res, hashes = hashes, values = vals)
ret = list(result = res, hashes = hashes)
if (mem_cache) {
ret$values = vals
db[[id]] = ret
} else {
dir_create(dirname(id))
rw$save(ret, id)
rw$save(ret, id) # result and variable hashes are saved to the main file
# variable values are saved in separate files of the form HASH.i; the i-th
# file is for the i-th variable
.mapply(rw$save, list(vals, sprintf('%s.%d', id, seq_along(vals))), NULL)
}
list2env(hashes, dict)
})
Expand Down
4 changes: 2 additions & 2 deletions man/cache_exec.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 977bc1a

Please sign in to comment.