% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/AllGenerics.R, R/storeDelayedObject.R
\name{storeDelayedObject}
\alias{storeDelayedObject}
\alias{storeDelayedObject,ConstantArraySeed-method}
\alias{storeDelayedObject,DelayedAbind-method}
\alias{storeDelayedObject,ANY-method}
\alias{storeDelayedObject,DelayedAperm-method}
\alias{storeDelayedObject,DelayedNaryIsoOp-method}
\alias{storeDelayedObject,DelayedSetDimnames-method}
\alias{storeDelayedObject,DelayedSubassign-method}
\alias{storeDelayedObject,DelayedSubset-method}
\alias{storeDelayedObject,DelayedUnaryIsoOpStack-method}
\alias{storeDelayedObject,DelayedUnaryIsoOpWithArgs-method}
\alias{storeDelayedObject,SVT_SparseMatrix-method}
\alias{storeDelayedObject,array-method}
\alias{storeDelayedObject,denseMatrix-method}
\alias{storeDelayedObject,sparseMatrix-method}
\alias{reloadDelayedObject}
\alias{reloadDelayedObjectFunctionRegistry}
\alias{registerReloadDelayedObjectFunction}
\alias{altStoreDelayedObjectFunction}
\alias{altStoreDelayedObject}
\alias{altReloadDelayedObjectFunction}
\alias{altReloadDelayedObject}
\alias{createExternalSeedDedupSession}
\title{Store/reload a DelayedArray}
\usage{
storeDelayedObject(x, handle, name, ...)

reloadDelayedObject(handle, name, version = package_version("1.1"), ...)

reloadDelayedObjectFunctionRegistry(type = c("operation", "array"))

registerReloadDelayedObjectFunction(
  type = c("operation", "array"),
  subtype,
  fun,
  existing = c("old", "new", "error")
)

\S4method{storeDelayedObject}{array}(
  x,
  handle,
  name,
  version = package_version("1.1"),
  save.external.array = FALSE,
  ...
)

\S4method{storeDelayedObject}{ANY}(
  x,
  handle,
  name,
  version = package_version("1.1"),
  external.save.args = list(),
  external.dedup.session = NULL,
  external.dedup.action = c("link", "copy", "symlink", "relsymlink"),
  ...
)

altStoreDelayedObjectFunction(store)

altStoreDelayedObject(...)

altReloadDelayedObjectFunction(reload)

altReloadDelayedObject(...)

createExternalSeedDedupSession()
}
\arguments{
\item{x}{Any of the delayed operation/array classes from \pkg{DelayedArray}.}

\item{handle}{An \pkg{rhdf5} handle of a HDF5 file to save into (for \code{storeDelayedObject}) or load from (for \code{reloadDelayedObject}).}

\item{name}{String containing the name of the group in \code{file} to save into (for \code{storeDelayedObject}) or load from (for \code{reloadDelayedObject}).}

\item{...}{For \code{storeDelayedObject} and \code{reloadDelayedObject}, additional arguments to be passed to specific methods.

For \code{altStoreDelayedObject} and \code{altReloadDelayedObject}, arguments to be passed to the alternative functions.}

\item{version}{Package version of the \pkg{chihaya} format to use when storing or reloading delayed objects.
When reloading, the version should be retrieved from the attributes of the outermost group, typically by \code{readDelayedArray}.}

\item{type}{String specifying the type of delayed object, i.e., operation or array.
This corresponds to \code{delayed_type} type in the \pkg{chihaya} attributes.}

\item{subtype}{String specifying the subtype of the delayed object, 
This corresponds to \code{delayed_array} or \code{delayed_operation} type (depending on \code{type}) in the \pkg{chihaya} attributes.}

\item{fun}{Function to reload a delayed object.
This should accept the same arguments as \code{reloadDelayedObject} and should return a delayed array (if \code{type="array"}) or operation (otherwise).
It may also be \code{NULL} to delete an existing entry in the registry.}

\item{existing}{Logical scalar indicating the action to take if a function has already been registered for \code{type} and \code{subtype} -
keep the old or new function, or throw an error.}

\item{save.external.array}{Logical scalar indicating whether to save an array-like seed as an external seed,
even if a dedicated \code{storeDelayedObject} method is available.}

\item{external.save.args}{Named list of further arguments to pass to \code{\link{altSaveObject}} when saving an external seed.}

\item{external.dedup.session}{Session object created by \code{createExternalSeedDedupSession}.}

\item{external.dedup.action}{String specifying the deduplication method to use.}

\item{store}{Function (typically a generic) to store delayed objects to file.
This should accept the same arguments as \code{storeDelayedObject}.}

\item{reload}{Function to reload delayed objects from file.
This should accept the same arguments as \code{reloadDelayedObject}.}
}
\value{
For \code{storeDelayedObject} and \code{altStoreDelayedObject}, the contents of \code{x} are saved to \code{file}, and \code{NULL} is invisibly returned.

For \code{reloadDelayedObject} and \code{altReloadDelayedObject}, a delayed operation or \linkS4class{DelayedArray} is returned.

For \code{altStoreDelayedObjectFunction}, the current store function is returned if \code{store} is missing.
Otherwise, \code{store} is set as the current store function and the previous store function is returned.

For \code{altReloadDelayedObjectFunction}, the current reload function is returned if \code{reload} is missing.
Otherwise, \code{reload} is set as the current reload function and the previous reload function is returned.
}
\description{
Store or reload the delayed operations or array-like seeds of a \linkS4class{DelayedArray} in an existing HDF5 file.
}
\section{Customization}{

Developers can easily extend \pkg{alabaster.matrix} to new delayed objects by writing new methods for \code{storeDelayedObject}.
Methods should save the contents of the delayed object to the HDF5 file in the \pkg{chihaya} format.
Each new store method typically requires a corresponding reloading function to be registered via \code{registerReloadDelayedObjectFunction},
so that \code{reloadDelayedObject} knows how to reconstitute the object from file.

Application developers can customize the process of storing/reloading delayed objects by specifying alternative functions in \code{altReloadDelayedObjectFunction} and \code{altStoreDelayedObjectFunction}.
For example, if we want to preserve all delayed objects except for \linkS4class{DelayedSubset},
we could replace \code{storeDelayedObject} with an \code{altStoreDelayedObject} that realizes any DelayedSubset instance into an ordinary matrix.
This is analogous to the overrides for \code{\link{altReadObject}} and \code{\link{altSaveObject}}.

Extension developers (i.e., those who write new methods for \code{storeDelayedObject} or new functions for \code{reloadDelayedObject})
should generally use \code{altStoreDelayedObject} and \code{altReloadDelayedObject} in their method/funcion bodies.
This ensures that any custom overrides specified by application developers are still respected in the extensions to \pkg{alabaster.matrix}.
}

