From 5e24debbd956c353aaa6f9675af76a72bb41c1d6 Mon Sep 17 00:00:00 2001 From: Joshua Ulrich Date: Mon, 6 Mar 2023 18:25:15 -0600 Subject: [PATCH] Add support for long vectors (> 2^32-1) R added support for long vectors in version 3.0.0. The xts C code had not been updated to take advantage of this feature. That meant xts objects were limited to matrices with less than 2^32-1 elements. Most of the changes are fall into these categories: 1. Change index counters from 'int' to 'R_xlen_t' 2. Use xlength() instead of LENGTH() or length() to get length 3. Use xlengthgets() instead of lengthgets() to set length There are a few non-functional changes to move type declaration closer to where the variable is used. See #239. --- inst/include/xts.h | 2 +- src/any.c | 4 ++-- src/binsearch.c | 24 ++++++++++++------------ src/coredata.c | 16 ++++++++-------- src/diff.c | 10 +++++----- src/endpoints.c | 5 +++-- src/extract_col.c | 22 +++++++++++----------- src/isOrdered.c | 4 ++-- src/merge.c | 31 ++++++++++++++++--------------- src/na.c | 18 +++++++++--------- src/period_apply.c | 4 ++-- src/period_arithmetic.c | 12 ++++++------ src/period_quantile.c | 8 ++++---- src/rbind.c | 20 ++++++++++---------- src/rollfun.c | 30 +++++++++++++++++------------- src/runSum.c | 8 ++++---- src/subset.c | 19 ++++++++++--------- src/subset.old.c | 22 +++++++++++----------- src/unique.time.c | 10 +++++----- 19 files changed, 138 insertions(+), 131 deletions(-) diff --git a/inst/include/xts.h b/inst/include/xts.h index 25dcf5f0..408c274b 100644 --- a/inst/include/xts.h +++ b/inst/include/xts.h @@ -111,7 +111,7 @@ void copy_xtsAttributes(SEXP x, SEXP y); // internal only void copy_xtsCoreAttributes(SEXP x, SEXP y);// internal only SEXP isXts(SEXP x); // is.xts analogue -int firstNonNA(SEXP x); +R_xlen_t firstNonNA(SEXP x); SEXP extract_col (SEXP x, SEXP j, SEXP drop, SEXP first_, SEXP last_); SEXP do_startofyear(SEXP from, SEXP to, SEXP origin); int xts_ncols(SEXP x); diff --git a/src/any.c b/src/any.c index 4f089186..0f01fe35 100644 --- a/src/any.c +++ b/src/any.c @@ -25,8 +25,8 @@ SEXP any_negative (SEXP i_) { - int i; - int len = length(i_); + R_xlen_t i; + R_xlen_t len = xlength(i_); int *int_i=NULL; double *real_i=NULL; diff --git a/src/binsearch.c b/src/binsearch.c index 0880584a..9f59cd48 100644 --- a/src/binsearch.c +++ b/src/binsearch.c @@ -76,7 +76,7 @@ SEXP binsearch(SEXP key, SEXP vec, SEXP start) error("start must be specified as true or false"); } - if (length(vec) < 1 || length(key) < 1) { + if (xlength(vec) < 1 || length(key) < 1) { return ScalarInteger(NA_INTEGER); } @@ -105,9 +105,9 @@ SEXP binsearch(SEXP key, SEXP vec, SEXP start) error("unsupported type"); } - int mid; - int lo = 0; - int hi = length(vec) - 1; + R_xlen_t mid; + R_xlen_t lo = 0; + R_xlen_t hi = xlength(vec) - 1; while (lo < hi) { mid = lo + (hi - lo) / 2; @@ -126,7 +126,7 @@ SEXP binsearch(SEXP key, SEXP vec, SEXP start) /* cmp_func() := vector[index] >= key when start == true, and we need * to return the smallest index subject to vector[index] >= key. */ - if (!cmp_func(data, length(vec)-1)) { + if (!cmp_func(data, xlength(vec)-1)) { /* entire vector < key */ return ScalarInteger(NA_INTEGER); } @@ -158,19 +158,19 @@ SEXP fill_window_dups_rev(SEXP _x, SEXP _index) * upper bound of the location of the user index in the xts index. * This is necessary to handle duplicate dates in the xts index. */ - int n_x = length(_x); + R_xlen_t n_x = xlength(_x); int *x = INTEGER(_x); - if (length(_index) < 1) { + if (xlength(_index) < 1) { return allocVector(INTSXP, 0); } PROTECT_INDEX px; SEXP _out; - PROTECT_WITH_INDEX(_out = allocVector(INTSXP, length(_index)), &px); + PROTECT_WITH_INDEX(_out = allocVector(INTSXP, xlength(_index)), &px); int *out = INTEGER(_out); - int i, xi, j, k = 0, n_out = length(_out); + R_xlen_t i, xi, j, k = 0, n_out = xlength(_out); switch (TYPEOF(_index)) { case REALSXP: { @@ -184,7 +184,7 @@ SEXP fill_window_dups_rev(SEXP _x, SEXP _index) if (k == n_out) { REPROTECT(_out = xlengthgets(_out, k+2*(i+1)), px); out = INTEGER(_out); - n_out = length(_out); + n_out = xlength(_out); } out[k++] = j--; } while (j > 0 && index[xi-1] == index[j-1]); @@ -203,7 +203,7 @@ SEXP fill_window_dups_rev(SEXP _x, SEXP _index) if (k == n_out) { REPROTECT(_out = xlengthgets(_out, k+2*(i+1)), px); out = INTEGER(_out); - n_out = length(_out); + n_out = xlength(_out); } out[k++] = j--; } while (j > 0 && index[xi-1] == index[j-1]); @@ -214,7 +214,7 @@ SEXP fill_window_dups_rev(SEXP _x, SEXP _index) error("unsupported index type"); } - /* truncate so length(_out) = k + /* truncate so xlength(_out) = k * NB: output is in reverse order! */ REPROTECT(_out = xlengthgets(_out, k), px); diff --git a/src/coredata.c b/src/coredata.c index 26ad6dac..af1a7178 100644 --- a/src/coredata.c +++ b/src/coredata.c @@ -33,21 +33,21 @@ SEXP coredata (SEXP x, SEXP copyAttr) removing */ SEXP result; - int i, j, ncs, nrs; - int P=0; - PROTECT(result = allocVector(TYPEOF(x), length(x))); P++; + R_xlen_t i, j, ncs, nrs; + int P = 0; + PROTECT(result = allocVector(TYPEOF(x), xlength(x))); P++; switch( TYPEOF(x)) { case REALSXP: - memcpy(REAL(result), REAL(x), length(result) * sizeof(double)); + memcpy(REAL(result), REAL(x), xlength(result) * sizeof(double)); break; case INTSXP: - memcpy(INTEGER(result), INTEGER(x), length(result) * sizeof(int)); + memcpy(INTEGER(result), INTEGER(x), xlength(result) * sizeof(int)); break; case LGLSXP: - memcpy(LOGICAL(result), LOGICAL(x), length(result) * sizeof(int)); + memcpy(LOGICAL(result), LOGICAL(x), xlength(result) * sizeof(int)); break; case CPLXSXP: - memcpy(COMPLEX(result), COMPLEX(x), length(result) * sizeof(Rcomplex)); + memcpy(COMPLEX(result), COMPLEX(x), xlength(result) * sizeof(Rcomplex)); break; case STRSXP: ncs = ncols(x); nrs = nrows(x); @@ -56,7 +56,7 @@ SEXP coredata (SEXP x, SEXP copyAttr) SET_STRING_ELT(result, i+j*nrs, STRING_ELT(x, i+j*nrs)); break; case RAWSXP: - memcpy(RAW(result), RAW(x), length(result) * sizeof(unsigned char)); + memcpy(RAW(result), RAW(x), xlength(result) * sizeof(unsigned char)); break; default: error("currently unsupported data type"); diff --git a/src/diff.c b/src/diff.c index a108a22b..0fe9c858 100644 --- a/src/diff.c +++ b/src/diff.c @@ -34,9 +34,9 @@ SEXP diffXts(SEXP x, SEXP lag, SEXP diff, SEXP arith, SEXP nap, SEXP dots) SEXP lagXts(SEXP x, SEXP k, SEXP pad) { SEXP result; - int nrs, ncs; - int i, j, ij, iijj, K, NApad; - int mode; + R_xlen_t nrs, ncs; + R_xlen_t i, j, ij, iijj, K; + int mode, NApad; int P=0; /*PROTECT counter*/ int *int_result=NULL, *int_x=NULL; int *lgl_result=NULL, *lgl_x=NULL; @@ -169,8 +169,8 @@ SEXP lagXts(SEXP x, SEXP k, SEXP pad) setAttrib(result, R_ClassSymbol, getAttrib(x, R_ClassSymbol)); if(!NApad) { /* No NA padding */ SEXP oindex, nindex, dims; - int nRows = (K > 0) ? nrs-K : nrs+K; - int incr = (K > 0) ? K : 0; + R_xlen_t nRows = (K > 0) ? nrs-K : nrs+K; + R_xlen_t incr = (K > 0) ? K : 0; PROTECT(oindex = getAttrib(x, xts_IndexSymbol)); PROTECT(nindex = allocVector(TYPEOF(oindex), nRows)); switch(TYPEOF(oindex)) { diff --git a/src/endpoints.c b/src/endpoints.c index 02e45401..b687f1c8 100644 --- a/src/endpoints.c +++ b/src/endpoints.c @@ -32,9 +32,10 @@ SEXP endpoints (SEXP _x, SEXP _on, SEXP _k, SEXP _addlast /* TRUE */) c(0,which(diff(_x%/%on%/%k+1) != 0),NROW(_x)) */ + int P = 0; int *int_index = NULL; double *real_index = NULL; - int i=1,j=1, nr, P=0; + R_xlen_t i = 1, j = 1, nr; int int_tmp[2]; int64_t int64_tmp[2]; @@ -134,7 +135,7 @@ SEXP endpoints (SEXP _x, SEXP _on, SEXP _k, SEXP _addlast /* TRUE */) ep[j] = nr; j++; } - PROTECT(_ep = lengthgets(_ep, j)); P++; + PROTECT(_ep = xlengthgets(_ep, j)); P++; UNPROTECT(P); return(_ep); } diff --git a/src/extract_col.c b/src/extract_col.c index ce622cc6..d4a02f28 100644 --- a/src/extract_col.c +++ b/src/extract_col.c @@ -39,7 +39,7 @@ SEXP extract_col (SEXP x, SEXP j, SEXP drop, SEXP first_, SEXP last_) { SEXP result, index, new_index; - int nrs, nrsx, i, ii, jj, first, last; + R_xlen_t nrs, nrsx, i, ii, jj, first, last; nrsx = nrows(x); @@ -50,11 +50,11 @@ SEXP extract_col (SEXP x, SEXP j, SEXP drop, SEXP first_, SEXP last_) { nrs = last - first + 1; - PROTECT(result = allocVector(TYPEOF(x), nrs * length(j))); + PROTECT(result = allocVector(TYPEOF(x), nrs * xlength(j))); switch(TYPEOF(x)) { case REALSXP: - for(i=0; i