Skip to content

Commit 31d19c3

Browse files
author
luke
committed
Add resizable vector interface to experimental API.
git-svn-id: https://svn.r-project.org/R/trunk@89077 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent 8e31e44 commit 31d19c3

File tree

2 files changed

+84
-12
lines changed

2 files changed

+84
-12
lines changed

doc/manual/R-exts.texi

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12721,15 +12721,6 @@ Other useful allocation functions are @code{Rf_alloc3DArray},
1272112721
@apifun Rf_allocArray
1272212722
@apifun Rf_allocMatrix
1272312723

12724-
At times it can be useful to allocate a larger initial result vector and
12725-
resize it to a shorter length if that is sufficient. The functions
12726-
@code{Rf_lengthgets} and @code{Rf_xlengthgets} accomplish this; they are
12727-
analogous to using @code{length(x) <- n} in @R{}. Typically these
12728-
functions return a freshly allocated object, but in some cases they may
12729-
re-use the supplied object.
12730-
@apifun Rf_lengthgets
12731-
@apifun Rf_xlengthgets
12732-
1273312724
When creating new result objects it can be useful to fill them in with
1273412725
values from an existing object. The functions @code{Rf_copyVector} and
1273512726
@code{Rf_copyMatrix} can be used for this. @code{Rf_copyMostAttributes} can
@@ -13653,6 +13644,82 @@ support future changes, package code should use @code{NO_REFERENCES},
1365313644
@apifun MAYBE_SHARED
1365413645
@apifun MARK_NOT_MUTABLE
1365513646

13647+
@node Resizing vectors
13648+
@subsection Resizing vectors
13649+
@cindex Resizing vectors
13650+
13651+
The functions @code{Rf_lengthgets} and @code{Rf_xlengthgets} are
13652+
analogous to using @code{length(x) <- n} in @R{}. These functions
13653+
typically allocate a fresh object. Elements from the original vector are
13654+
copied into the result up to the specified new length.
13655+
@apifun Rf_lengthgets
13656+
@apifun Rf_xlengthgets
13657+
13658+
On rare occasions it may be useful to allocate a longer vector and
13659+
destructively set its length to a shorter value. This is possible if a
13660+
vector has been marked as resizable at allocation. An experimental
13661+
framework to support this has been added in @R 4.6.0.
13662+
13663+
Resizable vectors can be created by an initial allocation or as a copy
13664+
of an existing vector:
13665+
13666+
@example
13667+
SEXP R_allocResizableVector(SEXPTYPE type, R_xlen_t maxlen);
13668+
SEXP R_duplicateAsResizable(SEXP x);
13669+
@end example
13670+
@eapifun R_allocResizableVector
13671+
@eapifun R_duplicateAsResizable
13672+
13673+
A resizable vector can then be resized with
13674+
@example
13675+
void R_resizeVector(SEXP x, R_xlen_t newlen);
13676+
@end example
13677+
@eapifun R_resizeVector
13678+
13679+
It is an error to attempt to resize a vector that is not resizable, or
13680+
to request a size greater than the initial allocated size. Resizing a
13681+
vector will drop @code{dim}, @code{dimnames}, and @code{names}
13682+
attributes; other attributes are retained.
13683+
13684+
Whether a vector is resizable and the maximal available size of a
13685+
resizable vector can be determined using
13686+
13687+
@example
13688+
bool R_isResizable(SEXP x);
13689+
R_xlen_t R_maxLength(SEXP x);
13690+
@end example
13691+
@eapifun R_isResizable
13692+
@eapifun R_maxLength
13693+
13694+
Some considerations for using resizable vectors:
13695+
13696+
@itemize
13697+
13698+
@item Resizing a vector is a destructive modification. Like any destructive
13699+
modification at the @code{C} level it has to be done with care to avoid
13700+
violating the pass-by-value semantics of the @code{R}
13701+
language. Ordinarily only objects with no references are safe to modify;
13702+
if an object has references from other @R{} objects then these must be
13703+
thoroughly understood before considering a destructive modification.
13704+
13705+
@item If enabling package code to resize vectors that have references causes
13706+
too many issues, then @code{R_resizeVector} may be modified to disallow
13707+
this.
13708+
13709+
@item Serializing and unserializing a resizable vector does not preserve the
13710+
resizable property. The result is an ordinary non-resizable vector.
13711+
13712+
@item The memory betweeen a shorter length and the initially allocated
13713+
maximal length of a resizable vector is not accessible and cannot be
13714+
reclaimed until the shorter vector is reclaimed by the garbage
13715+
collector.
13716+
13717+
@end itemize
13718+
13719+
In most cases using @code{Rf_lengthgets} or @code{Rf_xlengthgets} is a
13720+
better, safer, and more memory-efficient choice than using resizable
13721+
vectors.
13722+
1365613723

1365713724
@node Interface functions .Call and .External
1365813725
@section Interface functions @code{.Call} and @code{.External}
@@ -17536,6 +17603,8 @@ functions that should be used instead:
1753617603
@item R_GetCurrentEnv
1753717604
Use @code{environment()} at the @R{} level and pass the result as
1753817605
an argument to your C function.
17606+
@item SETLENGTH
17607+
See @ref{Resizing vectors}.
1753917608
@end table
1754017609

1754117610
For recently added entry points packages that need to be compiled
@@ -17744,6 +17813,9 @@ void CLEAR_ATTRIB(SEXP x)
1774417813

1774517814
#if R_VERSION < R_Version(4, 6, 0)
1774617815
# define DATAPTR_RW(x) DATAPTR(x)
17816+
# define R_allocResizableVector(type, maxlen) Rf_allocVector(type, naxlen)
17817+
# define R_duplicateAsResizable(x) duplicate(x)
17818+
# define R_resizeVector(x, newlen) SETLENGTH(x, n)
1774717819
#endif
1774817820
@end example
1774917821

src/library/tools/R/sotools.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -715,9 +715,9 @@ nonAPI <- c("chol_", "chol2inv_", "cg_", "ch_", "rg_",
715715
"Rf_isFrame",
716716
"BODY", "FORMALS", "CLOENV", "ENCLOS",
717717
"IS_ASCII", "IS_UTF8",
718-
## experimental resizable vector entry points -- not yet in the API
719-
"R_isResizable", "R_maxLength", "R_resizeVector",
720-
"R_allocResizableVector", "R_duplicateAsResizable",
718+
## experimental resizable vector entry points -- now in the experimental API
719+
## "R_isResizable", "R_maxLength", "R_resizeVector",
720+
## "R_allocResizableVector", "R_duplicateAsResizable",
721721
## experimental hashtable support -- not yet in the API
722722
"R_asHashtable", "R_HashtabSEXP", "R_isHashtable", "R_mkhashtab",
723723
"R_gethash", "R_sethash", "R_remhash", "R_numhash", "R_typhash",

0 commit comments

Comments
 (0)