\section{External seeds}{

Whenever \code{storeDelayedObject} encounters a delayed operation or array-like seed for which it has no methods,
the ANY method will save the delayed object as an \dQuote{external seed}.
The array is saved via \code{\link{altSaveObject}} into a \code{seeds} directory next to the file associated with \code{handle}.
A reference to this external location is then stored in the \code{name} group inside \code{handle}.

Users can force this behavior for all array-like seeds by passing \code{save.external.array=TRUE} in the \code{...} arguments of \code{storeDelayedObject}.
This instructs \code{storeDelayedObject} to save everything as external seeds, including those arrays for which it has methods.
Doing so can be beneficial to enable deduplication, e.g., when two delayed arrays perform different operations on the same underlying seed.
By saving the seeds externally, file management systems can identify the redundancy to save storage space.

Advanced users can explicitly deduplicate external seeds by setting \code{save.external.array=TRUE} and passing \code{external.dedup.session=} to \code{storeDelayedObject}.
The \code{external.dedup.session} object is filled up with unique seeds as \code{storeDelayedObject} is called on various DelayedArrays.
Whenever a duplicate seed is encountered, it is not saved again, but is instead linked or copied from the file path associated with the identical external seed.
For example, a new session can be created when saving a SummarizedExperiment to deduplicate seeds across its assays.

The exact deduplication action can be specified by specifying the \code{external.dedup.action=} parameter.
By default, \code{storeDelayedObject} attempts to create hard links, falling back to copies when a link cannot be created.
Users can instead create copies, symbolic links to absolute paths, or even symbolic links to relative paths
(e.g., to link to a \dQuote{neighboring} assay of the same SummarizedExperiment).

When external seeds are encountered by \code{reloadDelayedObject}, they are loaded as \linkS4class{ReloadedArray}s (or some variant thereof) by \code{\link{altReadObject}}.
Users can forcibly realize the reloaded seed into memory by passing \code{custom.takane.reload=TRUE} in \code{...} for the \code{reloadDelayedObject} call.
This is occasionally helpful for providing a more faithful roundtrip from file back into memory.
}

\examples{
library(DelayedArray)
X <- DelayedArray(matrix(runif(100), ncol=20))
Y <- cbind(X, DelayedArray::ConstantArray(value=50, c(5, 10)))

library(rhdf5)
temp <- tempfile()
dir.create(temp)

fpath <- file.path(temp, "foo.h5")
fhandle <- H5Fcreate(fpath)
storeDelayedObject(Y@seed, fhandle, "YAY")
rhdf5::h5ls(fhandle)
H5Fclose(fhandle)

fhandle <- H5Fopen(fpath, "H5F_ACC_RDONLY")
reloadDelayedObject(fhandle, "YAY")
H5Fclose(fhandle)

}
\seealso{
\code{\link{saveObject,DelayedArray-method}} and \code{\link{readDelayedArray}}, where these methods are used.

\url{https://artifactdb.github.io/chihaya/}, for the file format specification of delayed objects.
}
\author{
Aaron Lun
}
