pax_global_header00006660000000000000000000000064126211332370014512gustar00rootroot0000000000000052 comment=8b4c1f03ccf9baf73ef13bc09e8110b95ae7ebb8 R.cache-0.12.0/000077500000000000000000000000001262113323700130355ustar00rootroot00000000000000R.cache-0.12.0/.Rbuildignore000066400000000000000000000011231262113323700154600ustar00rootroot00000000000000#---------------------------- # Git and SVN related #---------------------------- ^.svn ^.git ^.make INSTALL[.]md OVERVIEW[.]md #---------------------------- # Travis-CI et al. #---------------------------- ^[.]travis[.]yml$ ^travis-tool[.]sh$ ^pkg-build[.]sh$ ^appveyor[.]yml$ ^covr-utils.R$ ^[.]covr[.]R$ #---------------------------- # R related #---------------------------- ^cran-comments[.].*$ ^vignettes/.*[.](pdf|PDF)$ ^vignettes/.*[.](r|R)$ ^vignettes/[.]install_extras$ ^Makefile$ ^incl ^NAMESPACE,.*[.]txt$ ^nohup.*$ ^[.]R ^[.]benchmark ^[.]devel ^[.]test ^[.]check ^.*[.]tar[.]gz$ R.cache-0.12.0/.covr.R000066400000000000000000000015151262113323700142110ustar00rootroot00000000000000################################################################# # Test coverage # # * covr-utils: https://github.com/HenrikBengtsson/covr-utils # * covr: https://github.com/jimhester/covr # * Coveralls: https://coveralls.io/ # # Henrik Bengtsson ################################################################# if (!file_test("-f", "covr-utils.R")) { source("http://callr.org/install#R.utils[u]") R.utils::downloadFile("https://raw.githubusercontent.com/HenrikBengtsson/covr-utils/master/covr-utils.R") } source("covr-utils.R") # Exclusion rules excl <- exclusions( filter(r_files(), covr_lines), # Apply 'covr:' rules in source code filter(r_files(), stop_lines) # Skip lines with stop(). ) str(excl) # Run through tests, record source code coverage, and # publish to Coveralls covr <- covr_package(exclusions=excl, quiet=FALSE) R.cache-0.12.0/.gitignore000066400000000000000000000000661262113323700150270ustar00rootroot00000000000000.Rhistory *~ **/*~ .R .benchmark .check .test .o .dll R.cache-0.12.0/.make/000077500000000000000000000000001262113323700140305ustar00rootroot00000000000000R.cache-0.12.0/.make/Makefile000066400000000000000000000424771262113323700155060ustar00rootroot00000000000000# Makefile for R packages # CORE MACROS ifeq ($(OS), Windows_NT) CD=cd CURDIR=$(subst \,/,$(shell cmd.exe /C cd)) FSEP=; else CD=cd -P "$(CURDIR)"; cd # This handles the case when CURDIR is a softlink FSEP=: endif CP=cp MAKE=make MV=mv RM=rm -f MKDIR=mkdir -p RMDIR=$(RM) -r GIT=git # PACKAGE MACROS PKG_VERSION := $(shell grep -i ^version DESCRIPTION | cut -d : -d \ -f 2) PKG_NAME := $(shell grep -i ^package DESCRIPTION | cut -d : -d \ -f 2) PKG_DIR := $(shell basename "$(CURDIR)") PKG_DIR := $(CURDIR) PKG_TARBALL := $(PKG_NAME)_$(PKG_VERSION).tar.gz PKG_ZIP := $(PKG_NAME)_$(PKG_VERSION).zip PKG_TGZ := $(PKG_NAME)_$(PKG_VERSION).tgz # FILE MACROS FILES_R := $(wildcard R/*.R) FILES_DATA := $(wildcard data/*) FILES_MAN := $(wildcard man/*.Rd) FILES_INCL := $(wildcard incl/*) FILES_INST := $(wildcard inst/* inst/*/* inst/*/*/* inst/*/*/*/*) FILES_VIGNETTES := $(wildcard vignettes/* vignettes/.install_extras) FILES_SRC := $(wildcard src/* src/*/* src/*/*/* src/*/*/*/* src/*/*/*/*/* src/*/*/*/*/*/* src/*/*/*/*/*/*/* src/*/*/*/*/*/*/*/*) FILES_SRC_C := $(wildcard src/*.c) FILES_SRC_H := $(wildcard src/*.h) FILES_TESTS := $(wildcard tests/*.R) FILES_NEWS := $(wildcard NEWS inst/NEWS) FILES_MISC := $(wildcard README.md) FILES_ROOT := DESCRIPTION NAMESPACE $(wildcard .Rbuildignore .Rinstignore) PKG_FILES := $(FILES_ROOT) $(FILES_NEWS) $(FILES_R) $(FILES_DATA) $(FILES_MAN) $(FILES_INST) $(FILES_VIGNETTES) $(FILES_SRC) $(FILES_TESTS) $(FILES_MISC) FILES_MAKEFILE := $(wildcard ../../Makefile) # Has vignettes in 'vignettes/' or 'inst/doc/'? DIR_VIGNS := $(wildcard vignettes inst/doc) # R MACROS R = R R_SCRIPT = Rscript R_HOME := $(shell $(R_SCRIPT) -e "cat(R.home())") ## R_USE_CRAN := $(shell $(R_SCRIPT) -e "cat(Sys.getenv('R_USE_CRAN', 'FALSE'))") R_NO_INIT := --no-init-file R_VERSION_STATUS := $(shell $(R_SCRIPT) -e "status <- tolower(R.version[['status']]); if (regexpr('unstable', status) != -1L) status <- 'devel'; cat(status)") R_VERSION_X_Y := $(shell $(R_SCRIPT) -e "cat(gsub('[.][0-9]+$$', '', getRversion()))") R_VERSION := $(shell $(R_SCRIPT) -e "cat(as.character(getRversion()))") R_VERSION_FULL := $(R_VERSION)$(R_VERSION_STATUS) R_LIBS_USER_X := $(shell $(R_SCRIPT) -e "cat(.libPaths()[1])") R_INCLUDE := $(shell $(R_SCRIPT) -e "cat(R.home('include'))") R_OUTDIR := ../_R-$(R_VERSION_FULL) ## R_BUILD_OPTS := ## R_BUILD_OPTS := $(R_BUILD_OPTS) --no-build-vignettes R_CHECK_OUTDIR := $(R_OUTDIR)/$(PKG_NAME).Rcheck _R_CHECK_CRAN_INCOMING_ = $(shell $(R_SCRIPT) -e "cat(Sys.getenv('_R_CHECK_CRAN_INCOMING_', 'FALSE'))") _R_CHECK_XREFS_REPOSITORIES_ = $(shell if test "$(_R_CHECK_CRAN_INCOMING_)" = "TRUE"; then echo ""; else echo "invalidURL"; fi) _R_CHECK_FULL_ = $(shell $(R_SCRIPT) -e "cat(Sys.getenv('_R_CHECK_FULL_', ''))") R_CHECK_OPTS = --as-cran --timings $(shell if test "$(_R_CHECK_USE_VALGRIND_)" = "TRUE"; then echo "--use-valgrind"; fi) R_RD4PDF = $(shell $(R_SCRIPT) -e "if (getRversion() < 3) cat('times,hyper')") R_CRAN_OUTDIR := $(R_OUTDIR)/$(PKG_NAME)_$(PKG_VERSION).CRAN HAS_ASPELL := $(shell $(R_SCRIPT) -e "cat(Sys.getenv('HAS_ASPELL', !inherits(try(aspell('DESCRIPTION', control=c('--master=en_US', '--add-extra-dicts=en_GB'), dictionaries='en_stats', program='aspell'), silent=TRUE), 'try-error')))") ## Git related GIT_BRANCH := $(shell $(GIT) symbolic-ref --short HEAD) GIT_BRANCH := $(subst /,-,$(GIT_BRANCH)) GIT_COMMIT := $(shell $(GIT) log -1 --format="%h") R_LIBS_BRANCH := $(CURDIR)/.R/$(GIT_BRANCH) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Main # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - all: build install check # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Displays macros # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - debug: @echo CURDIR=\'$(CURDIR)\' @echo R_HOME=\'$(R_HOME)\' @echo @echo PKG_DIR=\'$(PKG_DIR)\' @echo PKG_NAME=\'$(PKG_NAME)\' @echo PKG_VERSION=\'$(PKG_VERSION)\' @echo PKG_TARBALL=\'$(PKG_TARBALL)\' @echo @echo HAS_ASPELL=\'$(HAS_ASPELL)\' @echo @echo R=\'$(R)\' ## @echo R_USE_CRAN=\'$(R_USE_CRAN)\' @echo R_NO_INIT=\'$(R_NO_INIT)\' @echo R_SCRIPT=\'$(R_SCRIPT)\' @echo R_VERSION_X_Y=\'$(R_VERSION_X_Y)\' @echo R_VERSION=\'$(R_VERSION)\' @echo R_VERSION_STATUS=\'$(R_VERSION_STATUS)\' @echo R_VERSION_FULL=\'$(R_VERSION_FULL)\' @echo R_LIBS_USER_X=\'$(R_LIBS_USER_X)\' @echo R_INCLUDE=\'$(R_INCLUDE)\' @echo R_OUTDIR=\'$(R_OUTDIR)\' @echo @echo "Default packages:" $(shell $(R) --slave -e "cat(paste(getOption('defaultPackages'), collapse=', '))") @echo @echo R_BUILD_OPTS=\'$(R_BUILD_OPTS)\' @echo @echo R_CHECK_OUTDIR=\'$(R_CHECK_OUTDIR)\' @echo _R_CHECK_CRAN_INCOMING_=\'$(_R_CHECK_CRAN_INCOMING_)\' @echo _R_CHECK_XREFS_REPOSITORIES_=\'$(_R_CHECK_XREFS_REPOSITORIES_)\' @echo _R_CHECK_FULL_=\'$(_R_CHECK_FULL_)\' @echo R_CHECK_OPTS=\'$(R_CHECK_OPTS)\' @echo R_RD4PDF=\'$(R_RD4PDF)\' @echo @echo R_CRAN_OUTDIR=\'$(R_CRAN_OUTDIR)\' @echo debug_full: debug @echo @echo FILES_ROOT=\'$(FILES_ROOT)\' @echo FILES_R=\'$(FILES_R)\' @echo FILES_DATA=\'$(FILES_DATA)\' @echo FILES_MAN=\'$(FILES_MAN)\' @echo FILES_INST=\'$(FILES_INST)\' @echo FILES_VIGNETTES=\'$(FILES_VIGNETTES)\' @echo FILES_SRC=\'$(FILES_SRC)\' @echo FILES_TESTS=\'$(FILES_TESTS)\' @echo FILES_INCL=\'$(FILES_INCL)\' @echo FILES_MISC=\'$(FILES_MISC)\' @echo @echo DIR_VIGNS=\'$(DIR_VIGNS)\' @echo dirname\(DIR_VIGNS\)=\'$(shell dirname $(DIR_VIGNS))\' @echo @echo GIT_BRANCH=\'$(GIT_BRANCH)\' @echo GIT_COMMIT=\'$(GIT_COMMIT)\' @echo R_LIBS_BRANCH=\'$(R_LIBS_BRANCH)\' # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Update / install # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Update existing packages update: $(R_SCRIPT) -e "try(update.packages(ask=FALSE)); source('http://bioconductor.org/biocLite.R'); biocLite(ask=FALSE);" # Install missing dependencies deps: DESCRIPTION $(MAKE) update $(R_SCRIPT) -e "x <- unlist(strsplit(read.dcf('DESCRIPTION',fields=c('Depends', 'Imports', 'Suggests')),',')); x <- gsub('([[:space:]]*|[(].*[)])', '', x); libs <- .libPaths()[file.access(.libPaths(), mode=2) == 0]; x <- unique(setdiff(x, c('R', rownames(installed.packages(lib.loc=libs))))); if (length(x) > 0) { try(install.packages(x)); x <- unique(setdiff(x, c('R', rownames(installed.packages(lib.loc=libs))))); source('http://bioconductor.org/biocLite.R'); biocLite(x); }" setup: update deps $(R_SCRIPT) -e "source('http://aroma-project.org/hbLite.R'); hbLite('R.oo')" ns: $(R_SCRIPT) -e "library('$(PKG_NAME)'); source('X:/devtools/NAMESPACE.R'); writeNamespaceSection('$(PKG_NAME)'); writeNamespaceImports('$(PKG_NAME)');" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Build source tarball # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(R_OUTDIR)/$(PKG_TARBALL): $(PKG_FILES) $(MKDIR) $(R_OUTDIR) $(RM) $@ $(CD) $(R_OUTDIR);\ $(R) $(R_NO_INIT) CMD build $(R_BUILD_OPTS) $(PKG_DIR) build: $(R_OUTDIR)/$(PKG_TARBALL) build_force: $(RM) $(R_OUTDIR)/$(PKG_TARBALL) $(MAKE) install # Make sure the tarball is readable build_fix: $(R_OUTDIR)/$(PKG_TARBALL) ifeq ($(OS), Windows_NT) ifeq ($(USERNAME), hb) $(MKDIR) X:/tmp/$(R_VERSION_FULL) $(CP) -f $< X:/tmp/$(R_VERSION_FULL)/ $(RM) $< $(MV) X:/tmp/$(R_VERSION_FULL)/$( $(PKG_NAME).Rcheck/.check.complete check: $(R_CHECK_OUTDIR)/.check.complete check_force: $(RM) -r $(R_CHECK_OUTDIR) $(MAKE) check clang: clang -c -pedantic -Wall -I$(R_INCLUDE) src/*.c $(RM) *.o clang-ubsan: clang -fsanitize=undefined -I$(R_INCLUDE) -c src/*.c $(RM) *.o valgrind_scan: grep -E "^==.*==[ ]+(at|by) 0x" $(R_CHECK_OUTDIR)/tests*/*.Rout | cat grep "^==.* ERROR SUMMARY:" $(R_CHECK_OUTDIR)/tests*/*.Rout | grep -v -F "ERROR SUMMARY: 0 errors" | cat valgrind: export _R_CHECK_USE_VALGRIND_=TRUE;\ $(MAKE) check_force $(MAKE) valgrind_scan # Check the line width of incl/*.(R|Rex) files [max 100 chars in R devel] check_Rex: $(R_SCRIPT) -e "if (!file.exists('incl')) quit(status=0); setwd('incl/'); fs <- dir(pattern='[.](R|Rex)$$'); ns <- sapply(fs, function(f) max(nchar(readLines(f)))); ns <- ns[ns > 100]; print(ns); if (length(ns) > 0L) quit(status=1)" covr: $(R_SCRIPT) -e "source('.covr.R'); covr::shine(covr)" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Install and build binaries # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(R_OUTDIR)/$(PKG_ZIP): $(R_OUTDIR)/$(PKG_TARBALL) build_fix $(CD) $(R_OUTDIR);\ $(R) --no-init-file CMD INSTALL --build --merge-multiarch $(PKG_TARBALL) binary: $(R_OUTDIR)/$(PKG_ZIP) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Build Rd help files from Rdoc comments # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - rox: $(R_SCRIPT) -e "roxygen2::roxygenize()" Rd: check_Rex $(R_SCRIPT) -e "setwd('..'); Sys.setlocale(locale='C'); R.oo::compileRdoc('$(PKG_NAME)', path='$(PKG_DIR)')" %.Rd: $(R_SCRIPT) -e "setwd('..'); Sys.setlocale(locale='C'); R.oo::compileRdoc('$(PKG_NAME)', path='$(PKG_DIR)', '$*.R')" missing_Rd: $(R_SCRIPT) -e "x <- readLines('$(R_CHECK_OUTDIR)/00check.log'); from <- grep('Undocumented code objects:', x)+1; if (length(from) > 0L) { to <- grep('All user-level objects', x)-1; x <- x[from:to]; x <- gsub('^[ ]*', '', x); x <- gsub('[\']', '', x); cat(x, sep='\n', file='999.missingdocs.txt'); }" spell_Rd: $(R_SCRIPT) -e "f <- list.files('man', pattern='[.]Rd$$', full.names=TRUE); utils::aspell(f, filter='Rd')" spell_NEWS: $(R_SCRIPT) -e "utils::aspell('$(FILES_NEWS)')" spell: $(R_SCRIPT) -e "utils::aspell('DESCRIPTION', filter='dcf')" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Build package vignettes # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(R_OUTDIR)/vigns: install $(MKDIR) $(R_OUTDIR)/vigns/$(shell dirname $(DIR_VIGNS)) $(CP) DESCRIPTION $(R_OUTDIR)/vigns/ $(CP) -r $(DIR_VIGNS) $(R_OUTDIR)/vigns/$(shell dirname $(DIR_VIGNS)) $(CD) $(R_OUTDIR)/vigns;\ $(R_SCRIPT) -e "v <- tools::buildVignettes(dir='.'); file.path(getwd(), v[['outputs']])" vignettes: $(R_OUTDIR)/vigns # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Run package tests # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(R_OUTDIR)/tests/%.R: $(FILES_TESTS) $(RMDIR) $(R_OUTDIR)/tests $(MKDIR) $(R_OUTDIR)/tests $(CP) $? $(R_OUTDIR)/tests test_files: $(R_OUTDIR)/tests/*.R test: $(R_OUTDIR)/tests/%.R $(CD) $(R_OUTDIR)/tests;\ $(R_SCRIPT) -e "for (f in list.files(pattern='[.]R$$')) { print(f); source(f, echo=TRUE) }" test_full: $(R_OUTDIR)/tests/%.R $(CD) $(R_OUTDIR)/tests;\ export _R_CHECK_FULL_=TRUE;\ $(R_SCRIPT) -e "for (f in list.files(pattern='[.]R$$')) { print(f); source(f, echo=TRUE) }" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Benchmarking # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - R_branch: R_LIBS="$(R_LIBS_USER_X)$(FSEP)$(R_LIBS)" R_LIBS_USER="$(R_LIBS_BRANCH)" $(R) benchmark: $(MKDIR) .benchmark/$(PKG_VERSION);\ $(CD) .benchmark/$(PKG_VERSION);\ $(R_SCRIPT) -e "$(PKG_NAME):::benchmark('index')" benchmark_branch: $(MKDIR) .benchmark/$(PKG_VERSION)_$(GIT_BRANCH)_$(GIT_COMMIT);\ $(CD) .benchmark/$(PKG_VERSION)_$(GIT_BRANCH)_$(GIT_COMMIT);\ R_LIBS="$(R_LIBS_USER_X)$(FSEP)$(R_LIBS)" R_LIBS_USER="$(R_LIBS_BRANCH)" $(R_SCRIPT) -e "$(PKG_NAME):::benchmark('index')" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Miscellaneous development tools # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## Fully expanded src/*.c files .devel/src/%: src/% $(FILES_SRC) $(MKDIR) .devel/src/;\ gcc -I$(R_INCLUDE) -E $< | sed -e '/./b' -e :n -e 'N;s/\n$$//;tn' > .devel/$< .devel/src/all: $(FILES_SRC) for f in $(FILES_SRC_C); do\ echo $$f;\ $(MAKE) .devel/$$f;\ done # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Run extensive CRAN submission checks # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(R_CRAN_OUTDIR)/$(PKG_TARBALL): $(R_OUTDIR)/$(PKG_TARBALL) build_fix $(MKDIR) $(R_CRAN_OUTDIR) $(CP) $(R_OUTDIR)/$(PKG_TARBALL) $(R_CRAN_OUTDIR) $(R_CRAN_OUTDIR)/$(PKG_NAME),EmailToCRAN.txt: $(R_CRAN_OUTDIR)/$(PKG_TARBALL) $(CD) $(R_CRAN_OUTDIR);\ $(R_SCRIPT) -e "RCmdCheckTools::testPkgsToSubmit(delta=2/3)" cran_setup: $(R_CRAN_OUTDIR)/$(PKG_TARBALL) $(R_SCRIPT) -e "if (!nzchar(system.file(package='RCmdCheckTools'))) { source('http://aroma-project.org/hbLite.R'); hbLite('RCmdCheckTools', devel=TRUE); }" cran: cran_setup $(R_CRAN_OUTDIR)/$(PKG_NAME),EmailToCRAN.txt # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Send to win-builder server # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WIN_BUILDER = win-builder.r-project.org win-builder-devel: $(R_OUTDIR)/$(PKG_TARBALL) curl -v -T $? ftp://anonymous@$(WIN_BUILDER)/R-devel/ win-builder-release: $(R_OUTDIR)/$(PKG_TARBALL) curl -v -T $? ftp://anonymous@$(WIN_BUILDER)/R-release/ win-builder: win-builder-devel win-builder-release # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Local repositories # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ifeq ($(OS), Windows_NT) REPOS_PATH = T:/My\ Repositories/braju.com/R else REPOS_PATH = /tmp/hb/repositories/braju.com/R endif REPOS_SRC := $(REPOS_PATH)/src/contrib $(REPOS_SRC): $(MKDIR) "$@" $(REPOS_SRC)/$(PKG_TARBALL): $(R_OUTDIR)/$(PKG_TARBALL) $(REPOS_SRC) $(CP) $(R_OUTDIR)/$(PKG_TARBALL) $(REPOS_SRC) repos: $(REPOS_SRC)/$(PKG_TARBALL) Makefile: $(FILES_MAKEFILE) $(R_SCRIPT) -e "d <- 'Makefile'; s <- '../../Makefile'; if (file_test('-nt', s, d) && (regexpr('Makefile for R packages', readLines(s, n=1L)) != -1L)) file.copy(s, d, overwrite=TRUE)" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Refresh # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .make/Makefile: $(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/Makefile', path='.make/')" .make/.travis.yml.rsp: $(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/.travis.yml.rsp', path='.make/')" .make/appveyor.yml.rsp: $(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/appveyor.yml.rsp', path='.make/')" .make/README.md.rsp: $(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/README.md.rsp', path='.make/')" .covr.R: $(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/covr-utils/master/.covr.R')" clean: $(RM) .make/.travis.yml.rsp .make/appveyor.yml.rsp .make/README.md.rsp .covr.R $(RM) covr-utils.R refresh: clean $(MAKE) --silent .make/.travis.yml.rsp $(MAKE) --silent .make/appveyor.yml.rsp $(MAKE) --silent .make/README.md.rsp $(MAKE) --silent .covr.R $(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/Makefile', path='.make/', skip=FALSE)" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # GitHub, Travis CI, ... # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - README.md: .make/README.md.rsp $(R_SCRIPT) -e "R.rsp::rfile('$<', postprocess=FALSE)" .travis.yml: .make/.travis.yml.rsp $(R_SCRIPT) -e "R.rsp::rfile('$<', postprocess=FALSE)" appveyor.yml: .make/appveyor.yml.rsp $(R_SCRIPT) -e "R.rsp::rfile('$<', postprocess=FALSE)" config: .travis.yml appveyor.yml README.md R.cache-0.12.0/.travis.yml000066400000000000000000000047511262113323700151550ustar00rootroot00000000000000#---------------------------------------------------------------- # Travis-CI configuration for R packages # # REFERENCES: # * Travis CI: https://travis-ci.org/ # * r-builder: https://github.com/metacran/r-builder # * covr: https://github.com/jimhester/covr # # Validate your .travis.yml file at http://lint.travis-ci.org/ #---------------------------------------------------------------- language: c env: global: - RENV="./pkg-build.sh" # r-builder - R_BUILD_ARGS="--no-manual" - R_CHECK_ARGS="--no-manual --as-cran" - _R_CHECK_CRAN_INCOMING_=TRUE - _R_CHECK_FORCE_SUGGESTS_=false # Need LaTeX? (very time consuming!) - BOOTSTRAP_LATEX="" # Skip building vignettes, which iff LaTeX-based are very # time consuming because LaTeX needs to be installed # - R_BUILD_ARGS="--no-build-vignettes ${R_BUILD_ARGS}" # - R_CHECK_ARGS="--no-build-vignettes ${R_CHECK_ARGS}" # R versions r-builder should test on (ignored by r-travis) matrix: - RVERSION=3.1.3 - RVERSION=3.2.2 - RVERSION=devel _R_COVR_=TRUE _R_CHECK_FULL_=TRUE before_install: - echo RENV=$RENV - curl -OL https://raw.githubusercontent.com/HenrikBengtsson/r-builder/master/pkg-build.sh; - chmod 755 $RENV - $RENV bootstrap - if [ "BOOTSTRAP_LATEX" == "true" ]; then (cd /tmp && curl -OL http://mirrors.ctan.org/macros/latex/contrib/xcolor.zip && cd /usr/share/texmf/tex/latex && sudo unzip /tmp/xcolor.zip && cd xcolor && sudo latex xcolor.ins && sudo texhash); else export R_RSP_COMPILELATEX_FALLBACK="copy-force"; fi - if [[ "$_R_CHECK_USE_VALGRIND_" == "TRUE" ]]; then export R_BUILD_ARGS="--no-manual --no-build-vignettes"; export R_CHECK_ARGS="--no-manual --no-build-vignettes --no-codoc --no-examples --use-valgrind"; export _R_CHECK_TIMINGS_=10; sudo apt-get install valgrind; valgrind --version; fi install: - $RENV install_r digest R.methodsS3 R.oo R.utils script: - $RENV run_build - $RENV run_check after_success: - $RENV dump_logs_by_extension out - if [[ "$_R_COVR_" == "TRUE" && -f ".covr.R" ]]; then $RENV install_devtools; $RENV install_github jimhester/covr; curl -OL https://raw.githubusercontent.com/HenrikBengtsson/covr-utils/master/covr-utils.R; fi - if [[ "$_R_COVR_" == "TRUE" && -f ".covr.R" ]]; then $RENV run_script .covr.R; fi after_failure: - $RENV dump_logs notifications: email: on_success: change on_failure: change branches: except: - /-expt$/ R.cache-0.12.0/DESCRIPTION000077500000000000000000000022711262113323700145500ustar00rootroot00000000000000Package: R.cache Version: 0.12.0 Depends: R (>= 2.5.0) Imports: utils, R.methodsS3 (>= 1.7.0), R.oo (>= 1.19.0), R.utils (>= 2.1.0), digest (>= 0.6.8) Date: 2015-11-12 Title: Fast and Light-Weight Caching (Memoization) of Objects and Results to Speed Up Computations Authors@R: c(person("Henrik", "Bengtsson", role=c("aut", "cre", "cph"), email = "henrikb@braju.com")) Author: Henrik Bengtsson [aut, cre, cph] Maintainer: Henrik Bengtsson Description: Memoization can be used to speed up repetitive and computational expensive function calls. The first time a function that implements memoization is called the results are stored in a cache memory. The next time the function is called with the same set of parameters, the results are momentarily retrieved from the cache avoiding repeating the calculations. With this package, any R object can be cached in a key-value storage where the key can be an arbitrary set of R objects. The cache memory is persistent (on the file system). License: LGPL (>= 2.1) LazyLoad: TRUE URL: https://github.com/HenrikBengtsson/R.cache BugReports: https://github.com/HenrikBengtsson/R.cache/issues R.cache-0.12.0/Makefile000066400000000000000000000000271262113323700144740ustar00rootroot00000000000000include .make/Makefile R.cache-0.12.0/NAMESPACE000066400000000000000000000045001262113323700142530ustar00rootroot00000000000000# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # IMPORTS # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - importFrom("R.methodsS3", "setMethodS3") importFrom("R.methodsS3", "throw") ## Importing Class:es importFrom("R.oo", "Package") ## Importing generics importFrom("R.oo", "clearCache") ## Importing functions importFrom("R.oo", "attachLocally") importFrom("R.oo", "startupMessage") importFrom("R.oo", "trim") importFrom("R.utils", "cat") ## Multi-sources: R.utils, base importFrom("R.utils", "isAbsolutePath") importFrom("R.utils", "isDirectory") importFrom("R.utils", "isFile") importFrom("R.utils", "listDirectory") importFrom("R.utils", "mkdirs") importFrom("R.utils", "removeDirectory") importFrom("R.utils", "touchFile") importFrom("utils", "compareVersion") importFrom("utils", "packageVersion") importFrom("digest", "digest") ## Manually adjusted ## Cannot import explicitly from 'base'; ## importFrom("base", "getOption") ## Multi-sources: R.utils, base ## Manual imports importFrom("R.utils", "Arguments") # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # EXPORTS # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Export all public methods, that is, those without a preceeding dot # in their names. export("R.cache") export("evalWithMemoization") export("addMemoization") export("memoizedCall") export("getCacheRootPath") export("setCacheRootPath") export("getCachePath") export("findCache") export("readCacheHeader") export("loadCache") export("saveCache") export("getChecksum") export("clearCache") # Imported from R.oo # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # S3 METHOD DECLARATIONS # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # default S3method("addMemoization", "default") S3method("clearCache", "default") S3method("findCache", "default") S3method("generateCache", "default") S3method("getCachePath", "default") S3method("getCacheRootPath", "default") S3method("getChecksum", "default") S3method("loadCache", "default") S3method("memoizedCall", "default") S3method("readCacheHeader", "default") S3method("saveCache", "default") S3method("setCachePath", "default") S3method("setCacheRootPath", "default") S3method("setupCacheRootPath", "default") # Object S3method("getChecksum", "Object") R.cache-0.12.0/NEWS000077500000000000000000000245001262113323700135400ustar00rootroot00000000000000 Package: R.cache ================ Version: 0.12.0 [2015-11-12] o SPEEDUP: Now memoizedCall() generates cache pathname only once. o Now all prompt and verbose messages are send to the standard error (instead of the standard output). o ROBUSTNESS: Increased test coverage from 64% to 86%. o CLEANUP: Dropped argument 'verbose' from memoizedCall(). Version: 0.11.1 [2014-09-10] o ROBUSTNESS: Added package system tests for memoizeCall() and addMemoization(). o DOCUMENTATION: Clarified in help that function calls that returns ("has value") NULL will not be cached. o BUG FIX: addMemoization() will no longer memoize an already memoized function. Version: 0.11.0 [2014-09-05] o Now package imports rather than suggests the 'digest' package. This simplifies installation/usage of the package. o Bumped package dependencies. Version: 0.10.0 [2014-06-10] o Bumped package dependencies. Version: 0.9.5 [2014-05-01] o ROBUSTNESS: The textual prompt used to ask new R.cache users for approval on creating a persistent cache directory is now using the standard error (stderr) rather than the standard output (stdout). This lowers the risk for issues with report generators. Version: 0.9.4 [2014-04-26] o CLEANUP: Minimize use of '::'. Version: 0.9.3 [2014-01-30] o Bumped package dependencies. Version: 0.9.2 [2014-01-13] o All call to internal generateCache() with key=NULL would give a hard-to-understand error message. Now it's more informative. o Bumped package dependencies. Version: 0.9.1 [2013-12-21] o Added arguments 'path' and 'rootPath' to getCachePath(). o Added argument 'pathname' to saveCache(). Version: 0.9.0 [2013-10-17] o BUG FIX: If the package was only loaded but not attached, the cache root path would default to ~/.Rcache/, which in turn could cause that path to be create without asking the user. For instance, R.cache::loadCache(list()) would do. Thanks to Kurt Hornik at Vienna University of Economics and Business for reporting on this. Version: 0.8.4 [2013-10-14] o Adjusted package dependencies and NAMESPACE to work with the package versions available on CRAN. o Now DESCRIPTION's 'Authors' field matches 'Authors@R'. Version: 0.8.3 [2013-10-03] o Bumped package dependencies. Version: 0.8.2 [2013-09-28] o Now the 'R.cache' Package object is also available when the package is only loaded (but not attached). Version: 0.8.1 [2013-09-15] o CLEANUP: Now only importing a minimal set of functions needed from the 'R.oo' and the 'R.utils' packages. o Bumped package dependencies. Version: 0.8.0 [2013-08-21] o Now R.utils is no longer attached ("loaded") - only imported. o Added system tests. Version: 0.7.4 [2013-08-20] o Now explicitly importing one function from 'utils' in NAMESPACE. Version: 0.7.3 [2013-08-18] o Now clearCache() is exported (re-exported from R.oo). Version: 0.7.2 [2013-08-03] o Bumped package dependencies. o BUG FIX: R.cache:::.assertDigest() called from within another package would give an error that packageVersion() of 'utils' was not found. Version: 0.7.1 [2013-07-11] o Updated the title and the description of the package. Version: 0.7.0 [2013-07-03] o Now getChecksum() passes '...' to digest(), e.g. argument 'algo'. o Bumped package dependencies. Version: 0.6.10 [2013-05-25] o Minor speedup of loadCache() - replaced an rm() call with NULL assignment. Version: 0.6.9 [2013-05-20] o CRAN POLICY: Now all Rd \usage{} lines are at most 90 characters long. o Bumped package dependencies. Version: 0.6.8 [2012-12-19] o Utilizing new startupMessage() of R.oo. Version: 0.6.7 [2012-11-28] o Added support for clearCache(..., recursive=TRUE). Version: 0.6.6 [2012-11-27] o BUG FIX: clearCache() would give error "object 'dirs' not found". Version: 0.6.5 [2012-11-18] o ROBUSTNESS: Now package declares S3 methods in the namespace. o CLEANUP: Now package exports a smaller set of the methods. o CLEANUP: Package now only imports R.methodsS3 and R.oo, no long depends (loads) them. It still needs to load R.utils. o Added internal .assertDigest(), which originates from aroma.core. Version: 0.6.4 [2012-10-16] o ROBUSTNESS/BUG FIX: No longer passing '...' to NextMethod(), cf. R-devel thread 'Do *not* pass '...' to NextMethod() - it'll do it for you; missing documentation, a bug or just me?' on Oct 16, 2012. o Package now imports R.methodsS3 and R.oo. Version: 0.6.3 [2012-09-12] o Renamed the installed .Rcache/ directory to _Rcache/ to avoid R CMD check NOTEs. o CRAN POLICY: Removed one last call to .Internal() for loading saved data. This could be done in a backward-compatible way using readRDS(). Version: 0.6.2 [2012-03-20] o CRAN POLICY: Dropped an explicit call to an .Internal() function. Version: 0.6.1 [2012-01-22] o Updated the README that is copied to the .Rcache directory. o Updated package dependencies. Version: 0.6.0 [2011-12-30] o As before, the cache root path defaults to ~/.Rcache/. However, if it does not exists, then it is created when the package is loaded, but only after approval by the user (via a textual prompt). If not approved, or it is not possible to prompt the user (e.g. in a non-interactive session), then a session-specific temporary directory is used. Version: 0.5.3 [2011-12-29] o Now getCachePath() and setCacheRootPath() add a README.txt file to the root path, iff missing. It explains why the directory structure exists, what created it, and that it is safe to delete. Version: 0.5.2 [2011-10-05] o BUG FIX (for R v2.13.0 only): Applying the same fix that was done for R v2.12.2 and before in R.cache v0.5.1. Version: 0.5.1 [2011-08-31] o BUG FIX (for R v2.12.2 and before): After adding support for compressed files in R.cache v0.5.0, we would get the 'Error in seek.connection(con, origin = "current", where = -5) : whence = "end" is not implemented for gzfile connections' in readCacheHeader() iff running R v2.12.2 or before. Thanks to Uwe Ligges (R core) for reporting on this. Version: 0.5.0 [2011-08-16] o Added support for saving and loading compressed cache files. o ROBUSTNESS: Now findCache() asserts that any identified cache file is really a file. o CLEANUP: Now package uses packageStartupMessage() instead of cat(). Version: 0.4.3 [2011-07-21] o DOCUMENTATION: Clarified how argument 'dirs' (in methods using it) specifies the subdirectory of the cache root directory. Version: 0.4.2 [2011-05-19] o Added a help page to clearCache(). o Now argument 'prompt' for clearCache() defaults to TRUE iff interactive() is TRUE, otherwise FALSE. Version: 0.4.1 [2011-04-02] o Now generateCache() utilizes a generic function getChecksum() to obtain the checksum. This makes it possible to customize how checksums are calculated for different classes of objects. o Added a default getChecksum() which utilizes digest::digest(). o Added getChecksum() for the Object, which first clears the cache of the object and the calls the default ditto. o Added trial version of evalWithMemoization(). o BUG FIX: clearCache() would also report on subdirectories. Version: 0.4.0 [2011-02-14] o Added trial versions of memoizedCall() and addMemoization(). Version: 0.3.0 [2010-03-13] o Added a NAMESPACE. Version: 0.2.0 [2009-10-16] o BUG FIX: In R v2.10.0 and newer, we would get an error reporting that internal function loadFromConn() does not exists. Version: 0.1.9 [2009-09-11] o Added argument 'onError' to loadCache(), to specify the action when an error occurs. The default used to be to print the error message (onError="print"), but now the default is to generate a warning ("warning"). The other alternatives are do silently ignore it, or to throw the error ("error"). Except for onError="error", loadCache() always returns NULL if an error occurs. Version: 0.1.8 [2009-08-11] o ROBUSTNESS: Added sanity check to readCacheHeader() testing that the read header identifier is non-empty. This results in a clearer error message that before. o Now readCacheHeader() reports the "pathname" in error/warnings messages, if argument 'file' refers to a file and the "description" if it refers to a connection. o CLEAN UP: Renamed the HISTORY file to NEWS. Version: 0.1.7 [2008-02-27] o Added option to updated the "last-modified" timestamp of cache files whenever they are loaded via loadCache(). This will help identified what cache files have not been used for a long time. To turn this on, use options("R.cache::touchOnLoad"=TRUE). o Now error messages specifies the pathname, if available. o BUG FIX: The throw() for invalid identifiers was trying to put the connection object in the output and not the identifier. Version: 0.1.6 [2007-07-02] o Now environments, in addition to lists, may be used as keys for generating cache names. o Package passes R CMD check on R v2.6.0 devel. Minor mods. Version: 0.1.5 [2007-03-11] o Added getCacheRootPath() to the help index page. o Package passes R CMD check on R v2.5.0. Version: 0.1.4 [2007-03-07] o Added getCacheRootPath() and setCacheRootPath() to specify where the root of the file path is located. Version: 0.1.3 [2007-01-24] o Now saveCache() and loadCache() takes optional argument 'dirs' for caching data to subdirectories of the root cache directory. o Added setCacheRootPath() to set the root cache directory. Version: 0.1.2 [2006-05-25] o Added argument 'pathname' to loadCache() in order to load "unknown" cache files for which the key is unknown. o BUG FIX: Work around for not saving "promises" (non-evaluated arguments) in base::save(), which otherwise includes all of the surrounding environment if 'sources' is not evaluated/missing. For more details see code and my email to r-devel on 2006-05-25. Thanks to Brian Ripley for explaining what was going on. Version: 0.1.1 [2006-05-22] o Added header comment for file format > v0.1. o Added detection of file format version. o Added readCacheHeader(). Version: 0.1.0 [2005-12-16] o Using a special binary file format now. It allows you to check if cache is up-to-date to a source file. If not, the rest of the cache binary file is not loaded. o Added loadCache() and saveCache() methods. o Created. R.cache-0.12.0/R/000077500000000000000000000000001262113323700132365ustar00rootroot00000000000000R.cache-0.12.0/R/000.R000077500000000000000000000003131262113323700136600ustar00rootroot00000000000000## Look for existing generic functions also in imported namespaces. ## This will affect whether setGenericS3() creates a generic function ## or not. options("R.methodsS3:checkImports:setGenericS3"=TRUE) R.cache-0.12.0/R/006.fixVarArgs.R000077500000000000000000000005041262113323700157430ustar00rootroot00000000000000# Added '...' to some base functions. These will later be # turned into default functions by setMethodS3(). ############################################################################ # HISTORY: # 2005-12-06 # o Created to please R CMD check. ############################################################################ R.cache-0.12.0/R/999.NonDocumentedObjects.R000077500000000000000000000020051262113323700177660ustar00rootroot00000000000000###########################################################################/** # @RdocDocumentation "Non-documented objects" # # % File cache # # % Class Object # @alias getChecksum.Object # # % Misc. # @alias .textPrompt # # \description{ # This page contains aliases for all "non-documented" objects that # \code{R CMD check} detects in this package. # # Almost all of them are \emph{generic} functions that have specific # document for the corresponding method coupled to a specific class. # Other functions are re-defined by \code{setMethodS3()} to # \emph{default} methods. Neither of these two classes are non-documented # in reality. # The rest are deprecated methods. # } # # @author # # @keyword internal #*/########################################################################### ############################################################################ # HISTORY: # 2005-05-26 # o Created to please R CMD check. ############################################################################ R.cache-0.12.0/R/999.package.R000077500000000000000000000037311262113323700153140ustar00rootroot00000000000000#########################################################################/** # @RdocPackage R.cache # # \description{ # @eval "getDescription(R.cache)" # } # # \section{Installation and updates}{ # To install this package and all of its dependent packages, do: # \code{install.packages("R.cache")} # } # # \section{To get started}{ # \itemize{ # \item{\link{loadCache}, \link{saveCache}}{ # Methods for loading and saving objects from and to the cache. # } # \item{\link{getCacheRootPath}, \link{setCacheRootPath}}{ # Methods for getting and setting the directory where cache # files are stored. # } # } # } # # \section{How to cite this package}{ # Whenever using this package, please cite [1] as # # @howtocite "R.oo" # } # # \section{Wishlist}{ # Here is a list of features that would be useful, but which I have # too little time to add myself. Contributions are appreciated. # \itemize{ # \item Add a functionality to identify cache files that are # no longer of use. For now, there is an extra header field # for arbitrary comments which can be used, but maybe more # formal fields are useful, e.g. keywords, user, etc? # } # # If you consider implement some of the above, make sure it is not # already implemented by downloading the latest "devel" version! # } # # \section{Related work}{ # See also the \pkg{filehash} package, and the \code{cache()} function # in the \pkg{Biobase} package of Bioconductor. # } # # @author # # \section{License}{ # The releases of this package is licensed under # LGPL version 2.1 or newer. # # The development code of the packages is under a private licence # (where applicable) and patches sent to the author fall under the # latter license, but will be, if incorporated, released under the # "release" license above. # } # # \section{References}{ # [1] @include "../incl/BengtssonH_2003.bib.Rdoc" \cr # } #*/######################################################################### R.cache-0.12.0/R/Object.getChecksum.R000066400000000000000000000011151262113323700170260ustar00rootroot00000000000000setMethodS3("getChecksum", "Object", function(object, ...) { object <- clearCache(object); NextMethod("getChecksum", object=object); }, export=FALSE) ############################################################################ # HISTORY: # 2014-02-03 # o ROBUSTNESS, now passing the first/dispatch argument (named 'object') # to argument 'object' of NextMethod() as a named argument, which just # happens to be of the same names. # 2011-04-02 # o Added getChecksum() for the Object class. # o Created. ############################################################################ R.cache-0.12.0/R/addMemoization.R000066400000000000000000000044611262113323700163320ustar00rootroot00000000000000#########################################################################/** # @RdocDefault addMemoization # # @title "Creates a copy of an existing function such that its results are memoized" # # \description{ # @get "title". # } # # @synopsis # # \arguments{ # \item{fcn}{A @function (or the name of a function) that should be # copied and have memoization added.} # \item{envir}{The @environment from where to look for the function.} # \item{...}{Additional arguments for controlling the memoization, # i.e. all arguments of @see "memoizedCall" that are not passed # to @see "base::do.call".} # } # # \value{ # Returns a @function. # } # # \details{ # The new function is setup such that the the memoized call is done # in the environment of the caller (the parent frame of the function). # # If the @function returns @NULL, that particular function call is # \emph{not} memoized. # } # # @author # # \seealso{ # The returned function utilized @see "memoizedCall" internally. # } # # @keyword "programming" # @keyword "IO" #*/######################################################################### setMethodS3("addMemoization", "default", function(fcn, envir=parent.frame(), ...) { # Argument 'fcn': if (is.character(fcn)) { if (!exists(fcn, mode="function", envir=envir, inherits=TRUE)) { throw("Argument 'fcn' is not an existing function: ", fcn); } fcn <- get(fcn, mode="function", envir=envir, inherits=TRUE); } if (!is.function(fcn)) { throw("Argument 'fcn' is not a function: ", mode(fcn)); } # Already memoized? if (inherits(fcn, "MemoizedFunction")) { return(fcn) } # Record the argument specific to memoizedCall(). memArgs <- list(...); res <- function(..., envir=parent.frame()) { args <- list(fcn, ..., envir=envir); args <- c(args, memArgs); do.call("memoizedCall", args=args); } class(res) <- c("MemoizedFunction", class(res)) res }) # addMemoization() ####################################################################### # HISTORY: # 2014-09-10 # o ROBUSTNESS: addMemoization() will no longer memoize an already # memoized function. # 2011-02-14 # o Added addMemoization(). ####################################################################### R.cache-0.12.0/R/addREADME.R000066400000000000000000000010751262113323700147720ustar00rootroot00000000000000.addREADME <- function(to=getCacheRootPath(), ...) { # Add a README.txt to cache root (expaining what the directory is) filename <- "README.txt"; pathnameD <- file.path(to, filename); if (!isFile(pathnameD)) { pathnameS <- system.file("_Rcache", filename, package="R.cache"); file.copy(pathnameS, pathnameD); } } # .addREADME() ############################################################################ # HISTORY: # 2012-11-28 # o Added internal .addREADME(). # o Created. ############################################################################ R.cache-0.12.0/R/clearCache.R000077500000000000000000000125431262113323700154030ustar00rootroot00000000000000#########################################################################/** # @RdocDefault clearCache # # @title "Removes all files in a cache file directory" # # \description{ # @get "title". # } # # @synopsis # # \arguments{ # \item{path}{A @character string specifying the directory to be cleared. # By default, the path is what is returned by @see "getCachePath" # which arguments \code{...} are also passed.} # \item{...}{Arguments passed to @see "getCachePath", especially # argument \code{dirs} to specify subdirectories.} # \item{recursive}{If @TRUE, subdirectories are also removed, otherwise # just the files in the specified directory.} # \item{prompt}{If @TRUE, the user will be prompted to confirm that # the directory will cleared before files are removed.} # } # # \value{ # Returns (invisibly) a @character @vector of pathnames of the # files removed. If no files were removed, @NULL is returned. # } # # @author # # \details{ # If the specified directory does not exists, an exception is thrown. # } # # @keyword "programming" # @keyword "IO" # @keyword "internal" #*/######################################################################### setMethodS3("clearCache", "default", function(path=getCachePath(...), ..., recursive=FALSE, prompt=TRUE && interactive()) { # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Validate arguments # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Argument 'recursive': recursive <- Arguments$getLogical(recursive); # Argument 'path': path <- Arguments$getReadablePath(path, mustExist=TRUE); # Argument 'prompt': prompt <- Arguments$getLogical(prompt); # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Find files to be removed # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - allFiles <- listDirectory(path, allNames=TRUE, fullNames=TRUE, recursive=recursive); # Exclude '.' and '..' (just in case; listDirectory() shouldn't return them) excl <- grep("[.][.]*$", allFiles); if (length(excl) > 0L) allFiles <- allFiles[-excl]; # Exclude 'README.txt' excl <- grep("README.txt$", allFiles); if (length(excl) > 0L) allFiles <- allFiles[-excl]; nbrOfFiles <- length(allFiles); if (nbrOfFiles == 0L) { if (prompt) { message("Nothing to clear. Cache directory is empty: ", path, "\n", sep=""); } return(invisible(NULL)); } # Identify files and directories isdir <- file.info(allFiles)$isdir; dirs <- allFiles[isdir]; files <- allFiles[!isdir]; # Remove subdirectories before parent ones. o <- order(nchar(dirs), decreasing=TRUE); dirs <- dirs[o]; # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Prompt user? # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (prompt) { answer <- "."; while (!(answer %in% c("y", "n", ""))) { message(sprintf("Are you really sure you want to delete the %d files and %d directories in '%s'? [y/N]: ", length(files), length(dirs), path)); answer <- tolower(readline()); } if (answer != "y") { return(invisible(NULL)); } } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Remove files and directories # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # (a) Remove files removed <- file.remove(files); filesR <- files[!removed]; # (b) Remove subdirectories # Here we could use unlink(..., recursive=TRUE), but it is # SUPER-DUPER DANGEROUS to do that, because it may spawn off a # recursive deletion in a different place (in case there is a # bug or an inconsistency in list.files() etc), but also if we # forget to drop '.' and '..' from list.files(). /HB 2012-11-28 removed <- sapply(dirs, FUN=function(dir) { filesT <- list.files(path=dir, all.files=TRUE); filesT <- setdiff(filesT, c(".", "..")); # Remove only empty directories if (length(filesT) > 0L) return(FALSE); removeDirectory(dir); }); dirsR <- dirs[!removed]; # Files and directories removed files <- sort(setdiff(files, filesR)); dirs <- sort(setdiff(dirs, dirsR)); # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Report results? # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (prompt) { msg <- sprintf("Cache cleared. Removed %d files and %d directories", length(files), length(dirs)); if (length(filesR) + length(dirsR) > 0L) { msg <- sprintf("%s, but failed to remove another %d files and another %d directories", msg, length(filesR), length(dirsR)); } message(sprintf("%s.\n", msg)); } # Add a README.txt file, if missing. .addREADME(); invisible(c(dirs, files)); }) ############################################################################ # HISTORY: # 2012-11-28 # o GENERALIZATION: Now clearCache(..., recursive=TRUE) removes all # cache files in subdirectories too. The actual subdirectories are # not removed. # 2012-11-27 # o BUG FIX: clearCache() would give error "object 'dirs' not found". # 2011-05-19 # o Added Rdoc comments. # 2011-04-02 # o BUG FIX: clearCache() would also report on subdirectories. # 2005-12-09 # o BUG FIX: 'prompt=FALSE' would not clear cache. # 2005-12-07 # o Created. ############################################################################ R.cache-0.12.0/R/evalWithMemoization.R000066400000000000000000000050141262113323700173600ustar00rootroot00000000000000#########################################################################/** # @RdocFunction evalWithMemoization # # @title "Evaluates an R expression with memoization" # # \description{ # @get "title" such that the same objects are assigned to the # current environment and the same result is returned, if any. # } # # @synopsis # # \arguments{ # \item{expr}{The @expression to be evaluated.} # \item{key}{Additional objects to uniquely identify the evaluation.} # \item{...}{Additional arguments passed to @see "loadCache" # and @see "saveCache".} # \item{envir}{The @environment in which the expression should # be evaluated.} # \item{force}{If @TRUE, existing cached results are ignored.} # } # # \value{ # Returns the value of the evaluated \code{expr} @expression, if any. # } # # @examples "../incl/evalWithMemoization.Rex" # # @author # # \seealso{ # Internally, @see "base::eval" is used to evaluate the expression. # } # # @keyword "programming" # @keyword "IO" #*/######################################################################### evalWithMemoization <- function(expr, key=NULL, ..., envir=parent.frame(), force=FALSE) { expr <- substitute(expr); # Setup a unique list of keys key <- c(list(expr=expr), key); # Look for cached results resList <- loadCache(key=key, ...); if (!force && !is.null(resList)) { # Attach all objects memoized during the evaluation attachLocally(resList$envir, envir=envir); # Return the results of the memoized evaluation return(resList$result); } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Evaluate expression # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Evaluate the expression in a temporary environment, so that # we memoize all objects created along with the results. env <- new.env(parent=envir); res <- eval(expr, envir=env); # NOTE: For some unknown reason does attachLocally() set # the fields inside 'env' to NULL. /HB 2011-04-02 fields <- ls(envir=env, all.names=TRUE); for (field in fields) { assign(field, get(field, envir=env), envir=envir); } # Cache results resList <- list(envir=env, results=res); saveCache(resList, key=key, ...); res; } # evalWithMemoization() ####################################################################### # HISTORY: # 2011-04-01 # o Added evalWithMemoization(). ####################################################################### R.cache-0.12.0/R/findCache.R000077500000000000000000000033451262113323700152350ustar00rootroot00000000000000#########################################################################/** # @RdocDefault findCache # # @title "Locates a cache file" # # \description{ # @get "title" from a key object. # } # # @synopsis # # \arguments{ # \item{key}{An optional object from which a hexadecimal hash # code will be generated and appended to the filename.} # \item{...}{Additional argument passed to @see "generateCache".} # } # # \value{ # Returns the pathname as a @character, or @NULL if the no cached # data exists. # } # # @author # # \seealso{ # @see "generateCache". # @see "loadCache". # } # # @keyword "programming" # @keyword "IO" # @keyword "internal" #*/######################################################################### setMethodS3("findCache", "default", function(key=NULL, ...) { # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Generate cache name from basename and hash object. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - pathname <- generateCache(key=key, ...); if (file.exists(pathname) && !file.info(pathname)$isdir) { return(pathname); } pathnameT <- sprintf("%s.gz", pathname); if (file.exists(pathnameT) && !file.info(pathnameT)$isdir) { return(pathnameT); } return(NULL); }) ############################################################################ # HISTORY: # 2011-08-16 # o ROBUSTNESS: Now findCache() asserts that any identified cache # file is really a file. # o Now findCache() detects also *.gz files. # 2007-01-24 # o Added Rdoc comments. # o Removed non-used argument 'commentPattern'. # 2005-12-09 # o Removed 'file' argument. # 2005-12-06 # o Created. ############################################################################ R.cache-0.12.0/R/generateCache.R000077500000000000000000000041561262113323700161100ustar00rootroot00000000000000#########################################################################/** # @RdocDefault generateCache # # @title "Generates a cache pathname from a key object" # # \description{ # @get "title". # } # # @synopsis # # \arguments{ # \item{key}{A @list or an @environment from which a @character string # checksum will be calculated and that will constitute the name part # of the cache filename.} # \item{suffix}{A @character string to be appended to the end of the # filename.} # \item{...}{Arguments passed to @see "getCachePath".} # } # # \value{ # Returns the pathname as a @character string. # } # # @author # # \seealso{ # Internally, the generic function @see "getChecksum" is used to # calculate the checksum of argument \code{key}. # } # # @keyword "programming" # @keyword "IO" # @keyword "internal" #*/######################################################################### setMethodS3("generateCache", "default", function(key, suffix=".Rcache", ...) { # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Validate arguments # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Argument 'key': if (!is.list(key) && !is.environment(key)) { throw("Argument 'key' must be a list, an environment: ", class(key)[1L]); } # Generate cache name from hash code of key object cacheName <- getChecksum(key); # Add cache directory or pathname path <- getCachePath(...); cacheName <- file.path(path, cacheName); # Add suffix cacheName <- paste(cacheName, suffix, sep=""); cacheName; }, export=FALSE) ############################################################################ # HISTORY: # 2014-01-13 # o BUG FIX: generateCache(key=NULL) would generate "Error in # file.path(path, cacheName) : object 'cacheName' not found". # 2011-04-01 # o Now generateCache() utilizes a generic function getChecksum() # to obtain the checksum. # 2007-07-02 # o Added support for argument 'key' is an environment. # 2005-12-09 # o Removed 'file' argument. # 2005-12-06 # o Created. ############################################################################ R.cache-0.12.0/R/getCachePath.R000077500000000000000000000044141262113323700157070ustar00rootroot00000000000000#########################################################################/** # @RdocDefault getCachePath # # @title "Gets the path to the file cache directory" # # \description{ # @get "title". # If missing, the directory is created. # } # # @synopsis # # \arguments{ # \item{dirs}{A @character @vector constituting the path to the # cache subdirectory (of the \emph{cache root directory} # as returned by @see "getCacheRootPath") to be used. # If @NULL, the path will be the cache root path.} # \item{path, rootPath}{(Advanced) @character strings specifying the # explicit/default cache path and root cache path.} # \item{...}{Not used.} # } # # \value{ # Returns the path as a @character string. # } # # @author # # \seealso{ # @see "setCachePath". # } # # @keyword "programming" # @keyword "IO" # @keyword "internal" #*/######################################################################### setMethodS3("getCachePath", "default", function(dirs=NULL, path=NULL, rootPath=getCacheRootPath(), ...) { # Get path where to store cache file if (is.null(path)) { # (1) Get/make default path # (a) Get path from options subname <- paste(dirs, collapse="/"); name <- paste("R.cache:cachePath", subname, sep=":"); path <- getOption(name); # (b) If not availble, make on path <- paste(c(rootPath, dirs), collapse=.Platform$file.sep); } else if (!isAbsolutePath(path)) { # (2) Get/make default path path <- file.path(rootPath, path); } # Create missing directory? if (!isDirectory(path)) { mkdirs(path); if (!isDirectory(path)) { throw("Could not create cache directory: ", path); } # Add a README.txt file, if missing. .addREADME(to=rootPath); } path; }) # getCachePath() ############################################################################ # HISTORY: # 2013-12-21 # o Added argument 'path' and 'rootPath' to getCachePath(). # 2012-09-10 # o Renamed the installed .Rcache/ directory to _Rcache/ to avoid # R CMD check NOTEs. # 2011-12-29 # o Now getCachePath() adds a README.txt file to the root path, iff # missing. It explains why the directory structure exists and what # created it. # 2007-01-24 # o Created. ############################################################################ R.cache-0.12.0/R/getCacheRootPath.R000066400000000000000000000033621262113323700165510ustar00rootroot00000000000000#########################################################################/** # @RdocDefault getCacheRootPath # # @title "Gets the root path to the file cache directory" # # \description{ # @get "title". # } # # @synopsis # # \arguments{ # \item{defaultPath}{The default path, if no user-specified directory # has been given.} # \item{...}{Not used.} # } # # \value{ # Returns the path as a @character string. # } # # \examples{ # print(getCacheRootPath()) # } # # @author # # \seealso{ # Too set the directory where cache files are stored, # see @see "setCacheRootPath". # } # # @keyword "programming" # @keyword "IO" #*/######################################################################### setMethodS3("getCacheRootPath", "default", function(defaultPath="~/.Rcache", ...) { # Check for option settings path <- getOption("R.cache::rootPath"); # Backward compatibility if (is.null(path)) { if (is.null(path)) path <- getOption("R.cache.path"); # Check for system environment settings if (is.null(path)) { path <- Sys.getenv("R_CACHE_PATH"); } if (nchar(path) == 0L) { path <- NULL; } if (!is.null(path)) { warning("Use setCacheRootPath() to set the cache path in R.cache."); } } # Otherwise, use argument 'path'. if (is.null(path)) { path <- defaultPath; } path; }) ############################################################################ # HISTORY: # 2011-12-30 # o Add example(getCacheRootPath). # 2007-03-07 # o Made the root path settings internal. Use setCacheRootPath() instead. # 2007-01-24 # o Renamed argument 'create' to 'mkdirs'. # o Added Rdoc comments. # 2005-12-06 # o Created. ############################################################################ R.cache-0.12.0/R/getChecksum.R000066400000000000000000000040471262113323700156300ustar00rootroot00000000000000#########################################################################/** # @RdocDefault getChecksum # # @title "Generates a deterministic checksum for an R object" # # \description{ # @get "title" such that (i) if the same object is used again, then # the same checksum is obtained, and (ii) if another object is used, # then a different checksum is obtained with extremely high probability. # In other words, it is highly unlikely that two different objects # have the same checksum. # } # # @synopsis # # \arguments{ # \item{object}{The object for which a checksum should be calculated.} # \item{...}{Additional arguments passed to @see "digest::digest".} # } # # \value{ # Returns checksum represented as a @character string. # } # # \details{ # Because \code{getChecksum()} is a generic function, # it is possible to provide custom methods for specific # classes of objects. This means that, if a certain class # specifies fields that carry auxillary data, then these # can be excluded from the checksum calculation. # For instance, assume that all objects of class 'TimestampedObject' # contain timestamps specifying when each object was created. # Then a custom \code{getChecksum()} method for this class can # first drop the timestamp and then call the default # \code{getChecksum()} function. # } # # @author # # \seealso{ # Internally, the @see "digest::digest" method is used to calculate # the checksum. # } # # @keyword "programming" # @keyword "IO" # @keyword "internal" #*/######################################################################### setMethodS3("getChecksum", "default", function(object, ...) { digest(object, ...); }) ############################################################################ # HISTORY: # 2013-07-03 # o Now getChecksum() passes '...' to digest(), e.g. argument 'algo'. # 2012-11-17 # o CLEANUP: Removed a require("digest") to avoid loaded the package, # and instead call digest::digest(). # 2011-04-01 # o Created. ############################################################################ R.cache-0.12.0/R/loadCache.R000077500000000000000000000135071262113323700152350ustar00rootroot00000000000000#########################################################################/** # @RdocDefault loadCache # # @title "Loads data from file cache" # # \description{ # @get "title", which is unique for an optional key object. # } # # @synopsis # # \arguments{ # \item{key}{An optional object from which a hexadecimal hash # code will be generated and appended to the filename.} # \item{sources}{Optional source objects. If the cache object has a # timestamp older than one of the source objects, it will be ignored # and removed.} # \item{suffix}{A @character string to be appended to the end of the # filename.} # \item{removeOldCache}{If @TRUE and the cache is older than the # \code{sources}, the cache file is removed, otherwise not.} # \item{pathname}{The pathname to the cache file. If specified, # arguments \code{key} and \code{suffix} are ignored. Note that # this is only needed in order to read a cache file for which # the key is unknown, for instance, in order to investigate # an unknown cache file.} # \item{dirs}{A @character @vector constituting the path to the # cache subdirectory (of the \emph{cache root directory} # as returned by @see "getCacheRootPath") to be used. # If @NULL, the path will be the cache root path.} # \item{...}{Not used.} # \item{onError}{A @character string specifying what the action is # if an exception is thrown.} # } # # \value{ # Returns an \R object or @NULL, if cache does not exist. # } # # \details{ # The hash code calculated from the \code{key} object is a # 32 characters long hexadecimal MD5 hash code. # For more details, see @see "getChecksum". # } # # @author # # @examples "../incl/loadCache.Rex" # # \seealso{ # @see "saveCache". # } # # @keyword "programming" # @keyword "IO" #*/######################################################################### setMethodS3("loadCache", "default", function(key=NULL, sources=NULL, suffix=".Rcache", removeOldCache=TRUE, pathname=NULL, dirs=NULL, ..., onError=c("warning", "print", "quiet", "error")) { # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Validate arguments # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Argument 'onError': onError <- match.arg(onError); # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Find cached file # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (is.null(pathname)) pathname <- findCache(key=key, suffix=suffix, dirs=dirs); if (is.null(pathname)) return(NULL); # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Try to load cached object from file connection # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (!isFile(pathname)) return(NULL); fh <- gzfile(pathname, open="rb"); on.exit({ if (!is.null(fh)) close(fh); }); tryCatch({ header <- readCacheHeader(fh); if (!is.null(sources)) header$sources <- sources; timestamp <- NULL; attachLocally(header); # Attaches 'timestamp' (and 'sources') if (!is.null(timestamp) && !is.null(sources)) { for (sourcePathname in sources) { if (!is.character(sources)) { warning("No timestamp check of cache was performed. Unsupported type of cache source: ", class(sources)[1]); break; } if (!file.exists(sourcePathname)) { warning("No timestamp check of cache was performed. Source file not found: ", sourcePathname); break; } # Is source file newer than cache? lastModified <- file.info(sourcePathname)$mtime; if (lastModified > timestamp) { # Remove out-of-date cache file? if (removeOldCache) { close(fh); fh <- NULL; file.remove(pathname); } return(NULL); } } # for (sourcePathname in sources) } # 4. Load cached object: res <- .baseLoad(con=fh, ...); object <- res$object; res <- NULL; # Not needed anymore # 5. Update the "last-modified" timestamp of the cache file? touch <- getOption("R.cache::touchOnLoad"); touch <- identical(touch, TRUE); if (touch) { touchFile(pathname); } # 6. Return cached object return(object); }, error = function(ex) { if (onError == "print") { print(ex); } else if (onError == "warning") { warning(ex); } else if (onError == "error") { stop(ex); } }) NULL; }) ############################################################################ # HISTORY: # 2012-09-10 # o Updated readCacheHeader() to utilize updated .baseLoad(). # 2011-08-16 # o Added support for loading gzip compressed cache files. # 2009-10-16 # o Now calling an internal .baseLoad() function of the package. # 2009-09-11 # o Added argument 'onError' to loadCache(), to specify the action when # an error occurs. The default used to be to print the error message # (onError="print"), but now the default is to generate a warning # ("warning"). The other alternatives are do silently ignore it, or # to throw the error ("error"). Except for onError="error", loadCache() # always returns NULL if an error occurs. # 2008-02-27 # o Added option to updated the "last-modified" timestamp of cache files # whenever they are loaded via loadCache(). # 2008-02-14 # o Now errors reports the pathname, if available. # 2006-08-09 # o Added link to cache() in Biobase. # 2006-05-25 # o Added argument 'pathname' to make it possible to load a cache file # explicitly. # 2006-04-04 # o Added header comment for file format > v0.1. # o Added detection of file format version. # 2005-12-09 # o Added support for internal 'cache' and 'timestamp' objects. # 2005-12-06 # o Created. ############################################################################ R.cache-0.12.0/R/memoizedCall.R000066400000000000000000000044641262113323700157760ustar00rootroot00000000000000#########################################################################/** # @RdocDefault memoizedCall # # @title "Calls a function with memoization" # # \description{ # @get "title", that is, caches the results to be retrieved if # the function is called again with the exact same arguments. # } # # @synopsis # # \arguments{ # \item{what}{The @function to be called, or a @character string # specifying the name of the function to be called, # cf. @see "base::do.call".} # \item{...}{Arguments passed to the function.} # \item{envir}{The @environment in which the function is evaluated.} # \item{force}{If @TRUE, any cached results are ignored, otherwise not.} # \item{sources, dirs}{Optional arguments passed to # @see "loadCache" and @see "saveCache".} # } # # \value{ # Returns the result of the function call. # } # # \details{ # If the @function returns @NULL, that particular function call is # \emph{not} memoized. # } # # @author # # \seealso{ # Internally, @see "loadCache" is used to load memoized results, # if available. If not available, then @see "do.call" is used to # evaluate the function call, # and @see "saveCache" is used to save the results to cache. # } # # @keyword "programming" # @keyword "IO" #*/######################################################################### setMethodS3("memoizedCall", "default", function(what, ..., envir=parent.frame(), force=FALSE, sources=NULL, dirs=NULL) { # 1. Generate cache file key <- list(what=what, ...); pathnameC <- generateCache(key=key, dirs=dirs); # 1. Look for memoized results if (!force) { res <- loadCache(pathname=pathnameC, sources=sources); if (!is.null(res)) return(res) } # 2. Otherwise, call method with arguments res <- do.call(what, args=list(...), quote=FALSE, envir=envir); # 3. Memoize results saveCache(res, pathname=pathnameC, sources=sources); # 4. Return results res; }) # memoizedCall() ####################################################################### # HISTORY: # 2015-02-27 # o SPEEDUP: Now memoizedCall() generates cache pathname only once. # 2011-02-14 # o Added argument 'sources' to memoizedCall(). # 2011-02-13 # o Created. ####################################################################### R.cache-0.12.0/R/private.assertDigest.R000066400000000000000000000047611262113323700175030ustar00rootroot00000000000000.assertDigest <- function(onDiff=c("error", "warning", "message"), ...) { # Argument 'onDiff': onDiff <- match.arg(onDiff); # Value to validate against d1 <- digest(0); # Get the "truth" ver <- packageVersion("digest"); if (ver <= "0.2.3") { d0 <- "78a10a7e5929f8c605f71823203c0dc5"; } else if (ver >= "0.3.0") { d0 <- "908d1fd10b357ed0ceaaec823abf81bc"; } else { msg <- sprintf("No assertion rule available for digest v%s. Names of cache files might differ between R version and platforms.", ver); warning(msg); return(); } # Assert that we get the above results on the current machine. if (!identical(d1, d0)) { msg <- sprintf("Assertion failed: Detected inconsistency in digest::digest(0) (%s != %s) using digest v%s. The effect of this is that the generated cache files will be named differently on this platform/R version than in another.", d1, d0, ver); if (onDiff == "error") { throw(msg); } else if (onDiff == "warning") { warning(msg); } else { message(msg); } } } # .assertDigest() ############################################################################ # HISTORY: # 2013-08-03 # o BUG FIX: R.cache:::.assertDigest() called from within another package # would give an error that packageVersion() of 'utils' was not found. # 2012-11-17 # o Moved .assertDigest() from aroma.core to R.cache and tidied it up. # 2007-04-04 # o BUG FIX: The test for version of digest and the assignment of the # conditional patch must be done in .First.lib() and not here. Anything # put there such as if() statements will be evaluated during the build # of the package. # 2007-03-08 # o Prepared the digest() patch and .assertDigest() for the upcoming # digest v0.3.0. This will make the package work with both digest # v0.2.3 and v0.3.0, which is needed until everyone upgrade. # o Thanks to Luke Tierney's reply on my r-devel question of the serialize # header, we now look for the 4th newline, which is more robust to do # when serializing to ASCII. # 2007-03-07 # o Added .assertDigest(). # o BUG FIX: serialize() gives different results depending on R version. # The difference seems to be in raw bytes 8, 9 and 10. In other words, # if those are excluded before passing the stream on to the "digester" # we get the same results. From testing with "random" object we also # know that there are at most 18 bytes in the header. # 2007-01-06 # o Created. ############################################################################ R.cache-0.12.0/R/private.baseLoad.R000066400000000000000000000104161262113323700165460ustar00rootroot00000000000000###########################################################################/** # @eval "{.baseLoad <<- R.cache:::.baseLoad; ''}" # @RdocFunction ".baseLoad" # # @title "Loads an object from a file connection" # # \description{ # @get "title" similar to @see "base::load", but without resetting # file connections (to position zero). # # \emph{WARNING: This is an internal function that should not be # called by anything but the internal code of the \pkg{R.cache} package.} # } # # @synopsis # # \arguments{ # \item{con}{A @connection.} # \item{envir}{An @environment where the loaded object will be stored.} # } # # \value{ # Returns (invisible) a @character @vector of the names of objects # loaded. # } # # \details{ # The reason why it is not possible to use @see "base::load" is that # that resets the file position of the connection before trying to # load the object. # The reason why that happens is because when you pass a regular file # connection to @see "base::load" it gets coerced via @see "base::gzcon", # which is the function that resets the file position. # # The workaround is to creat a local copy of \code{base::load()} and # modify it by dropping the \code{gzcon()} coersion. This is possible # because this function, that is \code{.baseLoad()}, is always called # with a \code{gzfile()} @connection. # } # # \seealso{ # This function is used by @see "loadCache" and @see "readCacheHeader". # } # # @keyword internal #*/########################################################################### .baseLoad <- function(con, envir=parent.frame()) { # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Assert correctness of connection # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - magic <- readChar(con, nchars=5, useBytes=TRUE); if (regexpr("RD[AX]2\n", magic) == -1L) { if (regexpr("RD[ABX][12]\r", magic) == 1L) { stop("input has been corrupted, with LF replaced by CR"); } else { stop(gettextf("file '%s' has magic number '%s'\n Use of save versions prior to 2 is deprecated", summary(file)$description, gsub("[\n\r]*", "", magic))); } } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Load object from connection # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - res <- readRDS(con); } # .baseLoad() ############################################################################ # HISTORY: # 2012-09-10 # o CRAN POLICY: Updated internal .baseLoad() to utilize readRDS() instead # of .Internal(loadFromConn2(...)) such that it still reads the same # file format. # 2012-03-20 # o Added an Rdoc comment explaining the .baseLoad() function. # o CRAN POLICY: Previously .baseLoad() called .Internal(loadFromConn2(...)) # which is no longer allowed for CRAN packages. However, there is # still the problem of base::load(con) coercing a file connection via # gzcon() and while doing that it also resets the file position, which # we do not want. The workaround is not to do dynamic code computation # on base::load() code and create an adjusted just-in-time local version # that avoids the gzcon() coercion. # 2011-10-05 # o BUG FIX: Same bug fix as on 2011-08-31 but now also for R v2.13.0. # 2011-08-31 # o BUG FIX (for R v2.12.2 and before): After adding support for # compressed files in R.cache v0.5.0, we would get the 'Error in # seek.connection(con, origin = "current", where = -5) : whence = "end" # is not implemented for gzfile connections' in readCacheHeader() # iff running R v2.12.2 or before. # 2009-10-16 # o BUG FIX: In R v2.10.0 and newer, we would get an error reporting that # internal function loadFromConn() does not exists. That function was # used because it would read the stream from the position after the magic # string in the connection. We now use loadFromConn2() which tries to # read and validate the magic string. So, we have to make sure that the # connection is positioned where the magic string is. We do this using # seek(). We also note that we could have used loadFromConn2() already # since R v2.3.0. Since this package requires R v2.3.0, we simply drop # the old implementation and use this new one. # o Created. ############################################################################ R.cache-0.12.0/R/readCacheHeader.R000077500000000000000000000071031262113323700163350ustar00rootroot00000000000000#########################################################################/** # @RdocDefault readCacheHeader # # @title "Loads data from file cache" # # \description{ # @get "title", which is unique for an optional key object. # } # # @synopsis # # \arguments{ # \item{file}{A filename or a @connection.} # \item{...}{Not used.} # } # # \value{ # Returns a named @list structure with element \code{identifier}, # \code{version}, \code{comment} (optional), \code{sources} (optional), # and \code{timestamp}. # } # # @author # # @examples "../incl/readCacheHeader.Rex" # # \seealso{ # @see "findCache". # @see "loadCache". # @see "saveCache". # } # # @keyword "programming" # @keyword "IO" # @keyword "internal" #*/######################################################################### setMethodS3("readCacheHeader", "default", function(file, ...) { # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Validate arguments # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Argument 'file': if (inherits(file, "connection")) { pathname <- sprintf("'%s' [description of the opened connection]", summary(file)$description); } else { pathname <- as.character(file); if (!isFile(pathname)) throw("Argument 'file' is not an existing file: ", pathname); file <- gzfile(pathname, open="rb"); on.exit({ if (!is.null(file)) close(file); }); } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Try to load cached object from file connection # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - header <- list(); # 1a. Load identifier: id <- readChar(con=file, nchars=64L); if (length(id) == 0L) { throw("Rcache file format error. Read empty header identifier: ", pathname); } pattern <- "^Rcache v([0-9][0-9]*[.][0-9][0-9]*([.][0-9][0-9]*)*).*"; if (regexpr(pattern, id) == -1L) { throw("Rcache file format error ('", pathname, "'). Invalid identifier: ", id); } header$identifier <- id; # 1b. Get version header$version <- gsub(pattern, "\\1", id); # 1c. Read trailing '\0'. dummy <- readBin(con=file, what=integer(), size=1, n=1); # 2a. Load comment if (compareVersion(header$version, "0.1") > 0L) { nchars <- readBin(con=file, what=integer(), size=4L, n=1L); header$comment <- readChar(con=file, nchars=nchars); } # 2b. Read trailing '\0'. dummy <- readBin(con=file, what=integer(), size=1L, n=1L); # 3. Load sources: sources <- NULL; # To please 'codetools' in R v2.6.0 res <- .baseLoad(con=file, ...); header$sources <- res$sources; # 4. Load timestamp: res <- .baseLoad(con=file, ...); header$timestamp <- res$timestamp; header; }) ############################################################################ # HISTORY: # 2012-09-10 # o Updated readCacheHeader() to utilize updated .baseLoad(). # 2011-08-16 # o Added support for reading gzip compressed cache files. # 2009-10-16 # o Now calling an internal .baseLoad() function of the package. # 2009-08-11 # o Now readCacheHeader() reports the "pathname" in error/warnings messages, # if argument 'file' refers to a file and the "description" if it refers # to a connection. # 2009-07-29 # o ROBUSTNESS: Added sanity check to readCacheHeader() testing that the # read header identifier is non-empty. # 2008-02-14 # o BUG FIX: The throw() for invalid identifiers was trying to put the # connection object is the out and not the identifier. # 2006-04-04 # o Created. ############################################################################ R.cache-0.12.0/R/saveCache.R000077500000000000000000000115511262113323700152510ustar00rootroot00000000000000#########################################################################/** # @RdocDefault saveCache # # @title "Saves data to file cache" # # \description{ # @get "title", which is unique for an optional key object. # } # # @synopsis # # \arguments{ # \item{object}{The object to be saved to file.} # \item{key}{An optional object from which a hexadecimal hash # code will be generated and appended to the filename.} # \item{sources}{Source objects used for comparison of timestamps when # cache is loaded later.} # \item{suffix}{A @character string to be appended to the end of the # filename.} # \item{comment}{An optional @character string written in ASCII at the # beginning of the file.} # \item{pathname}{(Advanced) An optional @character string specifying # the pathname to the cache file. If not specified (default), a unique # one is automatically generated from arguments \code{key} and # \code{suffix} among other things.} # \item{dirs}{A @character @vector constituting the path to the # cache subdirectory (of the \emph{cache root directory} # as returned by @see "getCacheRootPath") to be used. # If @NULL, the path will be the cache root path.} # \item{compress}{If @TRUE, the cache file will be saved using # gzip compression, otherwise not.} # \item{...}{Additional argument passed to @see "base::save".} # } # # \value{ # Returns (invisible) the pathname of the cache file. # } # # \section{Compression}{ # The \code{saveCache()} method saves a compressed cache file # (with filename extension *.gz) if argument \code{compress} is @TRUE. # The @see "loadCache" method locates (via @see "findCache") and # loads such cache files as well. # } # # @author # # \examples{\dontrun{For an example, see ?loadCache}} # # \seealso{ # For more details on how the hash code is generated etc, @see "loadCache". # } # # @keyword "programming" # @keyword "IO" #*/######################################################################### setMethodS3("saveCache", "default", function(object, key=NULL, sources=NULL, suffix=".Rcache", comment=NULL, pathname=NULL, dirs=NULL, compress=getOption("R.cache::compress", FALSE), ...) { # Argument 'compress': if (!isTRUE(compress)) compress <- FALSE # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Cache file # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (is.null(pathname)) { # Generate cache name from basename and hash object. pathname <- generateCache(key=key, suffix=suffix, dirs=dirs); } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Save to file connection # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (compress) { pathname <- sprintf("%s.gz", pathname); fh <- gzfile(pathname, open="wb"); } else { fh <- file(pathname, open="wb"); } on.exit(close(fh)); # Save 'identifier' identifier <- "Rcache v0.1.7 (R package R.cache by Henrik Bengtsson)"; if (nchar(identifier) > 64L) throw("Internal error. Identifier is too long: ", identifier); tail <- paste(rep(" ", times=64L-nchar(identifier)), collapse=""); identifier <- paste(identifier, tail, sep=""); writeChar(con=fh, identifier, nchars=64L); # Save 'comment' if (is.null(comment)) comment <- ""; writeBin(con=fh, nchar(comment), size=4L); writeChar(comment, con=fh, nchars=nchar(comment)); # Save 'sources' # Look up base::save() once; '::' is expensive base_save <- base::save; # If 'sources' is not evaluated, it is a so called promise, which will # make all of its calling environments to be save too. dummy <- is.null(sources); base_save(file=fh, sources, compress=compress, ...); # Save 'timestamp' timestamp <- Sys.time(); base_save(file=fh, timestamp, compress=compress, ...); # Save 'object' base_save(file=fh, object, compress=compress, ...); invisible(pathname); }) ############################################################################ # HISTORY: # 2013-12-21 # o Added argument 'pathname' to saveCache(). # 2011-08-16 # o Added support for gzip compressed cache files. # 2007-01-24 # o Now saveCache() returns the pathname to the cache file. # 2006-05-25 # o BUG FIX: Work around for not saving "promises" (non-evaluated arguments) # in base::save(), which otherwise includes all of the surrounding # environment if 'sources' is not evaluated/missing. For more details # see code and my email to r-devel on 2006-05-25. Thanks to Brian Ripley # for explaining what was going on. # 2006-04-04 # o Added header comment. # 2005-12-09 # o Object save to file is now a structure containing the object to be # cached, a timestamp specifying the it was cached, and a source object. # o Replaced argument 'file' with 'source'. # 2005-12-06 # o Created. ############################################################################ R.cache-0.12.0/R/setCachePath.R000077500000000000000000000022221262113323700157160ustar00rootroot00000000000000#########################################################################/** # @RdocDefault setCachePath # # @title "Sets the path to the file cache directory" # # \description{ # @get "title". # } # # @synopsis # # \arguments{ # \item{dirs}{A @character @vector constituting the path to the # cache subdirectory of interest.} # \item{path}{The path to override the path according to the # \code{dirs} argument.} # \item{...}{Not used.} # } # # \value{ # Returns nothing. # } # # @author # # \seealso{ # @see "getCachePath". # } # # @keyword "programming" # @keyword "IO" # @keyword "internal" #*/######################################################################### setMethodS3("setCachePath", "default", function(dirs=NULL, path=NULL, ...) { subname <- paste(dirs, collapse="/"); name <- paste("R.cache:cachePath", subname, sep=":"); opts <- list(path); names(opts) <- name; ovalue <- options(opts); invisible(ovalue); }, export=FALSE) ############################################################################ # HISTORY: # 2007-01-24 # o Created. ############################################################################ R.cache-0.12.0/R/setCacheRootPath.R000066400000000000000000000030501262113323700165570ustar00rootroot00000000000000#########################################################################/** # @RdocDefault setCacheRootPath # # @title "Sets the root path to the file cache directory" # # \description{ # @get "title". # By default, this function will set it to \code{~/.Rcache/}. # } # # @synopsis # # \arguments{ # \item{path}{The path.} # \item{...}{Not used.} # } # # \value{ # Returns (invisibly) the old root path. # } # # @author # # \seealso{ # @see "getCacheRootPath". # } # # @keyword "programming" # @keyword "IO" #*/######################################################################### setMethodS3("setCacheRootPath", "default", function(path="~/.Rcache", ...) { path <- as.character(path); if (!isDirectory(path)) { mkdirs(path); if (!isDirectory(path)) { throw("Could not create cache directory: ", path); } } # Add a README.txt file, if missing. .addREADME(to=path); ovalue <- options("R.cache::rootPath"=path); invisible(ovalue); }) # setCacheRootPath() ############################################################################ # HISTORY: # 2012-09-10 # o Renamed the installed .Rcache/ directory to _Rcache/ to avoid # R CMD check NOTEs. # 2011-12-29 # o Now setCacheRootPath() adds a README.txt file to the root path, iff # missing. It explains why the directory structure exists and what # created it. # 2007-03-07 # o Changed the default root path to ~/.Rcache/ # 2007-01-24 # o Renamed from setCachePath(). # 2005-12-07 # o Created. ############################################################################ R.cache-0.12.0/R/setupCacheRootPath.R000066400000000000000000000052101262113323700171240ustar00rootroot00000000000000#########################################################################/** # @RdocDefault setupCacheRootPath # # @title "Interactively offers the user to set up the default root path" # # \description{ # @get "title". # } # # @synopsis # # \arguments{ # \item{defaultPath}{Default root path to set.} # \item{...}{Not used.} # } # # \value{ # Returns (invisibly) the root path, # or @NULL if running a non-interactive session. # } # # \details{ # If the cache root path is already set, it is used and nothing is done. # If the "default" root path (\code{defaultPath}) exists, it is used, # otherwise, if running interactively, the user is asked to approve # the usage (and creation) of the default root path. # In all other cases, the cache root path is set to a session-specific # temporary directory. # } # # @author # # \seealso{ # Internally, @see "setCacheRootPath" is used to set the cache root path. # The @see "base::interactive" function is used to test whether \R is # running interactively or not. # } # # @keyword "programming" # @keyword "IO" # @keyword "internal" #*/######################################################################### setMethodS3("setupCacheRootPath", "default", function(defaultPath="~/.Rcache/", ...) { rootPath <- getCacheRootPath(NULL); # If already set, nothing to do. if (!is.null(rootPath)) { return(invisible(rootPath)); } # Use a temporary root path... rootPath <- file.path(tempdir(), ".Rcache"); # unless the default directory exists, ... if (isDirectory(defaultPath)) { rootPath <- defaultPath; } else if (interactive()) { # or we cn ask the user to confirm the default path... prompt <- "The R.cache package needs to create a directory that will hold cache files."; if (identical(defaultPath, "~/.Rcache/")) { prompt <- c(prompt, "It is convenient to use one in the user's home directory, because it remains also after restarting R."); } prompt <- c(prompt, sprintf("Do you wish to create the '%s' directory? If not, a temporary directory (%s) that is specific to this R session will be used.", defaultPath, rootPath)); prompt <- paste(prompt, collapse=" "); tryCatch({ ans <- .textPrompt(prompt=prompt, options=c("Y"="yes", "n"="no")); if (ans == "yes") rootPath <- defaultPath; }, condition=function(ex) {}); } setCacheRootPath(rootPath); rootPath <- getCacheRootPath(); invisible(rootPath); }) # setupCacheRootPath() ############################################################################ # HISTORY: # 2011-12-29 # o Added setupCacheRootPath(). ############################################################################ R.cache-0.12.0/R/textPrompt.R000066400000000000000000000035411262113323700155520ustar00rootroot00000000000000.textPrompt <- function(prompt, options=c("Y"="yes", "n"="no"), caseSensitive=FALSE, maxTries=Inf, type=c("message", "output"), onSink=c("error", "ignore"), ...) { # Argument 'maxTries': maxTries <- Arguments$getNumeric(maxTries, range=c(1,Inf)); # Argument 'onSink': onSink <- match.arg(onSink); # Argument 'type': type <- match.arg(type); # Check if standard output is redirected. # NOTE: There always *2* sinks for type="message", cf. help("sink"). minSink <- switch(type, message=2L, 0L); hasSink <- (sink.number(type=type) > minSink); if (hasSink) { if (onSink == "error") { throw("Cannot prompt user via the standard ", type, ", because it is currently redirected and (most likely) not visible to the user."); } } # How to present the options to the user keys <- names(options); if (is.null(keys)) { keys <- options; } promptF <- sprintf("%s [%s]: ", prompt, paste(keys, collapse="/")); promptR <- gettext("Unknown reply.\n"); # Where to prompt if (type == "output") { con <- stdout(); } else { con <- stderr(); } count <- 0L; while (count < maxTries) { cat(file=con, promptF); ans <- readline(); count <- count + 1L; ans <- trim(ans); if (ans == "") { idx <- 1L; } else { if (caseSensitive) { idx <- pmatch(ans, options); } else { idx <- pmatch(tolower(ans), tolower(options)); } } if (is.finite(idx)) { ans <- options[idx]; break; } cat(file=con, promptR); } # while(...) attributes(ans) <- NULL; ans; } # .textPrompt() ############################################################################ # HISTORY: # 2014-05-01 # o Now argument 'type' defaults to c("message", "output"). # 2011-12-30 # o Added textPrompt(). ############################################################################ R.cache-0.12.0/R/zzz.R000077500000000000000000000012021262113323700142140ustar00rootroot00000000000000## covr: skip=all .onLoad <- function(libname, pkgname) { ns <- getNamespace(pkgname); pkg <- Package(pkgname); assign(pkgname, pkg, envir=ns); # Setup the cache root path, possibly by prompting the user. setupCacheRootPath(); } .onAttach <- function(libname, pkgname) { pkg <- get(pkgname, envir=getNamespace(pkgname)); startupMessage(pkg); } ############################################################################ # HISTORY: # 2013-10-17 # o CLEANUP: autoload("print.Object", package="R.oo") is no longer needed. # 2005-12-09 # o Created. ############################################################################ R.cache-0.12.0/README.md000066400000000000000000000023561262113323700143220ustar00rootroot00000000000000# R.cache: Fast and Light-weight Caching (Memoization) of Objects and Results to Speed Up Computations ## Installation R package R.cache is available on [CRAN](http://cran.r-project.org/package=R.cache) and can be installed in R as: ```r install.packages('R.cache') ``` ## Software status | Resource: | CRAN | Travis CI | Appveyor | | ------------- | ------------------- | ------------- | ---------------- | | _Platforms:_ | _Multiple_ | _Linux_ | _Windows_ | | R CMD check | CRAN version | Build status | Build status | | Test coverage | | Coverage Status | | R.cache-0.12.0/appveyor.yml000066400000000000000000000025071262113323700154310ustar00rootroot00000000000000#---------------------------------------------------------------- # AppVeyor configuration for R packages # # REFERENCES: # * AppVeyor CI: https://ci.appveyor.com/ # * r-travis: https://github.com/craigcitro/r-travis # # Validate your .appveyor.yml file at # https://ci.appveyor.com/tools/validate-yaml #---------------------------------------------------------------- environment: _R_CHECK_FORCE_SUGGESTS_: false # DO NOT CHANGE the "init" and "install" sections below # Download script file from GitHub init: ps: | $ErrorActionPreference = "Stop" Invoke-WebRequest http://raw.github.com/HenrikBengtsson/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1" Import-Module '..\appveyor-tool.ps1' install: ps: Bootstrap # Adapt as necessary starting from here build_script: - echo Current directory=%CD% - travis-tool.sh install_r digest R.methodsS3 R.oo R.utils test_script: - travis-tool.sh run_tests after_test: - 7z a all-Rout.zip *.Rcheck\**\*.Rout *.Rcheck\**\*.fail artifacts: - path: '*.Rcheck\**\*.log' name: Logs - path: '*.Rcheck\**\*.out' name: Logs - path: all-Rout.zip name: AllRout - path: '\*_*.tar.gz' name: Bits - path: '\*_*.zip' name: Bits on_failure: - 7z a failure.zip *.Rcheck\* - appveyor PushArtifact failure.zip R.cache-0.12.0/cran-comments.md000066400000000000000000000021201262113323700161200ustar00rootroot00000000000000# CRAN submission R.cache 0.12.0 on 2015-11-11 Thanks in advance ## Notes not sent to CRAN The package has been verified using `R CMD check --as-cran` on: * Platform x86_64-pc-linux-gnu (64-bit): - R version 3.0.3 (2014-03-06) - R version 3.1.3 (2015-03-09) - R version 3.2.2 (2015-08-14) - R version 3.2.2 Patched (2015-11-06 r69615) - R Under development (unstable) (2015-11-10 r69617) * Platform: x86_64-apple-darwin13.4.0 (64-bit): - R version 3.2.2 Patched (2015-10-22 r69556) * Platform x86_64-w64-mingw32/x64 (64-bit): - R version 3.1.3 (2015-03-09) - R version 3.2.2 Patched (2015-11-05 r69602) - R Under development (unstable) (2015-11-09 r69615) It has also verified using the service. Moreover, the updates cause no issues for any of the following 11 reverse dependency on CRAN and Bioconductor, which have been tested with `R CMD check --as-cran`: aroma.affymetrix 2.14.0, aroma.cn 1.6.1, aroma.core 2.14.0, fulltext 0.1.4, MSnID 1.5.0, PSCBS 0.50.0, QDNAseq 1.7.0, R.filesets 2.9.0, R.rsp 0.20.0, repmis 0.4.4 and scholar 0.1.3. R.cache-0.12.0/incl/000077500000000000000000000000001262113323700137625ustar00rootroot00000000000000R.cache-0.12.0/incl/BengtssonH_2003.bib.Rdoc000077500000000000000000000005471262113323700200550ustar00rootroot00000000000000H. Bengtsson, \emph{The R.oo package - Object-Oriented Programming with References Using Standard R Code}, In Kurt Hornik, Friedrich Leisch and Achim Zeileis, editors, Proceedings of the 3rd International Workshop on Distributed Statistical Computing (DSC 2003), March 20-22, Vienna, Austria. \url{http://www.ci.tuwien.ac.at/Conferences/DSC-2003/Proceedings/}R.cache-0.12.0/incl/evalWithMemoization.Rex000066400000000000000000000026621262113323700204470ustar00rootroot00000000000000for (kk in 1:5) { cat(sprintf("Iteration #%d:\n", kk)) res <- evalWithMemoization({ cat("Evaluating expression...") a <- 1 b <- 2 c <- 4 Sys.sleep(1) cat("done\n") b }) print(res) # Sanity checks stopifnot(a == 1 && b == 2 && c == 4) # Clean up rm(a, b, c) } # for (kk ...) ## OUTPUTS: ## Iteration #1: ## Evaluating expression...done ## [1] 2 ## Iteration #2: ## [1] 2 ## Iteration #3: ## [1] 2 ## Iteration #4: ## [1] 2 ## Iteration #5: ## [1] 2 ############################################################ # WARNING ############################################################ # If the expression being evaluated depends on # "input" objects, then these must be be specified # explicitly as "key" objects. for (ii in 1:2) { for (kk in 1:3) { cat(sprintf("Iteration #%d:\n", kk)) res <- evalWithMemoization({ cat("Evaluating expression...") a <- kk Sys.sleep(1) cat("done\n") a }, key=list(kk=kk)) print(res) # Sanity checks stopifnot(a == kk) # Clean up rm(a) } # for (kk ...) } # for (ii ...) ## OUTPUTS: ## Iteration #1: ## Evaluating expression...done ## [1] 1 ## Iteration #2: ## Evaluating expression...done ## [1] 2 ## Iteration #3: ## Evaluating expression...done ## [1] 3 ## Iteration #1: ## [1] 1 ## Iteration #2: ## [1] 2 ## Iteration #3: ## [1] 3 R.cache-0.12.0/incl/loadCache.Rex000077500000000000000000000012251262113323700163100ustar00rootroot00000000000000simulate <- function(mean, sd) { # 1. Try to load cached data, if already generated key <- list(mean, sd) data <- loadCache(key) if (!is.null(data)) { cat("Loaded cached data\n") return(data); } # 2. If not available, generate it. cat("Generating data from scratch...") data <- rnorm(1000, mean=mean, sd=sd) Sys.sleep(1) # Emulate slow algorithm cat("ok\n") saveCache(data, key=key, comment="simulate()") data; } data <- simulate(2.3, 3.0) data <- simulate(2.3, 3.5) data <- simulate(2.3, 3.0) # Will load cached data # Clean up file.remove(findCache(key=list(2.3,3.0))) file.remove(findCache(key=list(2.3,3.5))) R.cache-0.12.0/incl/readCacheHeader.Rex000077500000000000000000000003471262113323700174210ustar00rootroot00000000000000 data <- 1:120 key <- list(some=1, vari=2, ables=3) saveCache(key=key, data, comment="A simple example of a cached object.") header <- readCacheHeader(findCache(key=key)) print(header) # Clean up file.remove(findCache(key=key)) R.cache-0.12.0/inst/000077500000000000000000000000001262113323700140125ustar00rootroot00000000000000R.cache-0.12.0/inst/_Rcache/000077500000000000000000000000001262113323700153365ustar00rootroot00000000000000R.cache-0.12.0/inst/_Rcache/README.txt000066400000000000000000000006561262113323700170430ustar00rootroot00000000000000This directory structure was created by the R package 'R.cache' available on CRAN [http://cran.r-project.org/package=R.cache]. It holds cache files containing results memoized by various R packages that utilize the R.cache package. It is safe to delete all or part of these files at any time. By definition, if memoized results are missing, they are recalculated by the R package who needs them/created them in the first place. R.cache-0.12.0/man/000077500000000000000000000000001262113323700136105ustar00rootroot00000000000000R.cache-0.12.0/man/000.baseLoad.Rd000066400000000000000000000034561262113323700161170ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % private.baseLoad.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{.baseLoad} \alias{.baseLoad} \title{Loads an object from a file connection} \description{ Loads an object from a file connection similar to \code{\link[base]{load}}(), but without resetting file connections (to position zero). \emph{WARNING: This is an internal function that should not be called by anything but the internal code of the \pkg{R.cache} package.} } \usage{ .baseLoad(con, envir=parent.frame()) } \arguments{ \item{con}{A \code{\link[base:connections]{connection}}.} \item{envir}{An \code{\link[base]{environment}} where the loaded object will be stored.} } \value{ Returns (invisible) a \code{\link[base]{character}} \code{\link[base]{vector}} of the names of objects loaded. } \details{ The reason why it is not possible to use \code{\link[base]{load}}() is that that resets the file position of the connection before trying to load the object. The reason why that happens is because when you pass a regular file connection to \code{\link[base]{load}}() it gets coerced via \code{\link[base]{gzcon}}(), which is the function that resets the file position. The workaround is to creat a local copy of \code{base::load()} and modify it by dropping the \code{gzcon()} coersion. This is possible because this function, that is \code{.baseLoad()}, is always called with a \code{gzfile()} \code{\link[base:connections]{connection}}. } \seealso{ This function is used by \code{\link{loadCache}}() and \code{\link{readCacheHeader}}(). } \keyword{internal} R.cache-0.12.0/man/Non-documented_objects.Rd000077500000000000000000000017601262113323700204760ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % 999.NonDocumentedObjects.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{Non-documented objects} \alias{Non-documented objects} \title{Non-documented objects} % File cache % Class Object \alias{getChecksum.Object} % Misc. \alias{.textPrompt} \description{ This page contains aliases for all "non-documented" objects that \code{R CMD check} detects in this package. Almost all of them are \emph{generic} functions that have specific document for the corresponding method coupled to a specific class. Other functions are re-defined by \code{setMethodS3()} to \emph{default} methods. Neither of these two classes are non-documented in reality. The rest are deprecated methods. } \author{Henrik Bengtsson} \keyword{documentation} \keyword{internal} R.cache-0.12.0/man/R.cache-package.Rd000077500000000000000000000062531262113323700167440ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % 999.package.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{R.cache-package} \alias{R.cache-package} \alias{R.cache} \docType{package} \title{Package R.cache} \description{ Memoization can be used to speed up repetitive and computational expensive function calls. The first time a function that implements memoization is called the results are stored in a cache memory. The next time the function is called with the same set of parameters, the results are momentarily retrieved from the cache avoiding repeating the calculations. With this package, any R object can be cached in a key-value storage where the key can be an arbitrary set of R objects. The cache memory is persistent (on the file system). } \section{Installation and updates}{ To install this package and all of its dependent packages, do: \code{install.packages("R.cache")} } \section{To get started}{ \itemize{ \item{\link{loadCache}, \link{saveCache}}{ Methods for loading and saving objects from and to the cache. } \item{\link{getCacheRootPath}, \link{setCacheRootPath}}{ Methods for getting and setting the directory where cache files are stored. } } } \section{How to cite this package}{ Whenever using this package, please cite [1] as \preformatted{ Bengtsson, H. The R.oo package - Object-Oriented Programming with References Using Standard R Code, Proceedings of the 3rd International Workshop on Distributed Statistical Computing (DSC 2003), ISSN 1609-395X, Hornik, K.; Leisch, F. & Zeileis, A. (ed.), 2003 } \emph{} } \section{Wishlist}{ Here is a list of features that would be useful, but which I have too little time to add myself. Contributions are appreciated. \itemize{ \item Add a functionality to identify cache files that are no longer of use. For now, there is an extra header field for arbitrary comments which can be used, but maybe more formal fields are useful, e.g. keywords, user, etc? } If you consider implement some of the above, make sure it is not already implemented by downloading the latest "devel" version! } \section{Related work}{ See also the \pkg{filehash} package, and the \code{cache()} function in the \pkg{Biobase} package of Bioconductor. } \author{Henrik Bengtsson} \section{License}{ The releases of this package is licensed under LGPL version 2.1 or newer. The development code of the packages is under a private licence (where applicable) and patches sent to the author fall under the latter license, but will be, if incorporated, released under the "release" license above. } \section{References}{ [1] H. Bengtsson, \emph{The R.oo package - Object-Oriented Programming with References Using Standard R Code}, In Kurt Hornik, Friedrich Leisch and Achim Zeileis, editors, Proceedings of the 3rd International Workshop on Distributed Statistical Computing (DSC 2003), March 20-22, Vienna, Austria. \url{http://www.ci.tuwien.ac.at/Conferences/DSC-2003/Proceedings/} \cr } \keyword{package} R.cache-0.12.0/man/addMemoization.Rd000066400000000000000000000027561262113323700170550ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % addMemoization.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{addMemoization} \alias{addMemoization.default} \alias{addMemoization} \title{Creates a copy of an existing function such that its results are memoized} \description{ Creates a copy of an existing function such that its results are memoized. } \usage{ \method{addMemoization}{default}(fcn, envir=parent.frame(), ...) } \arguments{ \item{fcn}{A \code{\link[base]{function}} (or the name of a function) that should be copied and have memoization added.} \item{envir}{The \code{\link[base]{environment}} from where to look for the function.} \item{...}{Additional arguments for controlling the memoization, i.e. all arguments of \code{\link{memoizedCall}}() that are not passed to \code{\link[base]{do.call}}().} } \value{ Returns a \code{\link[base]{function}}. } \details{ The new function is setup such that the the memoized call is done in the environment of the caller (the parent frame of the function). If the \code{\link[base]{function}} returns \code{\link[base]{NULL}}, that particular function call is \emph{not} memoized. } \author{Henrik Bengtsson} \seealso{ The returned function utilized \code{\link{memoizedCall}}() internally. } \keyword{programming} \keyword{IO} R.cache-0.12.0/man/clearCache.Rd000066400000000000000000000031121262113323700161060ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % clearCache.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{clearCache} \alias{clearCache.default} \alias{clearCache} \title{Removes all files in a cache file directory} \description{ Removes all files in a cache file directory. } \usage{ \method{clearCache}{default}(path=getCachePath(...), ..., recursive=FALSE, prompt=TRUE && interactive()) } \arguments{ \item{path}{A \code{\link[base]{character}} string specifying the directory to be cleared. By default, the path is what is returned by \code{\link{getCachePath}}() which arguments \code{...} are also passed.} \item{...}{Arguments passed to \code{\link{getCachePath}}(), especially argument \code{dirs} to specify subdirectories.} \item{recursive}{If \code{\link[base:logical]{TRUE}}, subdirectories are also removed, otherwise just the files in the specified directory.} \item{prompt}{If \code{\link[base:logical]{TRUE}}, the user will be prompted to confirm that the directory will cleared before files are removed.} } \value{ Returns (invisibly) a \code{\link[base]{character}} \code{\link[base]{vector}} of pathnames of the files removed. If no files were removed, \code{\link[base]{NULL}} is returned. } \author{Henrik Bengtsson} \details{ If the specified directory does not exists, an exception is thrown. } \keyword{programming} \keyword{IO} \keyword{internal} R.cache-0.12.0/man/evalWithMemoization.Rd000066400000000000000000000053141262113323700201010ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % evalWithMemoization.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{evalWithMemoization} \alias{evalWithMemoization} \title{Evaluates an R expression with memoization} \description{ Evaluates an R expression with memoization such that the same objects are assigned to the current environment and the same result is returned, if any. } \usage{ evalWithMemoization(expr, key=NULL, ..., envir=parent.frame(), force=FALSE) } \arguments{ \item{expr}{The \code{\link[base]{expression}} to be evaluated.} \item{key}{Additional objects to uniquely identify the evaluation.} \item{...}{Additional arguments passed to \code{\link{loadCache}}() and \code{\link{saveCache}}().} \item{envir}{The \code{\link[base]{environment}} in which the expression should be evaluated.} \item{force}{If \code{\link[base:logical]{TRUE}}, existing cached results are ignored.} } \value{ Returns the value of the evaluated \code{expr} \code{\link[base]{expression}}, if any. } \examples{ for (kk in 1:5) { cat(sprintf("Iteration #\%d:\n", kk)) res <- evalWithMemoization({ cat("Evaluating expression...") a <- 1 b <- 2 c <- 4 Sys.sleep(1) cat("done\n") b }) print(res) # Sanity checks stopifnot(a == 1 && b == 2 && c == 4) # Clean up rm(a, b, c) } # for (kk ...) ## OUTPUTS: ## Iteration #1: ## Evaluating expression...done ## [1] 2 ## Iteration #2: ## [1] 2 ## Iteration #3: ## [1] 2 ## Iteration #4: ## [1] 2 ## Iteration #5: ## [1] 2 ############################################################ # WARNING ############################################################ # If the expression being evaluated depends on # "input" objects, then these must be be specified # explicitly as "key" objects. for (ii in 1:2) { for (kk in 1:3) { cat(sprintf("Iteration #\%d:\n", kk)) res <- evalWithMemoization({ cat("Evaluating expression...") a <- kk Sys.sleep(1) cat("done\n") a }, key=list(kk=kk)) print(res) # Sanity checks stopifnot(a == kk) # Clean up rm(a) } # for (kk ...) } # for (ii ...) ## OUTPUTS: ## Iteration #1: ## Evaluating expression...done ## [1] 1 ## Iteration #2: ## Evaluating expression...done ## [1] 2 ## Iteration #3: ## Evaluating expression...done ## [1] 3 ## Iteration #1: ## [1] 1 ## Iteration #2: ## [1] 2 ## Iteration #3: ## [1] 3 } \author{Henrik Bengtsson} \seealso{ Internally, \code{\link[base]{eval}}() is used to evaluate the expression. } \keyword{programming} \keyword{IO} R.cache-0.12.0/man/findCache.Rd000066400000000000000000000017331262113323700157470ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % findCache.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{findCache} \alias{findCache.default} \alias{findCache} \title{Locates a cache file} \description{ Locates a cache file from a key object. } \usage{ \method{findCache}{default}(key=NULL, ...) } \arguments{ \item{key}{An optional object from which a hexadecimal hash code will be generated and appended to the filename.} \item{...}{Additional argument passed to \code{\link{generateCache}}.} } \value{ Returns the pathname as a \code{\link[base]{character}}, or \code{\link[base]{NULL}} if the no cached data exists. } \author{Henrik Bengtsson} \seealso{ \code{\link{generateCache}}. \code{\link{loadCache}}(). } \keyword{programming} \keyword{IO} \keyword{internal} R.cache-0.12.0/man/generateCache.Rd000066400000000000000000000023571262113323700166240ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % generateCache.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{generateCache} \alias{generateCache.default} \alias{generateCache} \title{Generates a cache pathname from a key object} \description{ Generates a cache pathname from a key object. } \usage{ \method{generateCache}{default}(key, suffix=".Rcache", ...) } \arguments{ \item{key}{A \code{\link[base]{list}} or an \code{\link[base]{environment}} from which a \code{\link[base]{character}} string checksum will be calculated and that will constitute the name part of the cache filename.} \item{suffix}{A \code{\link[base]{character}} string to be appended to the end of the filename.} \item{...}{Arguments passed to \code{\link{getCachePath}}().} } \value{ Returns the pathname as a \code{\link[base]{character}} string. } \author{Henrik Bengtsson} \seealso{ Internally, the generic function \code{\link{getChecksum}}() is used to calculate the checksum of argument \code{key}. } \keyword{programming} \keyword{IO} \keyword{internal} R.cache-0.12.0/man/getCachePath.Rd000066400000000000000000000024201262113323700164150ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % getCachePath.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{getCachePath} \alias{getCachePath.default} \alias{getCachePath} \title{Gets the path to the file cache directory} \description{ Gets the path to the file cache directory. If missing, the directory is created. } \usage{ \method{getCachePath}{default}(dirs=NULL, path=NULL, rootPath=getCacheRootPath(), ...) } \arguments{ \item{dirs}{A \code{\link[base]{character}} \code{\link[base]{vector}} constituting the path to the cache subdirectory (of the \emph{cache root directory} as returned by \code{\link{getCacheRootPath}}()) to be used. If \code{\link[base]{NULL}}, the path will be the cache root path.} \item{path, rootPath}{(Advanced) \code{\link[base]{character}} strings specifying the explicit/default cache path and root cache path.} \item{...}{Not used.} } \value{ Returns the path as a \code{\link[base]{character}} string. } \author{Henrik Bengtsson} \seealso{ \code{\link{setCachePath}}. } \keyword{programming} \keyword{IO} \keyword{internal} R.cache-0.12.0/man/getCacheRootPath.Rd000066400000000000000000000017401262113323700172650ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % getCacheRootPath.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{getCacheRootPath} \alias{getCacheRootPath.default} \alias{getCacheRootPath} \title{Gets the root path to the file cache directory} \description{ Gets the root path to the file cache directory. } \usage{ \method{getCacheRootPath}{default}(defaultPath="~/.Rcache", ...) } \arguments{ \item{defaultPath}{The default path, if no user-specified directory has been given.} \item{...}{Not used.} } \value{ Returns the path as a \code{\link[base]{character}} string. } \examples{ print(getCacheRootPath()) } \author{Henrik Bengtsson} \seealso{ Too set the directory where cache files are stored, see \code{\link{setCacheRootPath}}(). } \keyword{programming} \keyword{IO} R.cache-0.12.0/man/getChecksum.Rd000066400000000000000000000034451262113323700163470ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % getChecksum.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{getChecksum} \alias{getChecksum.default} \alias{getChecksum} \title{Generates a deterministic checksum for an R object} \description{ Generates a deterministic checksum for an R object such that (i) if the same object is used again, then the same checksum is obtained, and (ii) if another object is used, then a different checksum is obtained with extremely high probability. In other words, it is highly unlikely that two different objects have the same checksum. } \usage{ \method{getChecksum}{default}(object, ...) } \arguments{ \item{object}{The object for which a checksum should be calculated.} \item{...}{Additional arguments passed to \code{\link[digest]{digest}}.} } \value{ Returns checksum represented as a \code{\link[base]{character}} string. } \details{ Because \code{getChecksum()} is a generic function, it is possible to provide custom methods for specific classes of objects. This means that, if a certain class specifies fields that carry auxillary data, then these can be excluded from the checksum calculation. For instance, assume that all objects of class 'TimestampedObject' contain timestamps specifying when each object was created. Then a custom \code{getChecksum()} method for this class can first drop the timestamp and then call the default \code{getChecksum()} function. } \author{Henrik Bengtsson} \seealso{ Internally, the \code{\link[digest]{digest}} method is used to calculate the checksum. } \keyword{programming} \keyword{IO} \keyword{internal} R.cache-0.12.0/man/loadCache.Rd000077500000000000000000000056501262113323700157530ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % loadCache.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{loadCache} \alias{loadCache.default} \alias{loadCache} \title{Loads data from file cache} \description{ Loads data from file cache, which is unique for an optional key object. } \usage{ \method{loadCache}{default}(key=NULL, sources=NULL, suffix=".Rcache", removeOldCache=TRUE, pathname=NULL, dirs=NULL, ..., onError=c("warning", "print", "quiet", "error")) } \arguments{ \item{key}{An optional object from which a hexadecimal hash code will be generated and appended to the filename.} \item{sources}{Optional source objects. If the cache object has a timestamp older than one of the source objects, it will be ignored and removed.} \item{suffix}{A \code{\link[base]{character}} string to be appended to the end of the filename.} \item{removeOldCache}{If \code{\link[base:logical]{TRUE}} and the cache is older than the \code{sources}, the cache file is removed, otherwise not.} \item{pathname}{The pathname to the cache file. If specified, arguments \code{key} and \code{suffix} are ignored. Note that this is only needed in order to read a cache file for which the key is unknown, for instance, in order to investigate an unknown cache file.} \item{dirs}{A \code{\link[base]{character}} \code{\link[base]{vector}} constituting the path to the cache subdirectory (of the \emph{cache root directory} as returned by \code{\link{getCacheRootPath}}()) to be used. If \code{\link[base]{NULL}}, the path will be the cache root path.} \item{...}{Not used.} \item{onError}{A \code{\link[base]{character}} string specifying what the action is if an exception is thrown.} } \value{ Returns an \R object or \code{\link[base]{NULL}}, if cache does not exist. } \details{ The hash code calculated from the \code{key} object is a 32 characters long hexadecimal MD5 hash code. For more details, see \code{\link{getChecksum}}(). } \author{Henrik Bengtsson} \examples{ simulate <- function(mean, sd) { # 1. Try to load cached data, if already generated key <- list(mean, sd) data <- loadCache(key) if (!is.null(data)) { cat("Loaded cached data\n") return(data); } # 2. If not available, generate it. cat("Generating data from scratch...") data <- rnorm(1000, mean=mean, sd=sd) Sys.sleep(1) # Emulate slow algorithm cat("ok\n") saveCache(data, key=key, comment="simulate()") data; } data <- simulate(2.3, 3.0) data <- simulate(2.3, 3.5) data <- simulate(2.3, 3.0) # Will load cached data # Clean up file.remove(findCache(key=list(2.3,3.0))) file.remove(findCache(key=list(2.3,3.5))) } \seealso{ \code{\link{saveCache}}(). } \keyword{programming} \keyword{IO} R.cache-0.12.0/man/memoizedCall.Rd000066400000000000000000000033401262113323700165040ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % memoizedCall.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{memoizedCall} \alias{memoizedCall.default} \alias{memoizedCall} \title{Calls a function with memoization} \description{ Calls a function with memoization, that is, caches the results to be retrieved if the function is called again with the exact same arguments. } \usage{ \method{memoizedCall}{default}(what, ..., envir=parent.frame(), force=FALSE, sources=NULL, dirs=NULL) } \arguments{ \item{what}{The \code{\link[base]{function}} to be called, or a \code{\link[base]{character}} string specifying the name of the function to be called, cf. \code{\link[base]{do.call}}().} \item{...}{Arguments passed to the function.} \item{envir}{The \code{\link[base]{environment}} in which the function is evaluated.} \item{force}{If \code{\link[base:logical]{TRUE}}, any cached results are ignored, otherwise not.} \item{sources, dirs}{Optional arguments passed to \code{\link{loadCache}}() and \code{\link{saveCache}}().} } \value{ Returns the result of the function call. } \details{ If the \code{\link[base]{function}} returns \code{\link[base]{NULL}}, that particular function call is \emph{not} memoized. } \author{Henrik Bengtsson} \seealso{ Internally, \code{\link{loadCache}}() is used to load memoized results, if available. If not available, then \code{\link{do.call}}() is used to evaluate the function call, and \code{\link{saveCache}}() is used to save the results to cache. } \keyword{programming} \keyword{IO} R.cache-0.12.0/man/readCacheHeader.Rd000077500000000000000000000024121262113323700170510ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % readCacheHeader.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{readCacheHeader} \alias{readCacheHeader.default} \alias{readCacheHeader} \title{Loads data from file cache} \description{ Loads data from file cache, which is unique for an optional key object. } \usage{ \method{readCacheHeader}{default}(file, ...) } \arguments{ \item{file}{A filename or a \code{\link[base:connections]{connection}}.} \item{...}{Not used.} } \value{ Returns a named \code{\link[base]{list}} structure with element \code{identifier}, \code{version}, \code{comment} (optional), \code{sources} (optional), and \code{timestamp}. } \author{Henrik Bengtsson} \examples{ data <- 1:120 key <- list(some=1, vari=2, ables=3) saveCache(key=key, data, comment="A simple example of a cached object.") header <- readCacheHeader(findCache(key=key)) print(header) # Clean up file.remove(findCache(key=key)) } \seealso{ \code{\link{findCache}}(). \code{\link{loadCache}}(). \code{\link{saveCache}}(). } \keyword{programming} \keyword{IO} \keyword{internal} R.cache-0.12.0/man/saveCache.Rd000077500000000000000000000047151262113323700157730ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % saveCache.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{saveCache} \alias{saveCache.default} \alias{saveCache} \title{Saves data to file cache} \description{ Saves data to file cache, which is unique for an optional key object. } \usage{ \method{saveCache}{default}(object, key=NULL, sources=NULL, suffix=".Rcache", comment=NULL, pathname=NULL, dirs=NULL, compress=getOption("R.cache::compress", FALSE), ...) } \arguments{ \item{object}{The object to be saved to file.} \item{key}{An optional object from which a hexadecimal hash code will be generated and appended to the filename.} \item{sources}{Source objects used for comparison of timestamps when cache is loaded later.} \item{suffix}{A \code{\link[base]{character}} string to be appended to the end of the filename.} \item{comment}{An optional \code{\link[base]{character}} string written in ASCII at the beginning of the file.} \item{pathname}{(Advanced) An optional \code{\link[base]{character}} string specifying the pathname to the cache file. If not specified (default), a unique one is automatically generated from arguments \code{key} and \code{suffix} among other things.} \item{dirs}{A \code{\link[base]{character}} \code{\link[base]{vector}} constituting the path to the cache subdirectory (of the \emph{cache root directory} as returned by \code{\link{getCacheRootPath}}()) to be used. If \code{\link[base]{NULL}}, the path will be the cache root path.} \item{compress}{If \code{\link[base:logical]{TRUE}}, the cache file will be saved using gzip compression, otherwise not.} \item{...}{Additional argument passed to \code{\link[base]{save}}().} } \value{ Returns (invisible) the pathname of the cache file. } \section{Compression}{ The \code{saveCache()} method saves a compressed cache file (with filename extension *.gz) if argument \code{compress} is \code{\link[base:logical]{TRUE}}. The \code{\link{loadCache}}() method locates (via \code{\link{findCache}}()) and loads such cache files as well. } \author{Henrik Bengtsson} \examples{\dontrun{For an example, see ?loadCache}} \seealso{ For more details on how the hash code is generated etc, \code{\link{loadCache}}(). } \keyword{programming} \keyword{IO} R.cache-0.12.0/man/setCachePath.Rd000066400000000000000000000017141262113323700164360ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % setCachePath.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{setCachePath} \alias{setCachePath.default} \alias{setCachePath} \title{Sets the path to the file cache directory} \description{ Sets the path to the file cache directory. } \usage{ \method{setCachePath}{default}(dirs=NULL, path=NULL, ...) } \arguments{ \item{dirs}{A \code{\link[base]{character}} \code{\link[base]{vector}} constituting the path to the cache subdirectory of interest.} \item{path}{The path to override the path according to the \code{dirs} argument.} \item{...}{Not used.} } \value{ Returns nothing. } \author{Henrik Bengtsson} \seealso{ \code{\link{getCachePath}}(). } \keyword{programming} \keyword{IO} \keyword{internal} R.cache-0.12.0/man/setCacheRootPath.Rd000066400000000000000000000015341262113323700173020ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % setCacheRootPath.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{setCacheRootPath} \alias{setCacheRootPath.default} \alias{setCacheRootPath} \title{Sets the root path to the file cache directory} \description{ Sets the root path to the file cache directory. By default, this function will set it to \code{~/.Rcache/}. } \usage{ \method{setCacheRootPath}{default}(path="~/.Rcache", ...) } \arguments{ \item{path}{The path.} \item{...}{Not used.} } \value{ Returns (invisibly) the old root path. } \author{Henrik Bengtsson} \seealso{ \code{\link{getCacheRootPath}}(). } \keyword{programming} \keyword{IO} R.cache-0.12.0/man/setupCacheRootPath.Rd000066400000000000000000000027111262113323700176450ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Do not modify this file since it was automatically generated from: % % setupCacheRootPath.R % % by the Rdoc compiler part of the R.oo package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \name{setupCacheRootPath} \alias{setupCacheRootPath.default} \alias{setupCacheRootPath} \title{Interactively offers the user to set up the default root path} \description{ Interactively offers the user to set up the default root path. } \usage{ \method{setupCacheRootPath}{default}(defaultPath="~/.Rcache/", ...) } \arguments{ \item{defaultPath}{Default root path to set.} \item{...}{Not used.} } \value{ Returns (invisibly) the root path, or \code{\link[base]{NULL}} if running a non-interactive session. } \details{ If the cache root path is already set, it is used and nothing is done. If the "default" root path (\code{defaultPath}) exists, it is used, otherwise, if running interactively, the user is asked to approve the usage (and creation) of the default root path. In all other cases, the cache root path is set to a session-specific temporary directory. } \author{Henrik Bengtsson} \seealso{ Internally, \code{\link{setCacheRootPath}}() is used to set the cache root path. The \code{\link[base]{interactive}}() function is used to test whether \R is running interactively or not. } \keyword{programming} \keyword{IO} \keyword{internal} R.cache-0.12.0/tests/000077500000000000000000000000001262113323700141775ustar00rootroot00000000000000R.cache-0.12.0/tests/Object.getChecksum.R000066400000000000000000000001231262113323700177650ustar00rootroot00000000000000library("R.cache") obj <- R.oo::Object() obj$value <- 42L print(getChecksum(obj)) R.cache-0.12.0/tests/StaticMethodsAndNamespaces.R000066400000000000000000000000501262113323700215130ustar00rootroot00000000000000R.cache::clearCache(dirs=sample(1:10)) R.cache-0.12.0/tests/addMemoization.R000066400000000000000000000030161262113323700172660ustar00rootroot00000000000000library("R.cache") # Use an empty temporary file cache setCacheRootPath(path=file.path(tempdir())) clearCache(recursive=TRUE, prompt=FALSE) dirs <- c("tests", "addMemoization") # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Define function to be memoized # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - sleep <- function(time) { cat(sprintf("Sleeping for %g seconds...\n", time)) Sys.sleep(time) cat(sprintf("Sleeping for %g seconds...done\n", time)) time } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Test memoization # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - sleep <- addMemoization(sleep) # There will be no cache hit for the first call t0 <- system.time({ res0 <- sleep(1.5) })[3] print(t0) # The second will have a cache hit and therefore # return the memoized results momentarily. t1 <- system.time({ res1 <- sleep(1.5) })[3] print(t1) print(t1/t0) # Sanity check stopifnot(identical(res1, res0)) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Don't memoize already memoized functions # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - sleep2 <- addMemoization(sleep) stopifnot(identical(sleep2, sleep)) sleep3 <- addMemoization("sleep") stopifnot(identical(sleep3, sleep)) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Exception handling # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - res <- try(addMemoization("non-existing-function"), silent=TRUE) stopifnot(inherits(res, "try-error")) R.cache-0.12.0/tests/assertDigest.R000066400000000000000000000001141262113323700167570ustar00rootroot00000000000000R.cache:::.assertDigest() library("R.cache") R.cache:::.assertDigest() R.cache-0.12.0/tests/clearCache.R000066400000000000000000000007011262113323700163320ustar00rootroot00000000000000library("R.cache") ## Use an empty temporary file cache setCacheRootPath(path=file.path(tempdir())) ## Try to clear it clearCache(recursive=TRUE, prompt=FALSE) clearCache(recursive=TRUE, prompt=TRUE) dirs <- c("tests", "clearCache") saveCache(1, key=list("clearCache"), dirs=dirs) clearCache(recursive=FALSE, prompt=TRUE) clearCache(recursive=TRUE, prompt=TRUE) clearCache(recursive=FALSE, prompt=FALSE) clearCache(recursive=TRUE, prompt=FALSE) R.cache-0.12.0/tests/evalWithMemoization.R000066400000000000000000000016631262113323700203270ustar00rootroot00000000000000library("R.cache") for (kk in 1:5) { cat(sprintf("Iteration #%d:\n", kk)) res <- evalWithMemoization({ cat("Evaluating expression...") a <- 1 b <- 2 c <- 4 cat("done\n") b }) print(res) # Sanity checks stopifnot(a == 1 && b == 2 && c == 4) # Clean up rm(list=c("a", "b", "c")) } # for (kk ...) ############################################################ # WARNING ############################################################ # If the expression being evaluated depends on # "input" objects, then these must be be specified # explicitly as "key" objects. for (ii in 1:2) { for (kk in 1:3) { cat(sprintf("Iteration #%d:\n", kk)) res <- evalWithMemoization({ cat("Evaluating expression...") a <- kk cat("done\n") a }, key=list(kk=kk)) print(res) # Sanity checks stopifnot(a == kk) # Clean up rm(list=c("a")) } # for (kk ...) } # for (ii ...) R.cache-0.12.0/tests/getCachePath.R000066400000000000000000000002721262113323700166430ustar00rootroot00000000000000library("R.cache") root <- getCacheRootPath() print(root) path <- getCachePath(dirs=c("abc", "def")) print(path) path <- getCachePath(dirs=c("abc", "def"), path="subdir") print(path) R.cache-0.12.0/tests/getCacheRootPath.R000066400000000000000000000015121262113323700175050ustar00rootroot00000000000000library("R.cache") setupCacheRootPath <- R.cache:::setupCacheRootPath oopts <- options() tmpdir <- tempdir() setCacheRootPath(path=tmpdir) print(getCacheRootPath()) setupCacheRootPath(defaultPath=tmpdir) path <- getCacheRootPath(NULL) print(path) stopifnot(identical(path, tmpdir)) options("R.cache::rootPath"=NULL) print(getCacheRootPath()) options("R.cache.path"="foo") print(getCacheRootPath()) options("R.cache.path"=NULL) print(getCacheRootPath()) oenv <- Sys.getenv("R_CACHE_PATH") Sys.setenv("R_CACHE_PATH"="") print(getCacheRootPath()) path <- getCacheRootPath(NULL) print(path) stopifnot(is.null(path)) setupCacheRootPath(defaultPath=tmpdir) path <- getCacheRootPath(NULL) print(path) stopifnot(identical(path, tmpdir)) ## Cleanup options(oopts) args <- list(oenv) names(args) <- "R_CACHE_PATH" do.call(Sys.setenv, args) R.cache-0.12.0/tests/loadCache.R000066400000000000000000000015031262113323700161640ustar00rootroot00000000000000library("R.cache") oopts <- options("R.cache::compress") simulate <- function(mean, sd) { # 1. Try to load cached data, if already generated key <- list(mean, sd) data <- loadCache(key) if (!is.null(data)) { cat("Loaded cached data\n") return(data) } # 2. If not available, generate it. cat("Generating data from scratch...") data <- rnorm(1000, mean=mean, sd=sd) Sys.sleep(1) # Emulate slow algorithm cat("ok\n") saveCache(data, key=key, comment="simulate()") data } for (compress in c(FALSE, TRUE)) { options("R.cache::compress"=compress) data <- simulate(2.3, 3.0) data <- simulate(2.3, 3.5) data <- simulate(2.3, 3.0) # Will load cached data # Clean up file.remove(findCache(key=list(2.3,3.0))) file.remove(findCache(key=list(2.3,3.5))) } ## Cleanup options(oopts) R.cache-0.12.0/tests/memoizedCall.R000066400000000000000000000021741262113323700167330ustar00rootroot00000000000000library("R.cache") # Use an empty temporary file cache setCacheRootPath(path=file.path(tempdir())) clearCache(recursive=TRUE, prompt=FALSE) dirs <- c("tests", "memoizedCall") # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Define function to be memoized # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - sleep <- function(time) { cat(sprintf("Sleeping for %g seconds...\n", time)) Sys.sleep(time) cat(sprintf("Sleeping for %g seconds...done\n", time)) time } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Test memoization # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # There will be no cache hit for the first call t0 <- system.time({ res0 <- memoizedCall(sleep, time=1.5, dirs=dirs) })[3] print(t0) # The second will have a cache hit and therefore # return the memoized results momentarily. t1 <- system.time({ res1 <- memoizedCall(sleep, time=1.5, dirs=dirs) })[3] print(t1) if (t1 >= t0) { warning("Second call to memoizedCall() took longer than the first: ", t1, " >= ", t0) } # Sanity check stopifnot(identical(res1, res0)) clearCache(recursive=TRUE) R.cache-0.12.0/tests/readCacheHeader.R000066400000000000000000000010511262113323700172670ustar00rootroot00000000000000library("R.cache") ## Use an empty temporary file cache setCacheRootPath(path=file.path(tempdir())) dirs <- c("tests", "readCacheHeader") for (compress in c(FALSE, TRUE)) { pathname <- saveCache(1, key=list("readCacheHeader"), dirs=dirs, compress=compress) for (byName in c(FALSE, TRUE)) { if (byName) { hdr <- readCacheHeader(pathname) } else { con <- gzfile(pathname, open="rb") hdr <- readCacheHeader(con) close(con) } str(list(pathname=pathname, hdr=hdr)) } } ## Cleanup clearCache(recursive=TRUE) R.cache-0.12.0/tests/setCachePath.R000066400000000000000000000004051262113323700166550ustar00rootroot00000000000000library("R.cache") setCachePath <- R.cache:::setCachePath ## Use an empty temporary file cache tmpdir <- tempdir() setCacheRootPath(path=tmpdir) dirs <- c("tests", "readCacheHeader") setCachePath(dirs=dirs, path=tmpdir) ## Cleanup clearCache(recursive=TRUE) R.cache-0.12.0/tests/setCacheRootPath.R000066400000000000000000000002761262113323700175270ustar00rootroot00000000000000library("R.cache") tmpdir <- tempdir() setCacheRootPath(path=tmpdir) setCacheRootPath(path=file.path(tmpdir, "subdir")) setCacheRootPath(path=tmpdir) ## Cleanup clearCache(recursive=TRUE) R.cache-0.12.0/tests/textPrompt.R000066400000000000000000000005601262113323700165110ustar00rootroot00000000000000textPrompt <- R.cache:::.textPrompt ans <- textPrompt("Do you have a minute?") print(ans) ans <- textPrompt("Do you have a minute?", options=c("yes", "no")) print(ans) ## Output to standard error ans <- textPrompt("Do you have a minute?", type="message") print(ans) ## Output to standard output ans <- textPrompt("Do you have a minute?", type="output") print(ans)