diff --git a/DESCRIPTION b/DESCRIPTION index 5acb496..311c66d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: marshal -Version: 0.0.1-9004 +Version: 0.0.1-9005 Title: Framework to Marshal Objects to be Used in Another R Process Depends: R (>= 3.2.0) @@ -7,6 +7,7 @@ Suggests: knitr, DT, jsonlite, + bigmemory, bundle, caret, data.table, diff --git a/NAMESPACE b/NAMESPACE index 29bdc80..58ac05e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -14,6 +14,7 @@ S3method(marshal,SOCKnode) S3method(marshal,SpatVector) S3method(marshal,XMLAbstractDocument) S3method(marshal,XMLAbstractNode) +S3method(marshal,big.matrix) S3method(marshal,connection) S3method(marshal,data.table) S3method(marshal,default) @@ -46,6 +47,7 @@ S3method(marshallable,SOCKnode) S3method(marshallable,SpatVector) S3method(marshallable,XMLAbstractDocument) S3method(marshallable,XMLAbstractNode) +S3method(marshallable,big.memory) S3method(marshallable,connection) S3method(marshallable,data.table) S3method(marshallable,default) diff --git a/R/marshal.bigmemory.R b/R/marshal.bigmemory.R new file mode 100644 index 0000000..97d6da4 --- /dev/null +++ b/R/marshal.bigmemory.R @@ -0,0 +1,70 @@ +#' Marshalling of 'bigmemory' objects +#' +#' @param x A [bigmemory::big.matrix] object. +#' +#' @param \dots Not used. +#' +#' @return +#' A `marshalled` object as described in [marshal()]. +#' +#' @details +#' [bigmemory::write.big.matrix()] is used to produce a marshalled version +#' of the original object. +#' [bigmemory::read.big.matrix()] is used to reconstruct a version of the +#' original object from the marshalled object. +#' +#' @example incl/marshal.bigmemory.R +#' +#' @rdname marshal.bigmemory +#' @aliases marshal.bigmemory +#' @export +marshal.big.matrix <- function(x, ...) { + marshal_bigmemory(x, ...) +} + +marshal_bigmemory <- function(x, ...) { + tf <- tempfile(fileext = ".bigmemory") + on.exit(if (!is.null(tf)) file.remove(tf)) + bigmemory::write.big.matrix(x, filename = tf) + raw <- readBin(tf, what = "raw", n = file.size(tf)) + file.remove(tf) + tf <- NULL + + res <- list( + marshalled = list( + typeof = bigmemory::typeof(x), + raw = raw + ) + ) + class(res) <- marshal_class(x) + rm(list = "raw") + + res[["unmarshal"]] <- unmarshal_bigmemory + + assert_no_references(res) + res +} + +unmarshal_bigmemory <- function(x, ...) { + object <- x[["marshalled"]] + raw <- object[["raw"]] + typeof <- object[["typeof"]] + + tf <- tempfile(fileext = ".bigmemory") + on.exit(if (!is.null(tf)) file.remove(tf)) + writeBin(raw, con = tf) + + res <- bigmemory::read.big.matrix(tf, type = typeof) + file.remove(tf) + tf <- NULL + + res +} + + +#' @rdname marshal.bigmemory +#' @aliases marshallable.big.memory +#' @export +marshallable.big.memory <- function(...) { + TRUE +} diff --git a/incl/marshal.bigmemory.R b/incl/marshal.bigmemory.R new file mode 100644 index 0000000..8313939 --- /dev/null +++ b/incl/marshal.bigmemory.R @@ -0,0 +1,15 @@ +if (requireNamespace("bigmemory", quietly = TRUE)) { + library(bigmemory) + + x <- big.matrix(nrow = 3, ncol = 2, type = "double") + x[] <- seq_along(x) + + ## Marshal + x_ <- marshal(x) + + ## Unmarshal + x2 <- unmarshal(x_) + + stopifnot(identical(x2[], x[])) +} + diff --git a/inst/known_cases.json b/inst/known_cases.json index 25cf49b..3b928d9 100644 --- a/inst/known_cases.json +++ b/inst/known_cases.json @@ -27,6 +27,13 @@ "can_be_marshalled": true, "must_be_marshalled": true }, + { + "package": "bigmemory", + "type": "big.matrix", + "if_not_marshalled": "segmentation fault", + "can_be_marshalled": true, + "must_be_marshalled": true + }, { "package": "caret", "type": "train", diff --git a/man/marshal.bigmemory.Rd b/man/marshal.bigmemory.Rd new file mode 100644 index 0000000..76b29f1 --- /dev/null +++ b/man/marshal.bigmemory.Rd @@ -0,0 +1,46 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/marshal.bigmemory.R +\name{marshal.big.matrix} +\alias{marshal.big.matrix} +\alias{marshal.bigmemory} +\alias{marshallable.big.memory} +\title{Marshalling of 'bigmemory' objects} +\usage{ +\method{marshal}{big.matrix}(x, ...) + +\method{marshallable}{big.memory}(...) +} +\arguments{ +\item{x}{A \link[bigmemory:big.matrix]{bigmemory::big.matrix} object.} + +\item{\dots}{Not used.} +} +\value{ +A \code{marshalled} object as described in \code{\link[=marshal]{marshal()}}. +} +\description{ +Marshalling of 'bigmemory' objects +} +\details{ +\code{\link[bigmemory:write.big.matrix]{bigmemory::write.big.matrix()}} is used to produce a marshalled version +of the original object. +\code{\link[bigmemory:write.big.matrix]{bigmemory::read.big.matrix()}} is used to reconstruct a version of the +original object from the marshalled object. +} +\examples{ +if (requireNamespace("bigmemory", quietly = TRUE)) { + library(bigmemory) + + x <- big.matrix(nrow = 3, ncol = 2, type = "double") + x[] <- seq_along(x) + + ## Marshal + x_ <- marshal(x) + + ## Unmarshal + x2 <- unmarshal(x_) + + stopifnot(identical(x2[], x[])) +} + +} diff --git a/tests/marshal.bigmemory.R b/tests/marshal.bigmemory.R new file mode 100644 index 0000000..490a647 --- /dev/null +++ b/tests/marshal.bigmemory.R @@ -0,0 +1,16 @@ +library(marshal) + +if (requireNamespace("bigmemory", quietly = TRUE)) { + library(bigmemory) + + x <- big.matrix(nrow = 3, ncol = 2, type = "double") + x[] <- seq_along(x) + + ## Marshal + x_ <- marshal(x) + + ## Unmarshal + x2 <- unmarshal(x_) + + stopifnot(identical(x2[], x[])) +}