The R Project SVN R

Rev

Rev 80066 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
60153 ripley 1
#  File src/library/base/makebasedb.R
68953 ripley 2
#  Part of the R package, https://www.R-project.org
60153 ripley 3
#
4
#  Copyright (C) 1995-2012 The R Core Team
5
#
6
#  This program is free software; you can redistribute it and/or modify
7
#  it under the terms of the GNU General Public License as published by
8
#  the Free Software Foundation; either version 2 of the License, or
9
#  (at your option) any later version.
10
#
11
#  This program is distributed in the hope that it will be useful,
12
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
#  GNU General Public License for more details.
15
#
16
#  A copy of the GNU General Public License is available at
68953 ripley 17
#  https://www.R-project.org/Licenses/
60153 ripley 18
 
30349 ripley 19
local({
20
    makeLazyLoadDB <- function(from, filebase, compress = TRUE, ascii = FALSE,
21
                               variables) {
22
 
60407 ripley 23
        envlist <- function(e)
80066 hornik 24
            .Internal(getVarsFromFrame(ls(e, all.names = TRUE), e, FALSE))
30349 ripley 25
 
26
        envtable <- function() {
27
            idx <- 0
28
            envs <- NULL
29
            enames <- character(0)
48780 ripley 30
            find <- function(v, keys, vals) {
47570 hornik 31
                for (i in seq_along(keys))
30349 ripley 32
                    if (identical(v, keys[[i]]))
33
                        return(vals[i])
48780 ripley 34
		NULL
35
	    }
30349 ripley 36
            getname <- function(e) find(e, envs, enames)
37
            insert <- function(e) {
38
                idx <<- idx + 1
39
                name <- paste("env", idx, sep="::")
40
                envs <<- c(e, envs)
41
                enames <<- c(name, enames)
42
                name
43
            }
81284 luke 44
            list(insert = insert, getname = getname)
30349 ripley 45
        }
46
 
47
        lazyLoadDBinsertValue <- function(value, file, ascii, compress, hook)
60407 ripley 48
            .Internal(lazyLoadDBinsertValue(value, file, ascii, compress, hook))
30349 ripley 49
 
50
        lazyLoadDBinsertListElement <- function(x, i, file, ascii, compress, hook)
60407 ripley 51
            .Internal(lazyLoadDBinsertValue(x[[i]], file, ascii, compress, hook))
30349 ripley 52
 
53
        lazyLoadDBinsertVariable <- function(n, e, file, ascii, compress, hook) {
60407 ripley 54
            x <- .Internal(getVarsFromFrame(n, e, FALSE))
55
            .Internal(lazyLoadDBinsertValue(x[[1L]], file, ascii, compress, hook))
30349 ripley 56
        }
57
 
58
        mapfile <- paste(filebase, "rdx", sep = ".")
59
        datafile <- paste(filebase, "rdb", sep = ".")
60
        close(file(datafile, "w")) # truncate to zero
61
        table <- envtable()
62
        varenv <- new.env(hash = TRUE)
63
        envenv <- new.env(hash = TRUE)
64
 
65
        envhook <- function(e) {
66
            if (is.environment(e)) {
67
                name <- table$getname(e)
68
                if (is.null(name)) {
69
                    name <- table$insert(e)
70
                    data <- list(bindings = envlist(e),
71
                                 enclos = parent.env(e))
72
                    key <- lazyLoadDBinsertValue(data, datafile, ascii,
73
                                                 compress, envhook)
41600 ripley 74
                    assign(name, key, envir = envenv)
30349 ripley 75
                }
76
                name
77
            }
78
        }
79
 
36174 murdoch 80
        if (is.environment(from)) {
30349 ripley 81
            if (! missing(variables))
82
                vars <- variables
80066 hornik 83
            else vars <- ls(from, all.names = TRUE)
30349 ripley 84
        }
85
        else if (is.list(from)) {
86
            vars <- names(from)
87
            if (length(vars) != length(from) || any(nchar(vars) == 0))
88
                stop("source list must have names for all elements")
89
        }
90
        else stop("source must be an environment or a list");
91
 
47570 hornik 92
        for (i in seq_along(vars)) {
36174 murdoch 93
            if (is.environment(from))
30349 ripley 94
                key <- lazyLoadDBinsertVariable(vars[i], from, datafile,
95
                                                ascii, compress,  envhook)
96
            else key <- lazyLoadDBinsertListElement(from, i, datafile, ascii,
97
                                                    compress, envhook)
41600 ripley 98
            assign(vars[i], key, envir = varenv)
30349 ripley 99
        }
100
 
41600 ripley 101
        vals <- lapply(vars, get, envir = varenv, inherits = FALSE)
30349 ripley 102
        names(vals) <- vars
103
 
80066 hornik 104
        rvars <- ls(envenv, all.names = TRUE)
41600 ripley 105
        rvals <- lapply(rvars, get, envir = envenv, inherits = FALSE)
30349 ripley 106
        names(rvals) <- rvars
107
 
108
        val <- list(variables = vals, references = rvals,
109
                    compressed = compress)
54021 ripley 110
       saveRDS(val, mapfile)
30349 ripley 111
    }
112
 
41531 ripley 113
    omit <- c(".Last.value", ".AutoloadEnv", ".BaseNamespaceEnv",
114
              ".Device", ".Devices", ".Machine", ".Options", ".Platform")
30349 ripley 115
 
116
    if (length(search()[search()!="Autoloads"]) != 2)
117
        stop("start R with NO packages loaded to create the data base")
118
 
30994 ripley 119
    baseFileBase <- file.path(.Library,"base","R","base")
30983 ripley 120
 
30349 ripley 121
    if (file.info(baseFileBase)["size"] < 20000) # crude heuristic
122
        stop("may already be using lazy loading on base");
123
 
41593 ripley 124
    basevars <- ls(baseenv(), all.names=TRUE)
41531 ripley 125
    prims <- basevars[sapply(basevars, function(n) is.primitive(get(n, baseenv())))]
126
    basevars <- basevars[! basevars %in% c(omit, prims)]
30349 ripley 127
 
35450 murdoch 128
    makeLazyLoadDB(baseenv(), baseFileBase, variables = basevars)
30349 ripley 129
})